summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2010-05-27 17:20:18 +0000
committerManolo Gouy <Manolo>2010-05-27 17:20:18 +0000
commit26049351e09d75bdf8b35273a76cf65202583fa7 (patch)
tree010685555b9f83d071a14262e8ce346c7388f254
parent0a280ce591046f6834f1233087a72fa6bdd97bad (diff)
Better device hierarchy with surfaces and graphics drivers.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7617 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--FL/Fl_Bitmap.H7
-rw-r--r--FL/Fl_Device.H205
-rw-r--r--FL/Fl_Image.H7
-rw-r--r--FL/Fl_Paged_Device.H92
-rw-r--r--FL/Fl_Pixmap.H5
-rw-r--r--FL/Fl_PostScript.H293
-rw-r--r--FL/Fl_Printer.H215
-rw-r--r--src/Fl_Bitmap.cxx109
-rw-r--r--src/Fl_Device.cxx59
-rw-r--r--src/Fl_Double_Window.cxx13
-rw-r--r--src/Fl_GDI_Printer.cxx9
-rw-r--r--src/Fl_Image.cxx140
-rw-r--r--src/Fl_Paged_Device.cxx291
-rw-r--r--src/Fl_Pixmap.cxx167
-rw-r--r--src/Fl_PostScript.cxx1393
-rw-r--r--src/Fl_Printer.cxx34
-rw-r--r--src/Fl_Quartz_Printer.mm9
-rw-r--r--src/Fl_cocoa.mm12
-rw-r--r--src/Fl_win32.cxx10
-rw-r--r--src/Fl_x.cxx19
-rw-r--r--src/fl_arc.cxx2
-rw-r--r--src/fl_arci.cxx4
-rw-r--r--src/fl_color.cxx4
-rw-r--r--src/fl_color_mac.cxx4
-rw-r--r--src/fl_color_win32.cxx4
-rw-r--r--src/fl_curve.cxx2
-rw-r--r--src/fl_draw_image.cxx8
-rw-r--r--src/fl_draw_image_mac.cxx8
-rw-r--r--src/fl_draw_image_win32.cxx11
-rw-r--r--src/fl_draw_pixmap.cxx84
-rw-r--r--src/fl_font_mac.cxx6
-rw-r--r--src/fl_font_win32.cxx11
-rw-r--r--src/fl_font_x.cxx6
-rw-r--r--src/fl_font_xft.cxx6
-rw-r--r--src/fl_line_style.cxx6
-rw-r--r--src/fl_rect.cxx47
-rw-r--r--src/fl_vertex.cxx28
-rw-r--r--src/ps_image.cxx43
38 files changed, 2898 insertions, 475 deletions
diff --git a/FL/Fl_Bitmap.H b/FL/Fl_Bitmap.H
index d47a82acf..33f1914a6 100644
--- a/FL/Fl_Bitmap.H
+++ b/FL/Fl_Bitmap.H
@@ -40,8 +40,10 @@ struct Fl_Menu_Item;
(bitmap) images. Images are drawn using the current color.
*/
class FL_EXPORT Fl_Bitmap : public Fl_Image {
- friend class Fl_Device;
- public:
+ friend class Fl_Quartz_Graphics_Driver;
+ friend class Fl_GDI_Graphics_Driver;
+ friend class Fl_Xlib_Graphics_Driver;
+public:
/** pointer to raw bitmap data */
const uchar *array;
@@ -58,7 +60,6 @@ class FL_EXPORT Fl_Bitmap : public Fl_Image {
unsigned id_;
#endif // __APPLE__ || WIN32
- void generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy);
public:
/** The constructors create a new bitmap from the specified bitmap data */
diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H
index 8eaaa0c87..21251f6c6 100644
--- a/FL/Fl_Device.H
+++ b/FL/Fl_Device.H
@@ -1,8 +1,8 @@
//
// "$Id$"
//
-// Definition of classes Fl_Device, Fl_Display, Fl_Quartz_Display, Fl_GDI_Display,
-// and Fl_Xlib_Display for the Fast Light Tool Kit (FLTK).
+// Definition of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device
+// for the Fast Light Tool Kit (FLTK).
//
// Copyright 2010 by Bill Spitzak and others.
//
@@ -26,7 +26,7 @@
// http://www.fltk.org/str.php
//
/** \file Fl_Device.H
- \brief declaration of classes Fl_Device, Fl_Display.
+ \brief declaration of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device.
*/
#ifndef Fl_Device_H
@@ -45,14 +45,15 @@
#include <stdio.h>
#endif
-class Fl_Widget;
-class Fl_Device;
-class Fl_Display;
-class Fl_Abstract_Printer;
-/** \brief Points to the device that currently receives all graphics requests */
-FL_EXPORT extern Fl_Device *fl_device;
-/** \brief Points to the platform's display device */
-FL_EXPORT extern Fl_Display *fl_display_device;
+class Fl_Graphics_Driver;
+class Fl_Display_Device;
+class Fl_Surface_Device;
+/** \brief Points to the driver that currently receives all graphics requests */
+extern Fl_Graphics_Driver *fl_device;
+/** \brief Points to the surface that currently receives all graphics requests */
+extern Fl_Surface_Device *fl_surface;
+/** \brief Points to the platform's display */
+extern Fl_Display_Device *fl_display_device;
/**
signature of image generation callback function.
@@ -65,33 +66,56 @@ FL_EXPORT extern Fl_Display *fl_display_device;
typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf);
/**
- \brief A pure virtual class subclassed to send the output of drawing functions to display, printers, or local files.
+ \brief All graphical output devices and all graphics systems.
+ */
+class Fl_Device {
+protected:
+ /** \brief The device type */
+ const char *type_;
+ /** \brief A string that identifies each subclass of Fl_Device.
+ *
+ Function type() applied to a device of this class returns this string.
+ */
+ static const char *device_type;
+public:
+ /**
+ @brief An RTTI emulation of device classes.
+ *
+ The type of an instance of an Fl_Device subclass can be checked with code such as:
+ \code
+ if ( instance->type() == Fl_Printer::device_type ) { ... }
+ \endcode
+ */
+ inline const char *type() {return type_;};
+};
+
+/**
+ \brief A virtual class subclassed for each graphics driver FLTK uses.
*
- The protected virtual methods of this class are those that a device should implement to
+ The protected virtual methods of this class are those that a graphics driver should implement to
support all of FLTK drawing functions.
<br> The preferred FLTK API for drawing operations is the function collection of the
\ref fl_drawings and \ref fl_attributes modules.
- <br> Alternatively, member functions of the Fl_Device class can be called
- using the global variable Fl_Device * \ref fl_device that points at all time to the single device
- (an instance of an Fl_Device subclass) that's currently receiving graphics requests:
+ <br> Alternatively, methods of the Fl_Graphics_Driver class can be called
+ using the global variable Fl_Graphics_Driver * \ref fl_device that points at all time to the single driver
+ (an instance of an Fl_Graphics_Driver subclass) that's currently receiving graphics requests:
\code fl_device->rect(x, y, w, h); \endcode
- <br>Each member function of the Fl_Device class has the same effect and parameter list as the
+ <br>Each protected method of the Fl_Graphics_Driver class has the same effect as the
function of the \ref fl_drawings and \ref fl_attributes modules which bears the same name
- prefixed with fl_ .
+ prefixed with fl_ and has the same parameter list.
*/
-class Fl_Device {
+class Fl_Graphics_Driver : public Fl_Device {
protected:
- /** \brief The device type */
- int type_;
- /** \brief red color for background and/or mixing if device does not support masking or alpha */
+/* ** \brief red color for background and/or mixing if device does not support masking or alpha *
uchar bg_r_;
- /** \brief green color for background and/or mixing if device does not support masking or alpha */
+ ** \brief green color for background and/or mixing if device does not support masking or alpha *
uchar bg_g_;
- /** \brief blue color for background and/or mixing if device does not support masking or alpha */
- uchar bg_b_;
+ ** \brief blue color for background and/or mixing if device does not support masking or alpha *
+ uchar bg_b_; */
friend class Fl_Pixmap;
friend class Fl_Bitmap;
friend class Fl_RGB_Image;
+ friend class Fl_PostScript_Graphics_Driver;
friend void fl_rect(int x, int y, int w, int h);
friend void fl_rectf(int x, int y, int w, int h);
friend void fl_line_style(int style, int width, char* dashes);
@@ -141,6 +165,8 @@ protected:
friend void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D);
friend FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D);
+ /** \brief The constructor. */
+ Fl_Graphics_Driver() {};
/** \brief see fl_rect(int x, int y, int w, int h). */
virtual void rect(int x, int y, int w, int h);
/** \brief see fl_rectf(int x, int y, int w, int h). */
@@ -239,74 +265,113 @@ protected:
/** \brief see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D). */
virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1);
// Image classes
- virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
- virtual void draw(Fl_Bitmap * bmp,int XP, int YP, int WP, int HP, int cx, int cy);
- virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
-
-public:
- /**
- @brief All implemented graphics output devices.
+ /** \brief Draws an Fl_RGB_Image object to the device.
+ *
+ Specifies a bounding box for the image, with the origin (upper left-hand corner) of
+ the image offset by the cx and cy arguments.
*/
- enum device_types {
- xlib_display = 0, /**< The X11 display. */
- quartz_display, /**< The Mac OS X display. */
- gdi_display, /**< The MSWindows display. */
- gdi_printer = 256, /**< The MSWindows printer. */
- quartz_printer, /**< The Mac OS X printer. */
- postscript_device /**< The PostScript device. */
- };
- /**
- @brief An RTTI emulation of device classes. It returns values < 256 if it is a display device
+ virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) {};
+ /** \brief Draws an Fl_Pixmap object to the device.
+ *
+ Specifies a bounding box for the image, with the origin (upper left-hand corner) of
+ the image offset by the cx and cy arguments.
*/
- inline int type() {return type_;};
- virtual Fl_Device *set_current(void);
-
- virtual ~Fl_Device() {};
- static Fl_Device *current();
-
- /**
- @brief Returns the platform's display device.
+ virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) {};
+ /** \brief Draws an Fl_Bitmap object to the device.
+ *
+ Specifies a bounding box for the image, with the origin (upper left-hand corner) of
+ the image offset by the cx and cy arguments.
*/
- static Fl_Display *display_device() { return fl_display_device; };
-
-};
-extern FL_EXPORT Fl_Device *fl_device;
-
-/**
- @brief A virtual class subclassed for OS-specific display graphics.
- */
-class Fl_Display : public Fl_Device {
- friend class Fl_PSfile_Device;
+ virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {};
+
+public:
+ static const char *device_type;
+ /** \brief The destructor */
+ virtual ~Fl_Graphics_Driver() {};
};
#if defined(__APPLE__) || defined(FL_DOXYGEN)
/**
- @brief The Mac OS X-specific display graphics class.
+ \brief The Mac OS X-specific graphics class.
+ *
+ This class is implemented only on the Mac OS X platform.
*/
-class Fl_Quartz_Display : public Fl_Display {
+class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver {
public:
- Fl_Quartz_Display() { type_ = quartz_display; };
+ Fl_Quartz_Graphics_Driver() { type_ = device_type; };
+ static const char *device_type;
+ void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
};
#endif
#if defined(WIN32) || defined(FL_DOXYGEN)
/**
- @brief The MSWindows-specific display graphics class.
+ \brief The MSWindows-specific graphics class.
+ *
+ This class is implemented only on the MSWindows platform.
*/
-class Fl_GDI_Display : public Fl_Display {
+class Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver {
public:
- Fl_GDI_Display() { type_ = gdi_display; };
+ Fl_GDI_Graphics_Driver() { type_ = device_type; };
+ static const char *device_type;
+ void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
};
#endif
-#if !( defined(__APPLE__) || defined(WIN32)) || defined(FL_DOXYGEN)
+#if !(defined(__APPLE__) || defined(WIN32))
/**
- @brief The X11-specific display graphics class.
+ \brief The Xlib-specific graphics class.
+ *
+ This class is implemented only on the Xlib platform.
*/
-class Fl_Xlib_Display : public Fl_Display {
+class Fl_Xlib_Graphics_Driver : public Fl_Graphics_Driver {
public:
- Fl_Xlib_Display() { type_ = xlib_display; };
+ Fl_Xlib_Graphics_Driver() { type_ = device_type; };
+ static const char *device_type;
+ void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
};
#endif
+/**
+ \brief A surface that's susceptible to receive graphical output.
+ */
+class Fl_Surface_Device : public Fl_Device {
+ /** \brief The graphics driver in use by this surface. */
+ Fl_Graphics_Driver *_driver;
+protected:
+ /** \brief Constructor that sets the graphics driver to use for the created surface. */
+ Fl_Surface_Device(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver; };
+public:
+ static const char *device_type;
+ virtual void set_current(void);
+ /** \brief Sets the graphics driver of this drawing surface. */
+ inline void driver(Fl_Graphics_Driver *graphics_driver) {_driver = graphics_driver;};
+ /** \brief Returns the graphics driver of this drawing surface. */
+ inline Fl_Graphics_Driver *driver() {return _driver; };
+ /** \brief the surface that currently receives graphics output */
+ static Fl_Surface_Device *surface() {return fl_surface; };
+ /** \brief The destructor. */
+ virtual ~Fl_Surface_Device() {}
+};
+
+/**
+ \brief A display to which the computer can draw.
+ */
+class Fl_Display_Device : public Fl_Surface_Device {
+public:
+ static const char *device_type;
+ /** \brief A constructor that sets the graphics driver used by the display */
+ Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device( graphics_driver) { type_ = device_type; };
+ /**
+ @brief Returns the platform's display device.
+ */
+ static Fl_Display_Device *display_device() { return fl_display_device; };
+};
+
#endif // Fl_Device_H
//
diff --git a/FL/Fl_Image.H b/FL/Fl_Image.H
index ff10b1ef6..329f3fa44 100644
--- a/FL/Fl_Image.H
+++ b/FL/Fl_Image.H
@@ -188,9 +188,10 @@ class FL_EXPORT Fl_Image {
&lt;FL/Fl_RGB_Image.H&gt; should be included.
*/
class FL_EXPORT Fl_RGB_Image : public Fl_Image {
- friend class Fl_Device;
- void generic_device_draw(int X, int Y, int W, int H, int cx=0, int cy=0);
- public:
+ friend class Fl_Quartz_Graphics_Driver;
+ friend class Fl_GDI_Graphics_Driver;
+ friend class Fl_Xlib_Graphics_Driver;
+public:
const uchar *array;
int alloc_array; // Non-zero if array was allocated
diff --git a/FL/Fl_Paged_Device.H b/FL/Fl_Paged_Device.H
new file mode 100644
index 000000000..41d1a5f00
--- /dev/null
+++ b/FL/Fl_Paged_Device.H
@@ -0,0 +1,92 @@
+//
+// "$Id: Fl_Paged_Device.H 7556 2010-04-27 21:33:44Z manolo $"
+//
+// Printing support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/** \file Fl_Paged_Device.H
+ \brief declaration of class Fl_Paged_Device.
+ */
+
+#ifndef Fl_Paged_Device_H
+#define Fl_Paged_Device_H
+
+#include <FL/Fl_Device.H>
+
+/**
+ \brief Represents page-structured drawing surfaces.
+ *
+ This class has no public constructor: don't instantiate it; use Fl_Printer
+ or Fl_PostScript_File_Device instead.
+ */
+class Fl_Paged_Device : public Fl_Surface_Device {
+private:
+#ifdef __APPLE__
+ struct chain_elt {
+ Fl_Image *image;
+ const uchar *data;
+ struct chain_elt *next;
+ };
+ void add_image(Fl_Image *image, const uchar *data); // adds an image to the page image list
+#endif
+ void traverse(Fl_Widget *widget); // finds subwindows of widget and prints them
+protected:
+ /** \brief horizontal offset to the origin of graphics coordinates */
+ int x_offset;
+ /** \brief vertical offset to the origin of graphics coordinates */
+ int y_offset;
+ /** \brief chained list of Fl_Image's used in this page */
+ struct chain_elt *image_list_;
+#ifdef __APPLE__
+ /** \brief deletes the page image list */
+ void delete_image_list();
+#endif
+ /** \brief The constructor */
+ Fl_Paged_Device() : Fl_Surface_Device(NULL) {type_ = device_type;};
+ /** \brief The destructor */
+ virtual ~Fl_Paged_Device() {};
+public:
+ static const char *device_type;
+ virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
+ virtual int start_page(void);
+ virtual int printable_rect(int *w, int *h);
+ virtual void margins(int *left, int *top, int *right, int *bottom);
+ virtual void origin(int x, int y);
+ void origin(int *x, int *y);
+ virtual void scale(float scale_x, float scale_y);
+ virtual void rotate(float angle);
+ virtual void translate(int x, int y);
+ virtual void untranslate(void);
+ void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
+ void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0);
+ virtual int end_page (void);
+ virtual void end_job (void);
+};
+
+#endif // Fl_Paged_Device_H
+
+//
+// End of "$Id: Fl_Paged_Device.H 7556 2010-04-27 21:33:44Z manolo $"
+//
+
diff --git a/FL/Fl_Pixmap.H b/FL/Fl_Pixmap.H
index 8cab445a5..7391e8341 100644
--- a/FL/Fl_Pixmap.H
+++ b/FL/Fl_Pixmap.H
@@ -45,7 +45,9 @@ struct Fl_Menu_Item;
(pixmap) images, including transparency.
*/
class FL_EXPORT Fl_Pixmap : public Fl_Image {
- friend class Fl_Device;
+ friend class Fl_Quartz_Graphics_Driver;
+ friend class Fl_GDI_Graphics_Driver;
+ friend class Fl_Xlib_Graphics_Driver;
void copy_data();
void delete_data();
void set_data(const char * const *p);
@@ -67,7 +69,6 @@ class FL_EXPORT Fl_Pixmap : public Fl_Image {
unsigned id_; // for internal use
unsigned mask_; // for internal use (mask bitmap)
#endif // __APPLE__ || WIN32
- void generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy);
public:
diff --git a/FL/Fl_PostScript.H b/FL/Fl_PostScript.H
new file mode 100644
index 000000000..8d16dc1c6
--- /dev/null
+++ b/FL/Fl_PostScript.H
@@ -0,0 +1,293 @@
+//
+// "$Id: Fl_PostScript.H 7556 2010-04-27 21:33:44Z manolo $"
+//
+// Support for graphics output to PostScript file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+/** \file Fl_PostScript.H
+ \brief declaration of classes Fl_PostScript_Graphics_Driver, Fl_PostScript_File_Device.
+ */
+
+
+#ifndef Fl_PostScript_H
+#define Fl_PostScript_H
+
+#include <FL/Fl_Paged_Device.H>
+#include <FL/fl_draw.H>
+
+#define NO_PAGE_FORMATS 30 /* MSVC6 compilation fix */
+
+/**
+ \brief PostScript graphical backend.
+ *
+ PostScript text output is presently implemented only for the latin character set.
+ FLTK's standard fonts are output using PostScript's standard fonts: Helvetica, Courier,
+ Times (and their bold, oblique, italic variants), Symbol, ZapfDingbats.
+ */
+class Fl_PostScript_Graphics_Driver : public Fl_Graphics_Driver {
+public:
+ static const char *device_type;
+ /**
+ \brief Possible page formats.
+ */
+ enum Page_Format {
+ A0 = 0,
+ A1,
+ A2,
+ A3,
+ A4,
+ A5,
+ A6,
+ A7,
+ A8,
+ A9,
+ B0,
+ B1,
+ B2,
+ B3,
+ B4,
+ B5,
+ B6,
+ B7,
+ B8,
+ B9,
+ B10,
+ C5E,
+ DLE,
+ EXECUTIVE,
+ FOLIO,
+ LEDGER,
+ LEGAL,
+ LETTER,
+ TABLOID,
+ ENVELOPE,
+ MEDIA = 0x1000
+ };
+
+ /**
+ \brief Possible page layouts.
+ */
+ enum Page_Layout {PORTRAIT = 0, LANDSCAPE = 0x100, REVERSED = 0x200, ORIENTATION = 0x300};
+
+#ifndef FL_DOXYGEN
+public:
+ enum SHAPE{NONE=0, LINE, LOOP, POLYGON, POINTS};
+
+typedef struct page_format {
+ int width;
+ int height;
+ const char *name;
+} page_format;
+
+class Clip {
+ public:
+ int x, y, w, h;
+ Clip *prev;
+ };
+ Clip * clip_;
+
+ int lang_level_;
+ int font_;
+ int size_;
+ Fl_Color color_;
+ int gap_;
+ int pages_;
+
+ double width_;
+ double height_;
+
+ int shape_;
+ int linewidth_;// need for clipping, lang level 1-2
+ int linestyle_;//
+ int interpolate_; //interpolation of images
+ unsigned char cr_,cg_,cb_;
+ char linedash_[256];//should be enough
+ void concat(); // transform ror scalable dradings...
+ void reconcat(); //invert
+ void recover(); //recovers the state after grestore (such as line styles...)
+ void reset();
+
+ uchar * mask;
+ int mx; // width of mask;
+ int my; // mask lines
+ //Fl_Color bg_;
+ int (*close_cmd_)(FILE *);
+ int page_policy_;
+ int nPages;
+ int orientation_;
+
+ float scale_x;
+ float scale_y;
+ float angle;
+ int left_margin;
+ int top_margin;
+
+ FILE *output;
+ double pw_, ph_;
+ static const page_format page_formats[NO_PAGE_FORMATS];
+
+ uchar bg_r, bg_g, bg_b;
+ int start_postscript (int pagecount, enum Page_Format format, enum Page_Layout layout);
+ /* int alpha_mask(const uchar * data, int w, int h, int D, int LD=0);
+ */
+ void draw(const char* s, int n, int x, int y) {transformed_draw(s,n,x,y); };
+ void draw(int angle, const char *str, int n, int x, int y);
+ void transformed_draw(const char* s, int n, double x, double y); //precise text placing
+ void transformed_draw(const char* s, double x, double y);
+ int alpha_mask(const uchar * data, int w, int h, int D, int LD=0);
+ void draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0);
+ void draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D=3, int LD=0);
+ void draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D);
+ void draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D);
+
+ enum Page_Format page_format_;
+ char *ps_filename_;
+ // implementation of drawing methods
+ void color(Fl_Color c);
+ //void bg_color(Fl_Color bg);
+ void color(uchar r, uchar g, uchar b);
+ Fl_Color color(){return color_;};
+
+ void push_clip(int x, int y, int w, int h);
+ int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
+ int not_clipped(int x, int y, int w, int h);
+ void push_no_clip();
+ void pop_clip();
+
+ void line_style(int style, int width=0, char* dashes=0);
+
+ void rect(int x, int y, int w, int h);
+ void rectf(int x, int y, int w, int h);
+
+ void xyline(int x, int y, int x1);
+ void xyline(int x, int y, int x1, int y2);
+ void xyline(int x, int y, int x1, int y2, int x3);
+
+ void yxline(int x, int y, int y1);
+ void yxline(int x, int y, int y1, int x2);
+ void yxline(int x, int y, int y1, int x2, int y3);
+
+ void line(int x1, int y1, int x2, int y2);
+ void line(int x1, int y1, int x2, int y2, int x3, int y3);
+
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2);
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+ void point(int x, int y);
+
+ void begin_points();
+ void begin_line();
+ void begin_loop();
+ void begin_polygon();
+ void vertex(double x, double y);
+ void curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3);
+ void circle(double x, double y, double r);
+ void arc(double x, double y, double r, double start, double a);
+ void arc(int x, int y, int w, int h, double a1, double a2);
+ void pie(int x, int y, int w, int h, double a1, double a2);
+ void end_points();
+ void end_line();
+ void end_loop();
+ void end_polygon();
+ void begin_complex_polygon(){begin_polygon();};
+ void gap(){gap_=1;};
+ void end_complex_polygon(){end_polygon();};
+ void transformed_vertex(double x, double y);
+
+ void font(int face, int size);
+ int font(){return font_;};
+ int size(){return size_;};
+ double width(unsigned c);
+ double width(const char* s, int n);
+ int descent();
+ int height();
+
+ void draw_image(const uchar* d, int x,int y,int w,int h, int delta=3, int ldelta=0){draw_scaled_image(d,x,y,w,h,w,h,delta,ldelta);};
+ void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, int ld=0){draw_scaled_image_mono(d,x,y,w,h,w,h,delta,ld);};
+ void draw_image(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=3){draw_scaled_image(call,data, x, y, w, h, w, h, delta);};
+ void draw_image_mono(Fl_Draw_Image_Cb call, void* data, int x,int y, int w, int h, int delta=1){draw_scaled_image_mono(call, data, x, y, w, h, w, h, delta);};
+
+ void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy);
+
+public:
+ void page_policy(int p);
+ int page_policy(){return page_policy_;};
+ void close_command( int (*cmd)(FILE *)){close_cmd_=cmd;};
+ FILE * file() {return output;};
+ //void orientation (int o);
+ //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int pages = 0); // ps (also multi-page) constructor
+ //Fl_PostScript_Graphics_Driver(FILE *o, int lang_level, int x, int y, int w, int h); //eps constructor
+ void interpolate(int i){interpolate_=i;};
+ int interpolate(){return interpolate_;}
+
+ void page(double pw, double ph, int media = 0);
+ void page(int format);
+
+ void place(double x, double y, double tx, double ty, double scale = 1);
+#endif // FL_DOXYGEN
+ Fl_PostScript_Graphics_Driver();
+ ~Fl_PostScript_Graphics_Driver();
+};
+
+/**
+ \brief To send graphical output to a PostScript file.
+ */
+class Fl_PostScript_File_Device : public Fl_Paged_Device {
+#ifdef __APPLE__
+ CGContextRef gc;
+#endif
+protected:
+ Fl_PostScript_Graphics_Driver *driver();
+public:
+ static const char *device_type;
+ Fl_PostScript_File_Device();
+ ~Fl_PostScript_File_Device();
+ int start_job(int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4,
+ enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT);
+ int start_job(FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format = Fl_PostScript_Graphics_Driver::A4,
+ enum Fl_PostScript_Graphics_Driver::Page_Layout layout = Fl_PostScript_Graphics_Driver::PORTRAIT);
+ 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 scale (float scale_x, float scale_y);
+ void rotate(float angle);
+ void translate(int x, int y);
+ void untranslate(void);
+ int end_page (void);
+ void end_job(void);
+#ifdef __APPLE__
+ void set_current() { fl_gc = gc; Fl_Paged_Device::set_current(); }
+#endif
+
+ static const char *file_chooser_title;
+};
+
+#endif // Fl_PostScript_H
+
+//
+// End of "$Id: Fl_PostScript.H 7556 2010-04-27 21:33:44Z manolo $"
+//
diff --git a/FL/Fl_Printer.H b/FL/Fl_Printer.H
index 8aba8dc81..07b7b5ff3 100644
--- a/FL/Fl_Printer.H
+++ b/FL/Fl_Printer.H
@@ -25,55 +25,34 @@
// http://www.fltk.org/str.php
//
/** \file Fl_Printer.H
- \brief declaration of classes Fl_Printer, Fl_Device_Plugin.
+ \brief declaration of classes Fl_System_Printer, Fl_PostScript_Printer, Fl_Printer, Fl_Device_Plugin.
*/
#ifndef Fl_Printer_H
#define Fl_Printer_H
-#include <FL/Fl_Abstract_Printer.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>
+#if !(defined(__APPLE__) || defined(WIN32))
+#include <FL/Fl_PostScript.H>
+#endif
#if defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN)
/**
- * @brief Provides an OS-independent interface to printing.
- *
- It allows to use all FLTK drawing, color, text, and clip functions, and to have them operate
- on printed page(s). There are two main, non exclusive, ways to use it.
- <ul><li>Print any widget (standard, custom, Fl_Window, Fl_Gl_Window) as it appears
- on screen, with optional translation and scaling. This is done by calling print_widget()
- or print_window_part().
- <li>Use a series of FLTK graphics commands (e.g., font, text, lines, colors, clip) to
- compose a page appropriately shaped for printing.
- </ul>
- In both cases, begin by start_job(), start_page(), printable_rect() and origin() calls
- and finish by end_page() and end_job() calls.
- <p><b>Platform specifics</b>
- <ul>
- <li>Xlib-based platforms (<i>e.g.</i>, Linux, Unix): this class is implemented as
- a subclass of Fl_PSfile_Device.
- Use the static public attributes of this class to set the print dialog to other languages
- than English. For example, the "Printer:" dialog item Fl_Printer::dialog_printer can be set to French with:
- \code
- Fl_Printer::dialog_printer = "Imprimante:";
- Fl_Printer myprinter;
- myprinter.start_job();
- \endcode
- Use Fl_PSfile_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.
- Class Fl_RGB_Image prints but loses its transparency if it has one.
- <li>MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers.
- 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.
- </ul>
+ \brief Print support under MSWindows and Mac OS X.
+*
+ Use Fl_Printer instead that is cross-platform and has the same API.
+ Fl_Printer is typedef'ed to Fl_System_Printer under MSWindows and Mac OS X.
*/
-class Fl_Printer : public Fl_Abstract_Printer {
+class Fl_System_Printer : public Fl_Paged_Device {
private:
+ /** \brief the printer's graphics context, if there's one, NULL otherwise */
+ void *gc;
+ void set_current();
#ifdef __APPLE__
float scale_x;
float scale_y;
@@ -91,96 +70,174 @@ private:
void absolute_printable_rect(int *x, int *y, int *w, int *h);
#endif
public:
+ static const char *device_type;
/**
@brief The constructor.
*/
- Fl_Printer(void);
+ Fl_System_Printer(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);
-#ifdef FL_DOXYGEN
- void origin(int *x, int *y);
-#endif
void scale (float scale_x, float scale_y);
void rotate(float angle);
void translate(int x, int y);
void untranslate(void);
-#ifdef FL_DOXYGEN
- void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
- void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0);
-#endif
int end_page (void);
void end_job (void);
/**
@brief The destructor.
*/
- ~Fl_Printer(void);
-
-#else // Xlib (Linux/Unix)
-
-#include <FL/Fl_PSfile_Device.H>
-
-class Fl_Printer : public Fl_PSfile_Device {
-
+ ~Fl_System_Printer(void);
+#ifndef FL_DOXYGEN
public:
+ static const char *dialog_title;
+ static const char *dialog_printer;
+ static const char *dialog_range;
+ static const char *dialog_copies;
+ static const char *dialog_all;
+ static const char *dialog_pages;
+ static const char *dialog_from;
+ static const char *dialog_to;
+ static const char *dialog_properties;
+ static const char *dialog_copyNo;
+ static const char *dialog_print_button;
+ static const char *dialog_cancel_button;
+ static const char *dialog_print_to_file;
+ static const char *property_title;
+ static const char *property_pagesize;
+ static const char *property_mode;
+ static const char *property_use;
+ static const char *property_save;
+ static const char *property_cancel;
+#endif // FL_DOXYGEN
+}; // class Fl_System_Printer
- Fl_Printer(void) {};
- ~Fl_Printer(void) {};
+/** \brief OS-independant class name */
+typedef Fl_System_Printer Fl_Printer;
+#endif
+
+#if !(defined(__APPLE__) || defined(WIN32))
+/**
+ \brief Print support under Unix/Linux.
+ *
+ Use Fl_Printer instead that is cross-platform and has the same API.
+ Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux.
+ */
+class Fl_PostScript_Printer : public Fl_PostScript_File_Device {
+private:
+ void set_current();
+public:
+ static const char *device_type;
int start_job(int pages, int *firstpage = NULL, int *lastpage = NULL);
-#endif // Fl_Printer (platform-dependent)
-
- // Fl_Printer:: common for all platforms
+#ifndef FL_DOXYGEN
+ static const char *dialog_title;
+ static const char *dialog_printer;
+ static const char *dialog_range;
+ static const char *dialog_copies;
+ static const char *dialog_all;
+ static const char *dialog_pages;
+ static const char *dialog_from;
+ static const char *dialog_to;
+ static const char *dialog_properties;
+ static const char *dialog_copyNo;
+ static const char *dialog_print_button;
+ static const char *dialog_cancel_button;
+ static const char *dialog_print_to_file;
+ static const char *property_title;
+ static const char *property_pagesize;
+ static const char *property_mode;
+ static const char *property_use;
+ static const char *property_save;
+ static const char *property_cancel;
+#endif // FL_DOXYGEN
+};
-public: // just to be sure ...
+/** \brief OS-independant class name */
+typedef Fl_PostScript_Printer Fl_Printer;
+#endif
- /** \name These attributes apply to the Xlib platform only.
+/**
+ * @brief OS-independent print support.
+ *
+ Fl_Printer allows to use all FLTK drawing, color, text, and clip functions, and to have them operate
+ on printed page(s). There are two main, non exclusive, ways to use it.
+ <ul><li>Print any widget (standard, custom, Fl_Window, Fl_Gl_Window) as it appears
+ on screen, with optional translation and scaling. This is done by calling print_widget()
+ or print_window_part().
+ <li>Use a series of FLTK graphics commands (e.g., font, text, lines, colors, clip) to
+ compose a page appropriately shaped for printing.
+ </ul>
+ In both cases, begin by start_job(), start_page(), printable_rect() and origin() calls
+ and finish by end_page() and end_job() calls.
+ <p><b>Platform specifics</b>
+ <br>Fl_Printer is typedef'ed to Fl_PostScript_Printer under Unix/Linux
+ and to Fl_System_Printer otherwise. Both classes have the same API.
+ <ul>
+ <li>Unix/Linux platforms:
+ Use the static public attributes of this class to set the print dialog to other languages
+ than English. For example, the "Printer:" dialog item Fl_Printer::dialog_printer can be set to French with:
+ \code
+ Fl_Printer::dialog_printer = "Imprimante:";
+ Fl_Printer myprinter;
+ myprinter.start_job();
+ \endcode
+ 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.
+ Class Fl_RGB_Image prints but loses its transparency if it has one.
+ <li>MSWindows platform: Transparent Fl_RGB_Image 's don't print with exact transparency on most printers.
+ 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.
+ </ul>
+ */
+#ifdef FL_DOXYGEN
+// this class is NOT compiled. It's here for Doxygen documentation purpose only
+class Fl_Printer : public Fl_System_Printer, Fl_PostScript_Printer {
+public:
+ static const char *device_type;
+ Fl_Printer(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 scale(float scale_x, float scale_y);
+ void rotate(float angle);
+ void translate(int x, int y);
+ void untranslate(void);
+ int end_page (void);
+ void end_job (void);
+ ~Fl_Printer(void);
+
+ /** \name These attributes are effective under the Xlib platform only.
\{
*/
- /** [this text may be customized at run-time] */
static const char *dialog_title;
- /** [this text may be customized at run-time] */
static const char *dialog_printer;
- /** [this text may be customized at run-time] */
static const char *dialog_range;
- /** [this text may be customized at run-time] */
static const char *dialog_copies;
- /** [this text may be customized at run-time] */
static const char *dialog_all;
- /** [this text may be customized at run-time] */
static const char *dialog_pages;
- /** [this text may be customized at run-time] */
static const char *dialog_from;
- /** [this text may be customized at run-time] */
static const char *dialog_to;
- /** "Properties..." [this text may be customized at run-time] */
static const char *dialog_properties;
- /** [this text may be customized at run-time] */
static const char *dialog_copyNo;
- /** [this text may be customized at run-time] */
static const char *dialog_print_button;
- /** [this text may be customized at run-time] */
static const char *dialog_cancel_button;
- /** [this text may be customized at run-time] */
static const char *dialog_print_to_file;
- /** [this text may be customized at run-time] */
static const char *property_title;
- /** [this text may be customized at run-time] */
static const char *property_pagesize;
- /** [this text may be customized at run-time] */
static const char *property_mode;
- /** [this text may be customized at run-time] */
static const char *property_use;
- /** [this text may be customized at run-time] */
static const char *property_save;
- /** [this text may be customized at run-time] */
static const char *property_cancel;
- /** \} */
-
-}; // class Fl_Printer
+ /** \} */
+};
+#endif
/**
This plugin socket allows the integration of new device drivers for special
diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx
index 13d5bcaee..d80d810a1 100644
--- a/src/Fl_Bitmap.cxx
+++ b/src/Fl_Bitmap.cxx
@@ -37,6 +37,7 @@
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Bitmap.H>
+#include <FL/Fl_Printer.H>
#include "flstring.h"
#if defined(__APPLE_QUARTZ__)
@@ -251,49 +252,66 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
}
-void Fl_Bitmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) {
- if (!array) {
- draw_empty(XP, YP);
- return;
- }
-
+static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy,
+ int &X, int &Y, int &W, int &H)
+{
// account for current clip region (faster on Irix):
- int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+ fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
- if ((cx+W) > w()) W = w()-cx;
- if (W <= 0) return;
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return 1;
if (cy < 0) {H += cy; Y -= cy; cy = 0;}
- if ((cy+H) > h()) H = h()-cy;
- if (H <= 0) return;
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return 1;
+ return 0;
+}
-#if defined(USE_X11)
- if (!id_) id_ = fl_create_bitmask(w(), h(), array);
+#ifdef __APPLE__
+void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (!bm->array) {
+ bm->draw_empty(XP, YP);
+ return;
+ }
+ if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
+ if (bm->id_ && fl_gc) {
+ CGRect rect = { { X, Y }, { W, H } };
+ Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h());
+ CGContextDrawImage(fl_gc, rect, (CGImageRef)bm->id_);
+ Fl_X::q_end_image();
+ }
+}
- XSetStipple(fl_display, fl_gc, id_);
- int ox = X-cx; if (ox < 0) ox += w();
- int oy = Y-cy; if (oy < 0) oy += h();
- XSetTSOrigin(fl_display, fl_gc, ox, oy);
- XSetFillStyle(fl_display, fl_gc, FillStippled);
- XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H);
- XSetFillStyle(fl_display, fl_gc, FillSolid);
#elif defined(WIN32)
- if (!id_) id_ = fl_create_bitmap(w(), h(), array);
-
+void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (!bm->array) {
+ bm->draw_empty(XP, YP);
+ return;
+ }
+ if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!bm->id_) bm->id_ = fl_create_bitmap(bm->w(), bm->h(), bm->array);
+
typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
static fl_transp_func fl_TransparentBlt;
HDC tempdc;
int save;
BOOL use_print_algo = false;
- if (fl_device->type() == Fl_Device::gdi_printer) {
+ if (fl_surface->type() == Fl_Printer::device_type) {
static HMODULE hMod = NULL;
if (!hMod) {
hMod = LoadLibrary("MSIMG32.DLL");
if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
- }
- if (hMod) use_print_algo = true;
}
+ if (hMod) use_print_algo = true;
+ }
if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer
Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
fl_begin_offscreen(tmp_id);
@@ -309,37 +327,48 @@ void Fl_Bitmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int
fl_color(save_c); // back to bitmap's color
tempdc = CreateCompatibleDC(fl_gc);
save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)id_);
+ SelectObject(tempdc, (HGDIOBJ)bm->id_);
SelectObject(fl_gc, fl_brush()); // use bitmap's desired color
BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
fl_end_offscreen(); // offscreen data is in tmp_id
SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
// draw it to printer context with background color as transparent
- fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, w(), h(), RGB(r, g, b) );
+ fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) );
fl_delete_offscreen(tmp_id);
- }
+ }
else { // algorithm for bitmap output to display
tempdc = CreateCompatibleDC(fl_gc);
save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)id_);
+ SelectObject(tempdc, (HGDIOBJ)bm->id_);
SelectObject(fl_gc, fl_brush());
// secret bitblt code found in old MSWindows reference manual:
BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
- }
+ }
RestoreDC(tempdc, save);
DeleteDC(tempdc);
-#elif defined(__APPLE_QUARTZ__)
- if (!id_) id_ = fl_create_bitmask(w(), h(), array);
- if (id_ && fl_gc) {
- CGRect rect = { { X, Y }, { W, H } };
- Fl_X::q_begin_image(rect, cx, cy, w(), h());
- CGContextDrawImage(fl_gc, rect, (CGImageRef)id_);
- Fl_X::q_end_image();
+}
+
+#else // Xlib
+void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (!bm->array) {
+ bm->draw_empty(XP, YP);
+ return;
}
-#else
-# error unsupported platform
-#endif
+ if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
+
+ XSetStipple(fl_display, fl_gc, bm->id_);
+ int ox = X-cx; if (ox < 0) ox += bm->w();
+ int oy = Y-cy; if (oy < 0) oy += bm->h();
+ XSetTSOrigin(fl_display, fl_gc, ox, oy);
+ XSetFillStyle(fl_display, fl_gc, FillStippled);
+ XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H);
+ XSetFillStyle(fl_display, fl_gc, FillSolid);
}
+#endif
/**
The destructor free all memory and server resources that are used by
diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx
index 9c76d3f6f..a7315552b 100644
--- a/src/Fl_Device.cxx
+++ b/src/Fl_Device.cxx
@@ -29,51 +29,26 @@
#include <FL/Fl_Device.H>
#include <FL/Fl_Image.H>
-/** \brief Draws an Fl_Pixmap object to the device.
- *
- Specifies a bounding box for the image, with the origin (upper left-hand corner) of
- the image offset by the cx and cy arguments.
- */
-void Fl_Device::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
- pxm->generic_device_draw(XP, YP, WP, HP, cx, cy);
-}
-
-/** \brief Draws an Fl_Bitmap object to the device.
- *
- Specifies a bounding box for the image, with the origin (upper left-hand corner) of
- the image offset by the cx and cy arguments.
- */
-void Fl_Device::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
- bm->generic_device_draw(XP, YP, WP, HP, cx, cy);
-}
+const char *Fl_Device::device_type = "Fl_Device";
+const char *Fl_Surface_Device::device_type = "Fl_Surface_Device";
+const char *Fl_Display_Device::device_type = "Fl_Display_Device";
+const char *Fl_Graphics_Driver::device_type = "Fl_Graphics_Driver";
+#if defined(__APPLE__) || defined(FL_DOXYGEN)
+const char *Fl_Quartz_Graphics_Driver::device_type = "Fl_Quartz_Graphics_Driver";
+#endif
+#if defined(WIN32) || defined(FL_DOXYGEN)
+const char *Fl_GDI_Graphics_Driver::device_type = "Fl_GDI_Graphics_Driver";
+#endif
+#if !(defined(__APPLE__) || defined(WIN32))
+const char *Fl_Xlib_Graphics_Driver::device_type = "Fl_Xlib_Graphics_Driver";
+#endif
-/** \brief Draws an Fl_RGB_Image object to the device.
- *
- Specifies a bounding box for the image, with the origin (upper left-hand corner) of
- the image offset by the cx and cy arguments.
- */
-void Fl_Device::draw(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
- rgb->generic_device_draw(XP, YP, WP, HP, cx, cy);
-}
-
-/**
- @brief Sets this device (display, printer, local file) as the target of future graphics calls.
- *
- @return The current target device of graphics calls.
- */
-Fl_Device *Fl_Device::set_current(void)
-{
- Fl_Device *current = fl_device;
- fl_device = this;
- return current;
-}
-/**
- @brief Returns the current target device of graphics calls.
- */
-Fl_Device *Fl_Device::current(void)
+/** \brief Use this drawing surface for future graphics requests. */
+void Fl_Surface_Device::set_current(void)
{
- return fl_device;
+ fl_device = _driver;
+ fl_surface = this;
}
//
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
index 89f838844..bd2155329 100644
--- a/src/Fl_Double_Window.cxx
+++ b/src/Fl_Double_Window.cxx
@@ -28,6 +28,7 @@
#include <config.h>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Printer.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
@@ -142,18 +143,24 @@ void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy)
DeleteDC(new_gc);
}
+//#include <FL/fl_ask.H>
void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
BOOL alpha_ok = 0;
// first try to alpha blend
- int to_display = Fl_Device::current()->type() < 256; // true iff display output
- if ( (!to_display) || fl_can_do_alpha_blending()) // if not on display, always try alpha_blend
+ // if to printer, always try alpha_blend
+ int to_display = Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type; // true iff display output
+//fl_alert("to_display=%d ",to_display);
+ if ( (to_display && fl_can_do_alpha_blending()) || Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) {
alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc);
+//fl_alert("alpha_ok=%d",alpha_ok);
+ }
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
- if (!alpha_ok)
+ if (!alpha_ok) {
BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
+ }
RestoreDC(new_gc, save);
DeleteDC(new_gc);
}
diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx
index f89374095..a7fa9fea2 100644
--- a/src/Fl_GDI_Printer.cxx
+++ b/src/Fl_GDI_Printer.cxx
@@ -34,12 +34,13 @@
extern HWND fl_window;
-Fl_Printer::Fl_Printer(void) : Fl_Abstract_Printer() {
+Fl_Printer::Fl_System_Printer(void) : Fl_Paged_Device() {
hPr = NULL;
- type_ = gdi_printer;
+ type_ = device_type;
+ driver(fl_device);
}
-Fl_Printer::~Fl_Printer(void) {
+Fl_Printer::~Fl_System_Printer(void) {
if (hPr) end_job();
}
@@ -117,7 +118,7 @@ int Fl_Printer::start_job (int pagecount, int *frompage, int *topage)
void Fl_Printer::end_job (void)
{
- Fl_Device::display_device()->set_current();
+ Fl_Display_Device::display_device()->set_current();
if (hPr != NULL) {
if (! abortPrint) {
prerr = EndDoc (hPr);
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx
index bf39f6b09..65636c73c 100644
--- a/src/Fl_Image.cxx
+++ b/src/Fl_Image.cxx
@@ -437,7 +437,7 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
}
-void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+/*void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) {
// Don't draw an empty image...
if (!d() || !array) {
draw_empty(XP, YP);
@@ -542,8 +542,146 @@ void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, i
#else
# error unsupported platform
#endif
+}*/
+
+static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy,
+ int &X, int &Y, int &W, int &H)
+{
+ // account for current clip region (faster on Irix):
+ fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+ cx += X-XP; cy += Y-YP;
+ // clip the box down to the size of image, quit if empty:
+ if (cx < 0) {W += cx; X -= cx; cx = 0;}
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return 1;
+ if (cy < 0) {H += cy; Y -= cy; cy = 0;}
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return 1;
+ return 0;
}
+#ifdef __APPLE__
+void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ // Don't draw an empty image...
+ if (!img->d() || !img->array) {
+ img->draw_empty(XP, YP);
+ return;
+ }
+ if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!img->id_) {
+ CGColorSpaceRef lut = 0;
+ if (img->d()<=2)
+ lut = CGColorSpaceCreateDeviceGray();
+ else
+ lut = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef src = CGDataProviderCreateWithData( 0L, img->array, img->w()*img->h()*img->d(), 0L);
+ img->id_ = CGImageCreate( img->w(), img->h(), 8, img->d()*8, img->ld()?img->ld():img->w()*img->d(),
+ lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
+ src, 0L, false, kCGRenderingIntentDefault);
+ CGColorSpaceRelease(lut);
+ CGDataProviderRelease(src);
+ }
+ if (img->id_ && fl_gc) {
+ CGRect rect = { { X, Y }, { W, H } };
+ Fl_X::q_begin_image(rect, cx, cy, img->w(), img->h());
+ CGContextDrawImage(fl_gc, rect, (CGImageRef)img->id_);
+ Fl_X::q_end_image();
+ }
+}
+
+#elif defined(WIN32)
+void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ // Don't draw an empty image...
+ if (!img->d() || !img->array) {
+ img->draw_empty(XP, YP);
+ return;
+ }
+ if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!img->id_) {
+ img->id_ = fl_create_offscreen(img->w(), img->h());
+ if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) {
+ fl_begin_offscreen((Fl_Offscreen)img->id_);
+ fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld());
+ fl_end_offscreen();
+ } else {
+ fl_begin_offscreen((Fl_Offscreen)img->id_);
+ fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld());
+ fl_end_offscreen();
+ if (img->d() == 2 || img->d() == 4) {
+ img->mask_ = fl_create_alphamask(img->w(), img->h(), img->d(), img->ld(), img->array);
+ }
+ }
+ }
+ if (img->mask_) {
+ HDC new_gc = CreateCompatibleDC(fl_gc);
+ int save = SaveDC(new_gc);
+ SelectObject(new_gc, (void*)img->mask_);
+ BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
+ SelectObject(new_gc, (void*)img->id_);
+ BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
+ RestoreDC(new_gc,save);
+ DeleteDC(new_gc);
+ } else if (img->d()==2 || img->d()==4) {
+ fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy);
+ } else {
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy);
+ }
+}
+
+#else
+void Fl_Xlib_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ // Don't draw an empty image...
+ if (!img->d() || !img->array) {
+ img->draw_empty(XP, YP);
+ return;
+ }
+ if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!img->id_) {
+ if (img->d() == 1 || img->d() == 3) {
+ img->id_ = fl_create_offscreen(img->w(), img->h());
+ fl_begin_offscreen((Fl_Offscreen)img->id_);
+ fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld());
+ fl_end_offscreen();
+ }
+ }
+ if (img->id_) {
+ if (img->mask_) {
+ // I can't figure out how to combine a mask with existing region,
+ // so cut the image down to a clipped rectangle:
+ int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
+ cx += nx-X; X = nx;
+ cy += ny-Y; Y = ny;
+ // make X use the bitmap as a mask:
+ XSetClipMask(fl_display, fl_gc, img->mask_);
+ int ox = X-cx; if (ox < 0) ox += img->w();
+ int oy = Y-cy; if (oy < 0) oy += img->h();
+ XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
+ }
+
+ fl_copy_offscreen(X, Y, W, H, img->id_, cx, cy);
+
+ if (img->mask_) {
+ // put the old clip region back
+ XSetClipOrigin(fl_display, fl_gc, 0, 0);
+ fl_restore_clip();
+ }
+ } else {
+ // Composite image with alpha manually each time...
+ alpha_blend(img, X, Y, W, H, cx, cy);
+ }
+}
+
+#endif
+
void Fl_RGB_Image::label(Fl_Widget* widget) {
widget->image(this);
}
diff --git a/src/Fl_Paged_Device.cxx b/src/Fl_Paged_Device.cxx
new file mode 100644
index 000000000..52001a060
--- /dev/null
+++ b/src/Fl_Paged_Device.cxx
@@ -0,0 +1,291 @@
+//
+// "$Id: Fl_Paged_Device.cxx 7556 2010-04-27 21:33:44Z manolo $"
+//
+// implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to:
+//
+// http://www.fltk.org/str.php
+//
+/** \file Fl_Paged_Device.cxx
+ \brief implementation of class Fl_Paged_Device.
+ */
+
+#include <FL/Fl.H>
+#include <FL/Fl_Printer.H>
+
+const char *Fl_Paged_Device::device_type = "Fl_Paged_Device";
+
+
+/**
+ @brief Draws the widget on the printed page.
+ *
+ The widget's position on the printed page is determined by the last call to origin()
+ and by the optional delta_x and delta_y arguments.
+ Its dimensions are in points unless there was a previous call to scale().
+ @param[in] widget Any FLTK widget (e.g., standard, custom, window).
+ @param[in] delta_x Optional horizontal offset for positioning the widget relatively
+ to the current origin of graphics functions.
+ @param[in] delta_y Same as above, vertically.
+ */
+void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y)
+{
+ int old_x, old_y, new_x, new_y, is_window;
+ if ( ! widget->visible() ) return;
+ is_window = (widget->as_window() != NULL);
+ widget->damage(FL_DAMAGE_ALL);
+ // set origin to the desired top-left position of the widget
+ origin(&old_x, &old_y);
+ new_x = old_x + delta_x;
+ new_y = old_y + delta_y;
+ if (!is_window) {
+ new_x -= widget->x();
+ new_y -= widget->y();
+ }
+ if (new_x != old_x || new_y != old_y) {
+ translate(new_x - old_x, new_y - old_y );
+ }
+ // if widget is a window, clip all drawings to the window area
+ if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() );
+ // we do some trickery to recognize OpenGL windows and draw them via a plugin
+ int drawn_by_plugin = 0;
+ if (widget->as_gl_window()) {
+ Fl_Plugin_Manager pm("fltk:device");
+ Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
+ if (pi) {
+ int width, height;
+ this->printable_rect(&width, &height);
+ drawn_by_plugin = pi->print(widget, 0, 0, height);
+ }
+ }
+ if (!drawn_by_plugin) {
+ widget->draw();
+ }
+ if (is_window) fl_pop_clip();
+ // find subwindows of widget and print them
+ traverse(widget);
+ // reset origin to where it was
+ if (new_x != old_x || new_y != old_y) {
+ untranslate();
+ }
+}
+
+
+void Fl_Paged_Device::traverse(Fl_Widget *widget)
+{
+ Fl_Group *g = widget->as_group();
+ if (!g) return;
+ int n = g->children();
+ for (int i = 0; i < n; i++) {
+ Fl_Widget *c = g->child(i);
+ if ( !c->visible() ) continue;
+ if ( c->as_window() ) {
+ print_widget(c, c->x(), c->y());
+ }
+ else traverse(c);
+ }
+}
+
+/**
+ @brief Computes the page coordinates of the current origin of graphics functions.
+ *
+ @param[out] x If non-null, *x is set to the horizontal page offset of graphics origin.
+ @param[out] y Same as above, vertically.
+ */
+void Fl_Paged_Device::origin(int *x, int *y)
+{
+ if (x) *x = x_offset;
+ if (y) *y = y_offset;
+}
+
+/**
+ @brief Prints a rectangular part of an on-screen window.
+ *
+ @param win The window from where to capture.
+ @param x The rectangle left
+ @param y The rectangle top
+ @param w The rectangle width
+ @param h The rectangle height
+ @param delta_x Optional horizontal offset from current graphics origin where to print the captured rectangle.
+ @param delta_y As above, vertically.
+ */
+void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
+{
+ int slice, width, offset, count = 0;
+ 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_gc = NULL;
+ Fl::check();
+ win->make_current();
+ uchar *image_data[20];
+#ifdef WIN32 // because of bug in StretchDIBits, vertically cut image in pieces of width slice
+ slice = 500;
+#else
+ slice = w;
+#endif
+ for ( offset = 0; offset < w; offset += slice) {
+ width = slice;
+ if (offset + width > w) width = w - offset;
+ image_data[count++] = fl_read_image(NULL, x + offset, y, width, h);
+ }
+ save_front->show();
+ current->set_current();
+ for ( int i = 0, offset = 0; i < count; i++, offset += slice) {
+ width = slice;
+ if (offset + width > w) width = w - offset;
+ fl_draw_image(image_data[i], delta_x + offset, delta_y, width, h, 3);
+#ifdef __APPLE__
+ add_image(NULL, image_data[i]);
+#else
+ delete image_data[i];
+#endif
+ }
+}
+
+#ifdef __APPLE__
+void Fl_Paged_Device::add_image(Fl_Image *image, const uchar *data)
+{
+ struct chain_elt *elt = (struct chain_elt *)calloc(sizeof(struct chain_elt), 1);
+ elt->image = image;
+ elt->data = data;
+ if (image_list_) { elt->next = image_list_; }
+ image_list_ = elt;
+}
+
+void Fl_Paged_Device::delete_image_list()
+{
+ while(image_list_) {
+ struct chain_elt *next = image_list_->next;
+ if(image_list_->image) delete image_list_->image;
+ if (image_list_->data) delete (uchar*) image_list_->data; // msvc6 compilation fix
+ free(image_list_);
+ image_list_ = next;
+ }
+}
+#endif
+
+
+/**
+ @brief Starts a print job.
+ *
+ @param[in] pagecount the total number of pages of the job
+ @param[out] frompage if non-null, *frompage is set to the first page the user wants printed
+ @param[out] topage if non-null, *topage is set to the last page the user wants printed
+ @return 0 iff OK
+ */
+int Fl_Paged_Device::start_job(int pagecount, int *frompage, int *topage) {return 1;}
+
+/**
+ @brief Starts a new printed page
+ *
+ The page coordinates are initially in points, i.e., 1/72 inch,
+ and with origin at the top left of the printable page area.
+ @return 0 iff OK
+ */
+int Fl_Paged_Device::start_page (void) {return 1;}
+
+/**
+ @brief Computes the width and height of the printable area of the page.
+ *
+ Values are in the same unit as that used by FLTK drawing functions,
+ are unchanged by calls to origin(), but are changed by scale() calls.
+ Values account for the user-selected paper type and print orientation.
+ @return 0 iff OK.
+ */
+int Fl_Paged_Device::printable_rect(int *w, int *h) {return 1;}
+
+/**
+ @brief Computes the dimensions of margins that lie between the printable page area and
+ the full page.
+ *
+ Values are in the same unit as that used by FLTK drawing functions. They are changed
+ by scale() calls.
+ @param[out] left If non-null, *left is set to the left margin size.
+ @param[out] top If non-null, *top is set to the top margin size.
+ @param[out] right If non-null, *right is set to the right margin size.
+ @param[out] bottom If non-null, *bottom is set to the bottom margin size.
+ */
+void Fl_Paged_Device::margins(int *left, int *top, int *right, int *bottom) {}
+
+/**
+ @brief Sets the position in page coordinates of the origin of graphics functions.
+ *
+ Arguments should be expressed relatively to the result of a previous printable_rect() call.
+ That is, <tt>printable_rect(&w, &h); origin(w/2, 0);</tt> sets the graphics origin at the
+ top center of the page printable area.
+ Origin() calls are not affected by rotate() calls.
+ Successive origin() calls don't combine their effects.
+ @param[in] x Horizontal position in page coordinates of the desired origin of graphics functions.
+ @param[in] y Same as above, vertically.
+ */
+void Fl_Paged_Device::origin(int x, int y) {}
+
+/**
+ @brief Changes the scaling of page coordinates.
+ *
+ This function also resets the origin of graphics functions at top left of printable page area.
+ After a scale() call, do a printable_rect() call to get the new dimensions of the printable page area.
+ Successive scale() calls don't combine their effects.
+ @param scale_x Horizontal dimensions of plot are multiplied by this quantity.
+ @param scale_y Same as above, vertically.
+ */
+void Fl_Paged_Device::scale (float scale_x, float scale_y) {}
+
+/**
+ @brief Rotates the graphics operations relatively to paper.
+ *
+ The rotation is centered on the current graphics origin.
+ Successive rotate() calls don't combine their effects.
+ @param angle Rotation angle in counterclockwise degrees.
+ */
+void Fl_Paged_Device::rotate(float angle) {}
+
+/**
+ @brief To be called at the end of each page.
+ *
+ @return 0 iff OK.
+ */
+int Fl_Paged_Device::end_page (void) {return 1;}
+
+/**
+ @brief To be called at the end of a print job.
+ */
+void Fl_Paged_Device::end_job (void) {}
+
+/**
+ @brief Translates the current graphics origin accounting for the current rotation.
+ *
+ This function is only useful after a rotate() call.
+ Each translate() call must be matched by an untranslate() call.
+ Successive translate() calls add up their effects.
+ */
+void Fl_Paged_Device::translate(int x, int y) {}
+
+/**
+ @brief Undoes the effect of a previous translate() call.
+ */
+void Fl_Paged_Device::untranslate(void) {}
+
+//
+// End of "$Id: Fl_Paged_Device.cxx 7556 2010-04-27 21:33:44Z manolo $".
+//
+
diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx
index d20132a35..a6049760a 100644
--- a/src/Fl_Pixmap.cxx
+++ b/src/Fl_Pixmap.cxx
@@ -47,6 +47,7 @@
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Printer.H>
#include <stdio.h>
#include "flstring.h"
@@ -77,121 +78,161 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
}
-void Fl_Pixmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) {
+static int start(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy,
+ int &X, int &Y, int &W, int &H)
+{
// ignore empty or bad pixmap data:
- if (!data()) {
- draw_empty(XP, YP);
- return;
+ if (!pxm->data()) {
+ return 2;
}
- if (w()<0) measure();
- if (WP==-1) {
- WP = w();
- HP = h();
+ if (WP == -1) {
+ WP = w;
+ HP = h;
}
- if (!w()) {
- draw_empty(XP, YP);
- return;
+ if (!w) {
+ return 2;
}
// account for current clip region (faster on Irix):
- int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
+ fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
- if (cx+W > w()) W = w()-cx;
- if (W <= 0) return;
+ if (cx+W > w) W = w-cx;
+ if (W <= 0) return 1;
if (cy < 0) {H += cy; Y -= cy; cy = 0;}
- if (cy+H > h()) H = h()-cy;
- if (H <= 0) return;
- if (!id_) {
-#ifdef __APPLE_QUARTZ__
- id_ = fl_create_offscreen_with_alpha(w(), h());
- fl_begin_offscreen((Fl_Offscreen)id_);
- fl_draw_pixmap(data(), 0, 0, FL_GREEN);
+ if (cy+H > h) H = h-cy;
+ if (H <= 0) return 1;
+ return 0;
+}
+
+#ifdef __APPLE__
+void Fl_Quartz_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (pxm->w() < 0) pxm->measure();
+ int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H);
+ if (code) {
+ if (code == 2) pxm->draw_empty(XP, YP);
+ return;
+ }
+ if (!pxm->id_) {
+ pxm->id_ = fl_create_offscreen_with_alpha(pxm->w(), pxm->h());
+ fl_begin_offscreen((Fl_Offscreen)pxm->id_);
+ fl_draw_pixmap(pxm->data(), 0, 0, FL_GREEN);
fl_end_offscreen();
-#else
- id_ = fl_create_offscreen(w(), h());
- fl_begin_offscreen((Fl_Offscreen)id_);
+ }
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy);
+}
+
+#elif defined(WIN32)
+void Fl_GDI_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (pxm->w() < 0) pxm->measure();
+ int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H);
+ if (code) {
+ if (code == 2) pxm->draw_empty(XP, YP);
+ return;
+ }
+ if (!pxm->id_) {
+ pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h());
+ fl_begin_offscreen((Fl_Offscreen)pxm->id_);
uchar *bitmap = 0;
fl_mask_bitmap = &bitmap;
- fl_draw_pixmap(data(), 0, 0, FL_BLACK);
+ fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK);
fl_mask_bitmap = 0;
if (bitmap) {
- mask_ = fl_create_bitmask(w(), h(), bitmap);
+ pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap);
delete[] bitmap;
}
fl_end_offscreen();
-#endif
- }
-
-#if defined(USE_X11)
- if (mask_) {
- // I can't figure out how to combine a mask with existing region,
- // so cut the image down to a clipped rectangle:
- int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
- cx += nx-X; X = nx;
- cy += ny-Y; Y = ny;
- // make X use the bitmap as a mask:
- XSetClipMask(fl_display, fl_gc, mask_);
- int ox = X-cx; if (ox < 0) ox += w();
- int oy = Y-cy; if (oy < 0) oy += h();
- XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
}
- fl_copy_offscreen(X, Y, W, H, id_, cx, cy);
- if (mask_) {
- // put the old clip region back
- XSetClipOrigin(fl_display, fl_gc, 0, 0);
- fl_restore_clip();
- }
-#elif defined(WIN32)
- if (fl_device->type() == Fl_Device::gdi_printer) {
+ if (fl_surface->type() == Fl_Printer::device_type) {
typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
static HMODULE hMod = NULL;
static fl_transp_func fl_TransparentBlt = NULL;
if (!hMod) {
hMod = LoadLibrary("MSIMG32.DLL");
if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
- }
+ }
if (hMod) {
- Fl_Offscreen tmp_id = fl_create_offscreen(w(), h());
+ Fl_Offscreen tmp_id = fl_create_offscreen(pxm->w(), pxm->h());
fl_begin_offscreen(tmp_id);
uchar *bitmap = 0;
fl_mask_bitmap = &bitmap;
// draw pixmap to offscreen
- fl_draw_pixmap(data(), 0, 0);
+ fl_draw_pixmap(pxm->data(), 0, 0);
fl_end_offscreen();
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, (void*)tmp_id);
// print all of offscreen but its parts in background color
extern UINT win_pixmap_bg_color; // computed by fl_draw_pixmap()
- fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, w(), h(), win_pixmap_bg_color );
+ fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, pxm->w(), pxm->h(), win_pixmap_bg_color );
RestoreDC(new_gc,save);
DeleteDC(new_gc);
fl_delete_offscreen(tmp_id);
}
else {
- fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy);
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy);
}
}
- else if (mask_) {
+ else if (pxm->mask_) {
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
- SelectObject(new_gc, (void*)mask_);
+ SelectObject(new_gc, (void*)pxm->mask_);
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
- SelectObject(new_gc, (void*)id_);
+ SelectObject(new_gc, (void*)pxm->id_);
BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
RestoreDC(new_gc,save);
DeleteDC(new_gc);
} else {
- fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy);
+ fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy);
}
-#elif defined(__APPLE_QUARTZ__)
- fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy);
-#else
-# error unsupported platform
-#endif
}
+#else // Xlib
+void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ if (pxm->w() < 0) pxm->measure();
+ int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H);
+ if (code) {
+ if (code == 2) pxm->draw_empty(XP, YP);
+ return;
+ }
+ if (!pxm->id_) {
+ pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h());
+ fl_begin_offscreen((Fl_Offscreen)pxm->id_);
+ uchar *bitmap = 0;
+ fl_mask_bitmap = &bitmap;
+ fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK);
+ fl_mask_bitmap = 0;
+ if (bitmap) {
+ pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap);
+ delete[] bitmap;
+ }
+ fl_end_offscreen();
+ }
+ if (pxm->mask_) {
+ // I can't figure out how to combine a mask with existing region,
+ // so cut the image down to a clipped rectangle:
+ int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
+ cx += nx-X; X = nx;
+ cy += ny-Y; Y = ny;
+ // make X use the bitmap as a mask:
+ XSetClipMask(fl_display, fl_gc, pxm->mask_);
+ int ox = X-cx; if (ox < 0) ox += pxm->w();
+ int oy = Y-cy; if (oy < 0) oy += pxm->h();
+ XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
+ }
+ fl_copy_offscreen(X, Y, W, H, pxm->id_, cx, cy);
+ if (pxm->mask_) {
+ // put the old clip region back
+ XSetClipOrigin(fl_display, fl_gc, 0, 0);
+ fl_restore_clip();
+ }
+}
+
+#endif
+
/**
The destructor free all memory and server resources that are used by
the pixmap.
diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx
new file mode 100644
index 000000000..18ae75385
--- /dev/null
+++ b/src/Fl_PostScript.cxx
@@ -0,0 +1,1393 @@
+//
+// "$Id: Fl_PS_Printer.cxx 7520 2010-04-16 20:19:09Z manolo $"
+//
+// PostScript device support for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+#include <stdio.h>
+#include <FL/Fl_PostScript.H>
+#include <FL/Fl_Native_File_Chooser.H>
+
+const char *Fl_PostScript_Graphics_Driver::device_type = "Fl_PostScript_Graphics_Driver";
+const char *Fl_PostScript_File_Device::device_type = "Fl_PostScript_File_Device";
+/** \brief Label of the PostScript file chooser window */
+const char *Fl_PostScript_File_Device::file_chooser_title = "Select a .ps file";
+
+/**
+ @brief The constructor.
+ */
+Fl_PostScript_Graphics_Driver::Fl_PostScript_Graphics_Driver(void)
+{
+ close_cmd_ = 0;
+ //lang_level_ = 3;
+ lang_level_ = 2;
+ mask = 0;
+ ps_filename_ = NULL;
+ type_ = device_type;
+ scale_x = scale_y = 1.;
+ bg_r = bg_g = bg_b = 255;
+}
+
+/** \brief The destructor. */
+Fl_PostScript_Graphics_Driver::~Fl_PostScript_Graphics_Driver() {
+ if(ps_filename_) free(ps_filename_);
+}
+
+/**
+ @brief The constructor.
+ */
+Fl_PostScript_File_Device::Fl_PostScript_File_Device(void)
+{
+ type_ = device_type;
+#ifdef __APPLE__
+ gc = fl_gc; // the display context is used by fl_text_extents()
+#endif
+ Fl_Surface_Device::driver( new Fl_PostScript_Graphics_Driver() );
+}
+
+/**
+ \brief Returns the PostScript driver of this drawing surface.
+ */
+Fl_PostScript_Graphics_Driver *Fl_PostScript_File_Device::driver()
+{
+ return (Fl_PostScript_Graphics_Driver*)Fl_Surface_Device::driver();
+}
+
+
+/**
+ @brief Begins the session where all graphics requests will go to a local PostScript file.
+ *
+ Opens a file dialog entitled with Fl_PostScript_File_Device::file_chooser_title to select an output PostScript file.
+ @param pagecount The total number of pages to be created.
+ @param format Desired page format.
+ @param layout Desired page layout.
+ @return 0 iff OK, 1 if user cancelled the file dialog, 2 if fopen failed on user-selected output file.
+ */
+int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout)
+{
+ Fl_Native_File_Chooser fnfc;
+ fnfc.title(Fl_PostScript_File_Device::file_chooser_title);
+ fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE);
+ fnfc.options(Fl_Native_File_Chooser::SAVEAS_CONFIRM);
+ fnfc.filter("PostScript\t*.ps\n");
+ // Show native chooser
+ if ( fnfc.show() ) return 1;
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ ps->output = fopen(fnfc.filename(), "w");
+ if(ps->output == NULL) return 2;
+ ps->ps_filename_ = strdup(fnfc.filename());
+ ps->start_postscript(pagecount, format, layout);
+ this->set_current();
+ return 0;
+}
+
+/**
+ @brief Begins the session where all graphics requests will go to FILE pointer.
+ *
+ @param ps_output A writable FILE pointer that will receive PostScript output and that will be closed
+ when end_job() will be called.
+ @param pagecount The total number of pages to be created.
+ @param format Desired page format.
+ @param layout Desired page layout.
+ @return always 0.
+ */
+int Fl_PostScript_File_Device::start_job (FILE *ps_output, int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout)
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ ps->output = ps_output;
+ ps->ps_filename_ = NULL;
+ ps->start_postscript(pagecount, format, layout);
+ this->set_current();
+ return 0;
+}
+
+/**
+ @brief The destructor.
+ */
+Fl_PostScript_File_Device::~Fl_PostScript_File_Device() {
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ if (ps) delete ps;
+}
+
+#ifndef FL_DOXYGEN
+
+#if ! (defined(__APPLE__) || defined(WIN32) )
+ #include "print_panel.cxx"
+#endif
+
+const Fl_PostScript_Graphics_Driver::page_format Fl_PostScript_Graphics_Driver::page_formats[NO_PAGE_FORMATS] = { // order of enum Page_Format
+// comes from appendix B of 5003.PPD_Spec_v4.3.pdf
+
+ // A* // index(Ai) = i
+ {2384, 3370, "A0"},
+ {1684, 2384, "A1"},
+ {1191, 1684, "A2"},
+ { 842, 1191, "A3"},
+ { 595, 842, "A4"},
+ { 420, 595, "A5"},
+ { 297, 420, "A6"},
+ { 210, 297, "A7"},
+ { 148, 210, "A8"},
+ { 105, 148, "A9"},
+
+ // B* // index(Bi) = i+10
+ {2920, 4127, "B0"},
+ {2064, 2920, "B1"},
+ {1460, 2064, "B2"},
+ {1032, 1460, "B3"},
+ { 729, 1032, "B4"},
+ { 516, 729, "B5"},
+ { 363, 516, "B6"},
+ { 258, 363, "B7"},
+ { 181, 258, "B8"},
+ { 127, 181, "B9"},
+ { 91, 127, "B10"},
+
+ // others
+ { 459, 649, "EnvC5"}, // envelope
+ { 312, 624, "EnvDL"}, // envelope
+ { 522, 756, "Executive"},
+ { 595, 935, "Folio"},
+ {1224, 792, "Ledger"}, // landscape
+ { 612, 1008, "Legal"},
+ { 612, 792, "Letter"},
+ { 792, 1224, "Tabloid"},
+ { 297, 684, "Env10"} // envelope
+};
+
+// Prolog string
+
+static const char * prolog =
+"%%BeginProlog\n"
+"/L { /y2 exch def\n"
+"/x2 exch def\n"
+"/y1 exch def\n"
+"/x1 exch def\n"
+"newpath x1 y1 moveto x2 y2 lineto\n"
+"stroke}\n"
+"bind def\n"
+
+
+"/R { /dy exch def\n"
+"/dx exch def\n"
+"/y exch def\n"
+"/x exch def\n"
+"newpath\n"
+"x y moveto\n"
+"dx 0 rlineto\n"
+"0 dy rlineto\n"
+"dx neg 0 rlineto\n"
+"closepath stroke\n"
+"} bind def\n"
+
+"/CL {\n"
+"/dy exch def\n"
+"/dx exch def\n"
+"/y exch def\n"
+"/x exch def\n"
+"newpath\n"
+"x y moveto\n"
+"dx 0 rlineto\n"
+"0 dy rlineto\n"
+"dx neg 0 rlineto\n"
+"closepath\n"
+"clip\n"
+"} bind def\n"
+
+"/FR { /dy exch def\n"
+"/dx exch def\n"
+"/y exch def\n"
+"/x exch def\n"
+"currentlinewidth 0 setlinewidth newpath\n"
+"x y moveto\n"
+"dx 0 rlineto\n"
+"0 dy rlineto\n"
+"dx neg 0 rlineto\n"
+"closepath fill setlinewidth\n"
+"} bind def\n"
+
+"/GS { gsave } bind def\n"
+"/GR { grestore } bind def\n"
+
+"/SP { showpage } bind def\n"
+"/LW { setlinewidth } bind def\n"
+"/CF /Courier def\n"
+"/SF { /CF exch def } bind def\n"
+"/fsize 12 def\n"
+"/FS { /fsize exch def fsize CF findfont exch scalefont setfont }def \n"
+
+
+"/GL { setgray } bind def\n"
+"/SRGB { setrgbcolor } bind def\n"
+
+// color images
+
+"/CI { GS /py exch def /px exch def /sy exch def /sx exch def\n"
+"translate \n"
+"sx sy scale px py 8 \n"
+"[ px 0 0 py neg 0 py ]\n"
+"currentfile /ASCIIHexDecode filter\n false 3"
+" colorimage GR\n"
+"} bind def\n"
+
+// gray images
+
+"/GI { GS /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale px py 8 \n"
+
+
+"[ px 0 0 py neg 0 py ]\n"
+"currentfile /ASCIIHexDecode filter\n"
+"image GR\n"
+"} bind def\n"
+
+// single-color bitmask
+
+"/MI { GS /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale px py false \n"
+"[ px 0 0 py neg 0 py ]\n"
+"currentfile /ASCIIHexDecode filter\n"
+"imagemask GR\n"
+"} bind def\n"
+
+
+// path
+
+"/BFP { newpath moveto } def\n"
+"/BP { newpath } bind def \n"
+"/PL { lineto } bind def \n"
+"/PM { moveto } bind def \n"
+"/MT { moveto } bind def \n"
+"/LT { lineto } bind def \n"
+"/EFP { closepath fill } bind def\n" //was:stroke
+"/ELP { stroke } bind def\n"
+"/ECP { closepath stroke } bind def\n" // Closed (loop)
+"/LW { setlinewidth } bind def\n"
+
+// ////////////////////////// misc ////////////////
+"/TR { translate } bind def\n"
+"/CT { concat } bind def\n"
+"/RCT { matrix invertmatrix concat} bind def\n"
+"/SC { scale } bind def\n"
+//"/GPD { currentpagedevice /PageSize get} def\n"
+
+// show at position with desired width
+// usage:
+// width (string) x y show_pos_width
+"/show_pos_width {GS moveto dup dup stringwidth pop exch length exch 3 index exch sub exch "
+"div 0 2 index 1 -1 scale ashow pop pop GR} bind def\n" // spacing altered to match desired width
+//"/show_pos_width {GS moveto dup stringwidth pop 3 2 roll exch div -1 matrix scale concat "
+//"show GR } bind def\n" // horizontally scaled text to match desired width
+
+;
+
+
+static const char * prolog_2 = // prolog relevant only if lang_level >1
+
+// color image dictionaries
+"/CII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale\n"
+"/DeviceRGB setcolorspace\n"
+"/IDD 8 dict def\n"
+"IDD begin\n"
+"/ImageType 1 def\n"
+"/Width px def\n"
+"/Height py def\n"
+"/BitsPerComponent 8 def\n"
+"/Interpolate inter def\n"
+"/DataSource currentfile /ASCIIHexDecode filter def\n"
+"/MultipleDataSources false def\n"
+"/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
+"/Decode [ 0 1 0 1 0 1 ] def\n"
+"end\n"
+"IDD image GR} bind def\n"
+
+// gray image dict
+
+
+"/GII {GS /inter exch def /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale\n"
+"/DeviceGray setcolorspace\n"
+"/IDD 8 dict def\n"
+"IDD begin\n"
+"/ImageType 1 def\n"
+"/Width px def\n"
+"/Height py def\n"
+"/BitsPerComponent 8 def\n"
+
+"/Interpolate inter def\n"
+"/DataSource currentfile /ASCIIHexDecode filter def\n"
+"/MultipleDataSources false def\n"
+"/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
+"/Decode [ 0 1 ] def\n"
+"end\n"
+"IDD image GR} bind def\n"
+
+;
+
+static const char * prolog_2_pixmap = // prolog relevant only if lang_level == 2 for pixmaps
+"/pixmap_size { /pixmap_sy exch def /pixmap_sx exch def } bind def\n"
+
+"/pixmap_mat {[ pixmap_sx 0 0 pixmap_sy neg 0 pixmap_sy ]} bind def\n"
+
+"/pixmap_dict {"
+"<< /PatternType 1 "
+"/PaintType 1 "
+"/TilingType 2 "
+"/BBox [0 0 pixmap_sx pixmap_sy] "
+"/XStep pixmap_sx "
+"/YStep pixmap_sy\n"
+"/PaintProc "
+"{ begin "
+"pixmap_sx pixmap_sy scale "
+"pixmap_sx pixmap_sy 8 "
+"pixmap_mat "
+"pixmap_data "
+"false 3 "
+"colorimage "
+"end "
+"} bind "
+">>\n"
+"} bind def\n"
+
+"/pixmap_plot {"
+"GS "
+"/pixmap_y exch def /pixmap_x exch def\n"
+"pixmap_x pixmap_y translate\n"
+"pixmap_dict matrix makepattern setpattern\n"
+"pixmap_sx pixmap_sy scale\n"
+"pixmap_sx pixmap_sy\n"
+"true\n"
+"pixmap_mat\n"
+"pixmap_mask\n"
+"imagemask\n"
+"GR\n"
+"} bind def\n"
+
+"/pixmap_loaddata { /pixmap_data currentfile pixmap_sx pixmap_sy 3 mul mul string readhexstring "
+"} bind def\n"
+
+"/pixmap_loadmask { "
+"/pixmap_mask currentfile pixmap_sx 8 div ceiling cvi pixmap_sy mul string readhexstring "
+"} bind def\n"
+;
+
+
+
+static const char * prolog_3 = // prolog relevant only if lang_level >2
+
+// masked color images
+"/CIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale\n"
+"/DeviceRGB setcolorspace\n"
+
+"/IDD 8 dict def\n"
+
+"IDD begin\n"
+"/ImageType 1 def\n"
+"/Width px def\n"
+"/Height py def\n"
+"/BitsPerComponent 8 def\n"
+"/Interpolate inter def\n"
+"/DataSource currentfile /ASCIIHexDecode filter def\n"
+"/MultipleDataSources false def\n"
+"/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
+
+"/Decode [ 0 1 0 1 0 1 ] def\n"
+"end\n"
+
+"/IMD 8 dict def\n"
+"IMD begin\n"
+"/ImageType 1 def\n"
+"/Width mx def\n"
+"/Height my def\n"
+"/BitsPerComponent 1 def\n"
+// "/Interpolate inter def\n"
+"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n"
+"/Decode [ 1 0 ] def\n"
+"end\n"
+
+"<<\n"
+"/ImageType 3\n"
+"/InterleaveType 2\n"
+"/MaskDict IMD\n"
+"/DataDict IDD\n"
+">> image GR\n"
+"} bind def\n"
+
+
+// masked gray images
+"/GIM {GS /inter exch def /my exch def /mx exch def /py exch def /px exch def /sy exch def /sx exch def \n"
+"translate \n"
+"sx sy scale\n"
+"/DeviceGray setcolorspace\n"
+
+"/IDD 8 dict def\n"
+
+"IDD begin\n"
+"/ImageType 1 def\n"
+"/Width px def\n"
+"/Height py def\n"
+"/BitsPerComponent 8 def\n"
+"/Interpolate inter def\n"
+"/DataSource currentfile /ASCIIHexDecode filter def\n"
+"/MultipleDataSources false def\n"
+"/ImageMatrix [ px 0 0 py neg 0 py ] def\n"
+
+"/Decode [ 0 1 ] def\n"
+"end\n"
+
+"/IMD 8 dict def\n"
+
+"IMD begin\n"
+"/ImageType 1 def\n"
+"/Width mx def\n"
+"/Height my def\n"
+"/BitsPerComponent 1 def\n"
+"/ImageMatrix [ mx 0 0 my neg 0 my ] def\n"
+"/Decode [ 1 0 ] def\n"
+"end\n"
+
+"<<\n"
+"/ImageType 3\n"
+"/InterleaveType 2\n"
+"/MaskDict IMD\n"
+"/DataDict IDD\n"
+">> image GR\n"
+"} bind def\n"
+
+
+"\n"
+;
+
+// end prolog
+
+int Fl_PostScript_Graphics_Driver::start_postscript (int pagecount, enum Fl_PostScript_Graphics_Driver::Page_Format format, enum Fl_PostScript_Graphics_Driver::Page_Layout layout)
+//returns 0 iff OK
+{
+ int w, h, x;
+ if (format == A4) {
+ left_margin = 18;
+ top_margin = 18;
+ }
+ else {
+ left_margin = 12;
+ top_margin = 12;
+ }
+ page_format_ = (enum Page_Format)(format | layout);
+
+ fputs("%!PS-Adobe-3.0\n", output);
+ fputs("%%Creator: FLTK\n", output);
+ if (lang_level_>1)
+ fprintf(output, "%%%%LanguageLevel: %i\n" , lang_level_);
+ if ((pages_ = pagecount))
+ fprintf(output, "%%%%Pages: %i\n", pagecount);
+ else
+ fputs("%%Pages: (atend)\n", output);
+ fprintf(output, "%%%%BeginFeature: *PageSize %s\n", page_formats[format].name );
+ w = page_formats[format].width;
+ h = page_formats[format].height;
+ if (lang_level_ == 3 && (layout & LANDSCAPE) ) { x = w; w = h; h = x; }
+ fprintf(output, "<</PageSize[%d %d]>>setpagedevice\n", w, h );
+ fputs("%%EndFeature\n", output);
+ fputs("%%EndComments\n", output);
+ fputs(prolog, output);
+ if (lang_level_ > 1) {
+ fputs(prolog_2, output);
+ }
+ if (lang_level_ == 2) {
+ fputs(prolog_2_pixmap, output);
+ }
+ if (lang_level_ > 2)
+ fputs(prolog_3, output);
+ if (lang_level_ >= 3) {
+ fputs("/CS { clipsave } bind def\n", output);
+ fputs("/CR { cliprestore } bind def\n", output);
+ } else {
+ fputs("/CS { GS } bind def\n", output);
+ fputs("/CR { GR } bind def\n", output);
+ }
+ page_policy_ = 1;
+
+
+ fputs("%%EndProlog\n",output);
+ if (lang_level_ >= 2)
+ fprintf(output,"<< /Policies << /Pagesize 1 >> >> setpagedevice\n");
+
+ reset();
+ nPages=0;
+ return 0;
+}
+
+void Fl_PostScript_Graphics_Driver::recover(){
+ color(cr_,cg_,cb_);
+ line_style(linestyle_,linewidth_,linedash_);
+ font(font_,size_);
+}
+
+void Fl_PostScript_Graphics_Driver::reset(){
+ gap_=1;
+ clip_=0;
+ cr_=cg_=cb_=0;
+ font_=FL_HELVETICA;
+ size_=12;
+ linewidth_=0;
+ linestyle_=FL_SOLID;
+ strcpy(linedash_,"");
+ Clip *c=clip_; ////just not to have memory leaks for badly writen code (forgotten clip popping)
+
+ while(c){
+ clip_=clip_->prev;
+ delete c;
+ c=clip_;
+ }
+
+}
+
+void Fl_PostScript_Graphics_Driver::page_policy(int p){
+ page_policy_ = p;
+ if(lang_level_>=2)
+ fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p);
+}
+
+// //////////////////// paging //////////////////////////////////////////
+
+
+
+void Fl_PostScript_Graphics_Driver::page(double pw, double ph, int media) {
+
+ if (nPages){
+ fprintf(output, "CR\nGR\nGR\nGR\nSP\nrestore\n");
+ }
+ ++nPages;
+ fprintf(output, "%%%%Page: %i %i\n" , nPages , nPages);
+ if (pw>ph){
+ fprintf(output, "%%%%PageOrientation: Landscape\n");
+ }else{
+ fprintf(output, "%%%%PageOrientation: Portrait\n");
+ }
+
+ fprintf(output, "%%%%BeginPageSetup\n");
+ if((media & MEDIA) &&(lang_level_>1)){
+ int r = media & REVERSED;
+ if(r) r = 2;
+ fprintf(output, "<< /PageSize [%i %i] /Orientation %i>> setpagedevice\n", (int)(pw+.5), (int)(ph+.5), r);
+ }
+ fprintf(output, "%%%%EndPageSetup\n");
+
+ pw_ = pw;
+ ph_ = ph;
+ reset();
+
+ fprintf(output, "save\n");
+ fprintf(output, "GS\n");
+ fprintf(output, "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/);
+ fprintf(output, "1 -1 SC\n");
+ line_style(0);
+ fprintf(output, "GS\n");
+
+ if (!((media & MEDIA) &&(lang_level_>1))){
+ if (pw > ph) {
+ if(media & REVERSED) {
+ fprintf(output, "-90 rotate %i 0 translate\n", int(-pw));
+ }
+ else {
+ fprintf(output, "90 rotate -%i -%i translate\n", (lang_level_ == 2 ? int(pw - ph) : 0), int(ph));
+ }
+ }
+ else {
+ if(media & REVERSED)
+ fprintf(output, "180 rotate %i %i translate\n", int(-pw), int(-ph));
+ }
+ }
+ fprintf(output, "GS\nCS\n");
+};
+
+void Fl_PostScript_Graphics_Driver::page(int format){
+
+
+ if(format & LANDSCAPE){
+ ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width;
+ pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height;
+ }else{
+ pw_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].width;
+ ph_=Fl_PostScript_Graphics_Driver::page_formats[format & 0xFF].height;
+ }
+ page(pw_,ph_,format & 0xFF00);//,orientation only;
+};
+
+void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) {
+ // Commented code does not work, i can't find the bug ;-(
+ // fprintf(output, "GS\n");
+ // fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h);
+ // fprintf(output, "GR\n");
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y);
+ fprintf(output, "%i %i LT\n", x+w-1 , y);
+ fprintf(output, "%i %i LT\n", x+w-1 , y+h-1);
+ fprintf(output, "%i %i LT\n", x , y+h-1);
+ fprintf(output, "ECP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) {
+ fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h);
+}
+
+void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) {
+ fprintf(output, "GS\n");
+ fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2);
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::line(int x0, int y0, int x1, int y1, int x2, int y2) {
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x0 , y0);
+ fprintf(output, "%i %i LT\n", x1 , y1);
+ fprintf(output, "%i %i LT\n", x2 , y2);
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3){
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y );
+ fprintf(output, "%i %i LT\n", x1 , y );
+ fprintf(output, "%i %i LT\n", x1 , y2);
+ fprintf(output,"%i %i LT\n", x3 , y2);
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+};
+
+
+void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1, int y2){
+
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y);
+ fprintf(output,"%i %i LT\n", x1 , y);
+ fprintf(output, "%i %i LT\n", x1 , y2 );
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+};
+
+void Fl_PostScript_Graphics_Driver::xyline(int x, int y, int x1){
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y);
+ fprintf(output, "%i %i LT\n", x1 , y );
+ fprintf(output, "ELP\n");
+
+ fprintf(output, "GR\n");
+};
+
+void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3){
+ fprintf(output, "GS\n");
+
+ fprintf(output,"BP\n");
+ fprintf(output,"%i %i MT\n", x , y);
+ fprintf(output, "%i %i LT\n", x , y1 );
+ fprintf(output, "%i %i LT\n", x2 , y1 );
+ fprintf(output , "%i %i LT\n", x2 , y3);
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+};
+
+void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1, int x2){
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y);
+ fprintf(output, "%i %i LT\n", x , y1);
+ fprintf(output, "%i %i LT\n", x2 , y1);
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+};
+
+void Fl_PostScript_Graphics_Driver::yxline(int x, int y, int y1){
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x , y);
+ fprintf(output, "%i %i LT\n", x , y1);
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+};
+
+void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x0 , y0);
+ fprintf(output, "%i %i LT\n", x1 , y1);
+ fprintf(output, "%i %i LT\n", x2 , y2);
+ fprintf(output, "ECP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x0 , y0);
+ fprintf(output, "%i %i LT\n", x1 , y1);
+ fprintf(output, "%i %i LT\n", x2 , y2);
+ fprintf(output, "%i %i LT\n", x3 , y3);
+ fprintf(output, "ECP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x0 , y0);
+ fprintf(output,"%i %i LT\n", x1 , y1);
+ fprintf(output, "%i %i LT\n", x2 , y2);
+ fprintf(output, "EFP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ fprintf(output, "GS\n");
+ fprintf(output,"BP\n");
+ fprintf(output, "%i %i MT\n", x0 , y0 );
+ fprintf(output, "%i %i LT\n", x1 , y1 );
+ fprintf(output, "%i %i LT\n", x2 , y2 );
+ fprintf(output, "%i %i LT\n", x3 , y3 );
+
+ fprintf(output, "EFP\n");
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::point(int x, int y){
+ rectf(x,y,1,1);
+}
+
+static int dashes_flat[5][7]={
+{-1,0,0,0,0,0,0},
+{3,1,-1,0,0,0,0},
+{1,1,-1,0,0,0,0},
+{3,1,1,1,-1,0,0},
+{3,1,1,1,1,1,-1}
+};
+
+
+//yeah, hack...
+static double dashes_cap[5][7]={
+{-1,0,0,0,0,0,0},
+{2,2,-1,0,0,0,0},
+{0.01,1.99,-1,0,0,0,0},
+{2,2,0.01,1.99,-1,0,0},
+{2,2,0.01,1.99,0.01,1.99,-1}
+};
+
+
+void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashes){
+ //line_styled_=1;
+
+ linewidth_=width;
+ linestyle_=style;
+ //dashes_= dashes;
+ if(dashes){
+ if(dashes != linedash_)
+ strcpy(linedash_,dashes);
+
+ }else
+ linedash_[0]=0;
+ char width0 = 0;
+ if(!width){
+ width=1; //for screen drawing compatability
+ width0=1;
+ }
+
+ fprintf(output, "%i setlinewidth\n", width);
+
+ if(!style && (!dashes || !(*dashes)) && width0) //system lines
+ style = FL_CAP_SQUARE;
+
+ int cap = (style &0xf00) >> 8;
+ if(cap) cap--;
+ fprintf(output,"%i setlinecap\n", cap);
+
+ int join = (style & 0xf000) >> 12;
+
+ if(join) join--;
+ fprintf(output,"%i setlinejoin\n", join);
+
+
+ fprintf(output, "[");
+ if(dashes && *dashes){
+ while(*dashes){
+ fprintf(output, "%i ", *dashes);
+ dashes++;
+ }
+ }else{
+ int * ds;
+ if(style & 0x200){ // round and square caps, dash length need to be adjusted
+ double *dt = dashes_cap[style & 0xff];
+ while (*dt >= 0){
+ fprintf(output, "%g ",width * (*dt));
+ dt++;
+ }
+ }else{
+
+ ds = dashes_flat[style & 0xff];
+ while (*ds >= 0){
+ fprintf(output, "%i ",width * (*ds));
+ ds++;
+ }
+ }
+ }
+ fprintf(output, "] 0 setdash\n");
+};
+
+static const char *_fontNames[] = {
+"Helvetica",
+"Helvetica-Bold",
+"Helvetica-Oblique",
+"Helvetica-BoldOblique",
+"Courier",
+"Courier-Bold",
+"Courier-Oblique",
+"Courier-BoldOblique",
+"Times",
+"Times-Bold",
+"Times-Italic",
+"Times-BoldItalic",
+"Symbol",
+"Courier",
+"Courier-Bold",
+"ZapfDingbats"
+};
+
+void Fl_PostScript_Graphics_Driver::font(int f, int s) {
+ if (f >= FL_FREE_FONT)
+ f = FL_COURIER;
+ fprintf(output, "/%s SF\n" , _fontNames[f]);
+ fprintf(output,"%i FS\n", s);
+ Fl_Display_Device::display_device()->driver()->font(f,s); // Use display fonts for font measurement
+ font_ = f; size_ = s;
+};
+
+void Fl_PostScript_Graphics_Driver::color(Fl_Color c) {
+ //colored_=1;
+ color_=c;
+ Fl::get_color(c, cr_, cg_, cb_);
+ if (cr_==cg_ && cg_==cb_) {
+ double gray = cr_/255.0;
+ fprintf(output, "%g GL\n", gray);
+
+ } else {
+ double fr, fg, fb;
+ fr = cr_/255.0;
+ fg = cg_/255.0;
+ fb = cb_/255.0;
+ fprintf(output,"%g %g %g SRGB\n", fr , fg , fb);
+ }
+}
+
+void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsigned char b) {
+ //colored_=1;
+ cr_=r;cg_=g;cb_=b;
+ if (r==g && g==b) {
+ double gray = r/255.0;
+ fprintf(output, "%g GL\n", gray);
+ } else {
+ double fr, fg, fb;
+ fr = r/255.0;
+ fg = g/255.0;
+ fb = b/255.0;
+ fprintf(output, "%g %g %g SRGB\n", fr , fg , fb);
+ }
+}
+
+void Fl_PostScript_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y)
+{
+ fprintf(output, "GS %d %d translate %d rotate\n", x, y, - angle);
+ this->transformed_draw(str, n, 0, 0);
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y){
+ if (!n || !str || !*str)return;
+ fprintf(output,"%g (", fl_width(str, n));
+ int i=1;
+ for (int j=0;j<n;j++){
+ if (i>240){
+ fprintf(output, "\\\n");
+ i=0;
+ }
+ i++;
+ switch (*str) {
+ case '(': case ')': case '\\' :
+ putc('\\' , output);
+ /* fallthrough */
+ default:
+ putc(*str , output);
+ }
+ str++;
+ }
+ fprintf(output, ") %g %g show_pos_width\n", x, y);
+}
+
+struct matrix {double a, b, c, d, x, y;};
+extern matrix * fl_matrix;
+
+void Fl_PostScript_Graphics_Driver::concat(){
+ fprintf(output,"[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
+}
+
+void Fl_PostScript_Graphics_Driver::reconcat(){
+ fprintf(output, "[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
+}
+
+///////////////// transformed (double) drawings ////////////////////////////////
+
+
+void Fl_PostScript_Graphics_Driver::begin_points(){
+ fprintf(output, "GS\n");
+ concat();
+
+ fprintf(output, "BP\n");
+ gap_=1;
+ shape_=POINTS;
+};
+
+void Fl_PostScript_Graphics_Driver::begin_line(){
+ fprintf(output, "GS\n");
+ concat();
+ fprintf(output, "BP\n");
+ gap_=1;
+ shape_=LINE;
+};
+
+void Fl_PostScript_Graphics_Driver::begin_loop(){
+ fprintf(output, "GS\n");
+ concat();
+ fprintf(output, "BP\n");
+ gap_=1;
+ shape_=LOOP;
+};
+
+void Fl_PostScript_Graphics_Driver::begin_polygon(){
+ fprintf(output, "GS\n");
+ concat();
+ fprintf(output, "BP\n");
+ gap_=1;
+ shape_=POLYGON;
+};
+
+void Fl_PostScript_Graphics_Driver::vertex(double x, double y){
+ if(shape_==POINTS){
+ fprintf(output,"%g %g MT\n", x , y);
+ gap_=1;
+ return;
+ }
+ if(gap_){
+ fprintf(output,"%g %g MT\n", x , y);
+ gap_=0;
+ }else
+ fprintf(output, "%g %g LT\n", x , y);
+};
+
+void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){
+ if(shape_==NONE) return;
+ if(gap_)
+ fprintf(output,"%g %g MT\n", x , y);
+ else
+ fprintf(output, "%g %g LT\n", x , y);
+ gap_=0;
+
+ fprintf(output, "%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3);
+};
+
+
+void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){
+ if(shape_==NONE){
+ fprintf(output, "GS\n");
+ concat();
+ // fprintf(output, "BP\n");
+ fprintf(output,"%g %g %g 0 360 arc\n", x , y , r);
+ reconcat();
+ // fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+ }else
+
+ fprintf(output, "%g %g %g 0 360 arc\n", x , y , r);
+
+};
+
+void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double start, double a){
+ if(shape_==NONE) return;
+ gap_=0;
+ if(start>a)
+ fprintf(output, "%g %g %g %g %g arc\n", x , y , r , -start, -a);
+ else
+ fprintf(output, "%g %g %g %g %g arcn\n", x , y , r , -start, -a);
+
+};
+
+void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) {
+ fprintf(output, "GS\n");
+ //fprintf(output, "BP\n");
+ begin_line();
+ fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
+ fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
+ arc(0,0,1,a2,a1);
+ // fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2);
+ fprintf(output, "%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) );
+ fprintf(output, "%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
+ end_line();
+
+ // fprintf(output, "%g setlinewidth\n", 2/sqrt(w*h));
+ // fprintf(output, "ELP\n");
+ // fprintf(output, 2.0/w , 2.0/w , " SC\n";
+ // fprintf(output, (-x - w/2.0) , (-y - h/2) , " TR\n";
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) {
+
+ fprintf(output, "GS\n");
+ fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
+ fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
+ begin_polygon();
+ vertex(0,0);
+ arc(0.0,0.0, 1, a2, a1);
+ end_polygon();
+ fprintf(output, "GR\n");
+}
+
+void Fl_PostScript_Graphics_Driver::end_points(){
+ gap_=1;
+ reconcat();
+ fprintf(output, "ELP\n"); //??
+ fprintf(output, "GR\n");
+ shape_=NONE;
+}
+
+void Fl_PostScript_Graphics_Driver::end_line(){
+ gap_=1;
+ reconcat();
+ fprintf(output, "ELP\n");
+ fprintf(output, "GR\n");
+ shape_=NONE;
+}
+void Fl_PostScript_Graphics_Driver::end_loop(){
+ gap_=1;
+ reconcat();
+ fprintf(output, "ECP\n");
+ fprintf(output, "GR\n");
+ shape_=NONE;
+}
+
+void Fl_PostScript_Graphics_Driver::end_polygon(){
+
+ gap_=1;
+ reconcat();
+ fprintf(output, "EFP\n");
+ fprintf(output, "GR\n");
+ shape_=NONE;
+}
+
+void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y){
+ reconcat();
+ if(gap_){
+ fprintf(output, "%g %g MT\n", x , y);
+ gap_=0;
+ }else
+ fprintf(output, "%g %g LT\n", x , y);
+ concat();
+};
+
+///////////////////////////// Clipping /////////////////////////////////////////////
+
+void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) {
+ Clip * c=new Clip();
+ clip_box(x,y,w,h,c->x,c->y,c->w,c->h);
+ c->prev=clip_;
+ clip_=c;
+ fprintf(output, "CR\nCS\n");
+ if(lang_level_<3)
+ recover();
+ fprintf(output, "%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h);
+
+}
+
+void Fl_PostScript_Graphics_Driver::push_no_clip() {
+ Clip * c = new Clip();
+ c->prev=clip_;
+ clip_=c;
+ clip_->x = clip_->y = clip_->w = clip_->h = -1;
+ fprintf(output, "CR\nCS\n");
+ if(lang_level_<3)
+ recover();
+}
+
+void Fl_PostScript_Graphics_Driver::pop_clip() {
+ if(!clip_)return;
+ Clip * c=clip_;
+ clip_=clip_->prev;
+ delete c;
+ fprintf(output, "CR\nCS\n");
+ if(clip_ && clip_->w >0)
+ fprintf(output, "%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h);
+ // uh, -0.5 is to match screen clipping, for floats there should be something beter
+ if(lang_level_<3)
+ recover();
+}
+
+int Fl_PostScript_Graphics_Driver::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){
+ if(!clip_){
+ X=x;Y=y;W=w;H=h;
+ return 1;
+ }
+ if(clip_->w < 0){
+ X=x;Y=y;W=w;H=h;
+ return 1;
+ }
+ int ret=0;
+ if (x > (X=clip_->x)) {X=x; ret=1;}
+ if (y > (Y=clip_->y)) {Y=y; ret=1;}
+ if ((x+w) < (clip_->x+clip_->w)) {
+ W=x+w-X;
+
+ ret=1;
+
+ }else
+ W = clip_->x + clip_->w - X;
+ if(W<0){
+ W=0;
+ return 1;
+ }
+ if ((y+h) < (clip_->y+clip_->h)) {
+ H=y+h-Y;
+ ret=1;
+ }else
+ H = clip_->y + clip_->h - Y;
+ if(H<0){
+ W=0;
+ H=0;
+ return 1;
+ }
+ return ret;
+};
+
+int Fl_PostScript_Graphics_Driver::not_clipped(int x, int y, int w, int h){
+ if(!clip_) return 1;
+ if(clip_->w < 0) return 1;
+ int X, Y, W, H;
+ clip_box(x, y, w, h, X, Y, W, H);
+ if(W) return 1;
+ return 0;
+};
+
+
+void Fl_PostScript_File_Device::margins(int *left, int *top, int *right, int *bottom) // to implement
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ if(left) *left = (int)(ps->left_margin / ps->scale_x + .5);
+ if(right) *right = (int)(ps->left_margin / ps->scale_x + .5);
+ if(top) *top = (int)(ps->top_margin / ps->scale_y + .5);
+ if(bottom) *bottom = (int)(ps->top_margin / ps->scale_y + .5);
+}
+
+int Fl_PostScript_File_Device::printable_rect(int *w, int *h)
+//returns 0 iff OK
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ if(w) *w = (int)((ps->pw_ - 2 * ps->left_margin) / ps->scale_x + .5);
+ if(h) *h = (int)((ps->ph_ - 2 * ps->top_margin) / ps->scale_y + .5);
+ return 0;
+}
+
+void Fl_PostScript_File_Device::origin(int x, int y)
+{
+ x_offset = x;
+ y_offset = y;
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
+ ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x, y, ps->angle);
+}
+
+void Fl_PostScript_File_Device::scale (float s_x, float s_y)
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ ps->scale_x = s_x;
+ ps->scale_y = s_y;
+ fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %f rotate GS\n",
+ ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, ps->angle);
+}
+
+void Fl_PostScript_File_Device::rotate (float rot_angle)
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ ps->angle = - rot_angle;
+ fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
+ ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x_offset, y_offset, ps->angle);
+}
+
+void Fl_PostScript_File_Device::translate(int x, int y)
+{
+ fprintf(driver()->output, "GS %d %d translate GS\n", x, y);
+}
+
+void Fl_PostScript_File_Device::untranslate(void)
+{
+ fprintf(driver()->output, "GR GR\n");
+}
+
+int Fl_PostScript_File_Device::start_page (void)
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ ps->page(ps->page_format_);
+ x_offset = 0;
+ y_offset = 0;
+ ps->scale_x = ps->scale_y = 1.;
+ ps->angle = 0;
+ fprintf(ps->output, "GR GR GS %d %d translate GS\n", ps->left_margin, ps->top_margin);
+ return 0;
+}
+
+int Fl_PostScript_File_Device::end_page (void)
+{
+ return 0;
+}
+
+void Fl_PostScript_File_Device::end_job (void)
+// finishes PostScript & closes file
+{
+ Fl_PostScript_Graphics_Driver *ps = driver();
+ if (ps->nPages) { // for eps nPages is 0 so it is fine ....
+ fprintf(ps->output, "CR\nGR\nGR\nGR\nSP\n restore\n");
+ if (!ps->pages_){
+ fprintf(ps->output, "%%%%Trailer\n");
+ fprintf(ps->output, "%%%%Pages: %i\n" , ps->nPages);
+ };
+ } else
+ fprintf(ps->output, "GR\n restore\n");
+ fputs("%%EOF",ps->output);
+ ps->reset();
+ fflush(ps->output);
+ if(ferror(ps->output)) {
+ fl_alert ("Error during PostScript data output.");
+ }
+#if ! (defined(__APPLE__) || defined(WIN32) )
+ if (print_pipe)
+ pclose(ps->output);
+ else
+ fclose(ps->output);
+#else
+ fclose(ps->output);
+#endif
+ while (ps->clip_){
+ Fl_PostScript_Graphics_Driver::Clip * c= ps->clip_;
+ ps->clip_= ps->clip_->prev;
+ delete c;
+ }
+ if (ps->close_cmd_) (*ps->close_cmd_)(ps->output);
+ Fl_Display_Device::display_device()->set_current();
+}
+
+#if ! (defined(__APPLE__) || defined(WIN32) )
+int Fl_Printer::start_job(int pages, int *firstpage, int *lastpage) {
+ enum Fl_PostScript_Graphics_Driver::Page_Format format;
+ enum Fl_PostScript_Graphics_Driver::Page_Layout layout;
+
+ // first test version for print dialog
+ if (!print_panel) make_print_panel();
+ 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
+
+ format = print_page_size->value() ? Fl_PostScript_Graphics_Driver::A4 : Fl_PostScript_Graphics_Driver::LETTER;
+ { // 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;
+ pages = to - from + 1;
+ }
+
+ if (print_output_mode[0]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT;
+ else if (print_output_mode[1]->value()) layout = Fl_PostScript_Graphics_Driver::LANDSCAPE;
+ else if (print_output_mode[2]->value()) layout = Fl_PostScript_Graphics_Driver::PORTRAIT;
+ else layout = Fl_PostScript_Graphics_Driver::LANDSCAPE;
+
+ 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 = "<File>";
+
+ 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];
+ 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);
+
+ 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;
+ }
+ this->set_current();
+ return ps->start_postscript(pages, format, layout); // start printing
+}
+
+#endif // ! (defined(__APPLE__) || defined(WIN32) )
+
+#endif // FL_DOXYGEN
+
+//
+// End of "$Id: Fl_PS_Printer.cxx 7520 2010-04-16 20:19:09Z manolo $".
+//
diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx
index d6e8425b3..7214ea1b7 100644
--- a/src/Fl_Printer.cxx
+++ b/src/Fl_Printer.cxx
@@ -34,30 +34,60 @@
#include <src/Fl_GDI_Printer.cxx>
#endif
-#include <src/Fl_PS_Printer.cxx>
+#include <src/Fl_PostScript.cxx>
// print dialog customization strings
-
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_title = "Print";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_printer = "Printer:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_range = "Print Range";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_copies = "Copies";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_all = "All";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_pages = "Pages";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_from = "From:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_to = "To:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_properties = "Properties...";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_copyNo = "# Copies:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_print_button = "Print";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_cancel_button = "Cancel";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_print_to_file = "Print To File";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_title = "Printer Properties";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_pagesize = "Page Size:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_mode = "Output Mode:";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_use = "Use";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_save = "Save";
+/** [this text may be customized at run-time] */
const char *Fl_Printer::property_cancel = "Cancel";
+const char *Fl_Printer::device_type = "Fl_Printer";
+
+void Fl_Printer::set_current()
+{
+#ifdef __APPLE__
+ fl_gc = (CGContextRef)gc;
+#elif defined(WIN32)
+ fl_gc = (HDC)gc;
+#endif
+ this->Fl_Surface_Device::set_current();
+}
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm
index 874686d3a..4bd15be58 100644
--- a/src/Fl_Quartz_Printer.mm
+++ b/src/Fl_Quartz_Printer.mm
@@ -35,15 +35,16 @@
extern void fl_quartz_restore_line_style_();
-Fl_Printer::Fl_Printer(void)
+Fl_System_Printer::Fl_System_Printer(void)
{
x_offset = 0;
y_offset = 0;
scale_x = scale_y = 1.;
- type_ = quartz_printer;
+ type_ = device_type;
+ driver(fl_device);
}
-Fl_Printer::~Fl_Printer(void) {}
+Fl_System_Printer::~Fl_System_Printer(void) {}
int Fl_Printer::start_job (int pagecount, int *frompage, int *topage)
//printing using a Quartz graphics context
@@ -288,7 +289,7 @@ void Fl_Printer::end_job (void)
fl_alert ("PM Session error %d", (int)status);
}
PMSessionEndDocumentNoDialog(printSession);
- Fl_Device::display_device()->set_current();
+ Fl_Display_Device::display_device()->set_current();
fl_gc = 0;
Fl::first_window()->show();
}
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index bb7e1e19e..0b09774aa 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -117,9 +117,11 @@ static void createAppleMenu(void);
static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h);
static void cocoaMouseHandler(NSEvent *theEvent);
-static Fl_Quartz_Display fl_quartz_device;
-FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_quartz_device; // does not change
-FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_quartz_device; // the current target device of graphics operations
+static Fl_Quartz_Graphics_Driver fl_quartz_driver;
+static Fl_Display_Device fl_quartz_display(&fl_quartz_driver);
+FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_quartz_display; // does not change
+FL_EXPORT Fl_Graphics_Driver *fl_device = (Fl_Graphics_Driver*)&fl_quartz_driver; // the current target device of graphics operations
+FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations
// public variables
int fl_screen;
@@ -2963,7 +2965,7 @@ int MACscreen_init(XRectangle screens[])
- (void)printPanel
{
Fl_Printer printer;
- //Fl_PSfile_Device printer;
+ //Fl_PostScript_File_Device printer;
int w, h;
Fl_Window *win = Fl::first_window();
if(!win) return;
@@ -3466,7 +3468,7 @@ WindowRef MACwindowRef(Fl_Window *w)
// so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes
CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h) {
- if (Fl_Device::current()->type() == Fl_Device::quartz_printer) return CGRectMake(x, y, w-1.5 , h-1.5 );
+ if ( Fl_Surface_Device::surface()->type() == Fl_Printer::device_type ) return CGRectMake(x, y, w-1.5 , h-1.5 );
return CGRectMake(x, y, w > 0 ? w - 0.9 : 0, h > 0 ? h - 0.9 : 0);
}
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index f26d639db..3ccfd3106 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -95,9 +95,11 @@
for async mode proper operation, not mentioning the side effects...
*/
-static Fl_GDI_Display fl_gdi_device;
-FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_gdi_device; // does not change
-FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_gdi_device; // the current target device of graphics operations
+static Fl_GDI_Graphics_Driver fl_gdi_driver;
+static Fl_Display_Device fl_gdi_display(&fl_gdi_driver);
+FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_gdi_display; // does not change
+FL_EXPORT Fl_Graphics_Driver *fl_device = (Fl_Graphics_Driver*)&fl_gdi_driver; // the current target driver of graphics operations
+FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations
// dynamic wsock dll handling api:
#if defined(__CYGWIN__) && !defined(SOCKET)
@@ -1925,7 +1927,7 @@ void fl_cleanup_dc_list(void) { // clean up the list
}
Fl_Region XRectangleRegion(int x, int y, int w, int h) {
- if (Fl_Device::current()->type() < 256) return CreateRectRgn(x,y,x+w,y+h);
+ if (Fl_Surface_Device::surface()->type() == Fl_Display_Device::device_type) return CreateRectRgn(x,y,x+w,y+h);
// because rotation may apply, the rectangle becomes a polygon in device coords
POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} };
LPtoDP(fl_gc, pt, 4);
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 1c81503f8..5b7f2c520 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -51,9 +51,11 @@
# include <X11/Xlocale.h>
# include <X11/Xlib.h>
-static Fl_Xlib_Display fl_xlib_device;
-FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_xlib_device; // does not change
-FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_xlib_device; // the current target device of graphics operations
+static Fl_Xlib_Graphics_Driver fl_xlib_driver;
+static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
+FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_xlib_display; // does not change
+FL_EXPORT Fl_Graphics_Driver *fl_device = (Fl_Graphics_Driver*)&fl_xlib_driver; // the current target device of graphics operations
+FL_EXPORT Fl_Surface_Device *fl_surface = (Fl_Surface_Device*)fl_display_device; // the current target surface of graphics operations
////////////////////////////////////////////////////////////////
// interface to poll/select call:
@@ -136,9 +138,7 @@ void Fl::add_fd(int n, void (*cb)(int, void*), void* v) {
void Fl::remove_fd(int n, int events) {
int i,j;
-# if !USE_POLL
maxfd = -1; // recalculate maxfd on the fly
-# endif
for (i=j=0; i<nfds; i++) {
# if USE_POLL
if (pollfds[i].fd == n) {
@@ -152,8 +152,8 @@ void Fl::remove_fd(int n, int events) {
if (!e) continue; // if no events left, delete this fd
fd[i].events = e;
}
- if (fd[i].fd > maxfd) maxfd = fd[i].fd;
# endif
+ if (fd[i].fd > maxfd) maxfd = fd[i].fd;
// move it down in the array if necessary:
if (j<i) {
fd[j] = fd[i];
@@ -1588,13 +1588,6 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
XFree(hints);
}
- // set the window type for menu and tooltip windows to avoid animations (compiz)
- if (win->menu_window() || win->tooltip_window()) {
- Atom net_wm_type = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False);
- Atom net_wm_type_kind = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_MENU", False);
- int ret = XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
- }
-
XMapWindow(fl_display, xp->xid);
if (showit) {
win->set_visible();
diff --git a/src/fl_arc.cxx b/src/fl_arc.cxx
index 0ee4269a4..0003319cc 100644
--- a/src/fl_arc.cxx
+++ b/src/fl_arc.cxx
@@ -43,7 +43,7 @@ static double _fl_hypot(double x, double y) {
return sqrt(x*x + y*y);
}
-void Fl_Device::arc(double x, double y, double r, double start, double end) {
+void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end) {
// draw start point accurately:
diff --git a/src/fl_arci.cxx b/src/fl_arci.cxx
index 41f70b542..cd9d8f3df 100644
--- a/src/fl_arci.cxx
+++ b/src/fl_arci.cxx
@@ -47,7 +47,7 @@
#endif
#include <config.h>
-void Fl_Device::arc(int x,int y,int w,int h,double a1,double a2) {
+void Fl_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) {
if (w <= 0 || h <= 0) return;
#if defined(USE_X11)
@@ -82,7 +82,7 @@ void Fl_Device::arc(int x,int y,int w,int h,double a1,double a2) {
#endif
}
-void Fl_Device::pie(int x,int y,int w,int h,double a1,double a2) {
+void Fl_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
if (w <= 0 || h <= 0) return;
#if defined(USE_X11)
diff --git a/src/fl_color.cxx b/src/fl_color.cxx
index 735757427..b4cee410b 100644
--- a/src/fl_color.cxx
+++ b/src/fl_color.cxx
@@ -127,7 +127,7 @@ Fl_XColor fl_xmap[1][256];
/** Current color for drawing operations */
Fl_Color fl_color_;
-void Fl_Device::color(Fl_Color i) {
+void Fl_Graphics_Driver::color(Fl_Color i) {
if (i & 0xffffff00) {
unsigned rgb = (unsigned)i;
fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
@@ -138,7 +138,7 @@ void Fl_Device::color(Fl_Color i) {
}
}
-void Fl_Device::color(uchar r,uchar g,uchar b) {
+void Fl_Graphics_Driver::color(uchar r,uchar g,uchar b) {
fl_color_ = fl_rgb_color(r, g, b);
if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid
XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b));
diff --git a/src/fl_color_mac.cxx b/src/fl_color_mac.cxx
index 6ad4133b0..fa10a2de1 100644
--- a/src/fl_color_mac.cxx
+++ b/src/fl_color_mac.cxx
@@ -49,7 +49,7 @@ Fl_XMap* fl_current_xmap;
Fl_Color fl_color_;
-void Fl_Device::color(Fl_Color i) {
+void Fl_Graphics_Driver::color(Fl_Color i) {
fl_color_ = i;
int index;
uchar r, g, b;
@@ -74,7 +74,7 @@ void Fl_Device::color(Fl_Color i) {
CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f);
}
-void Fl_Device::color(uchar r, uchar g, uchar b) {
+void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) {
fl_color_ = fl_rgb_color(r, g, b);
float fr = r/255.0f;
float fg = g/255.0f;
diff --git a/src/fl_color_win32.cxx b/src/fl_color_win32.cxx
index f9cd7cc5d..a5b2d6f16 100644
--- a/src/fl_color_win32.cxx
+++ b/src/fl_color_win32.cxx
@@ -94,7 +94,7 @@ static void set_xmap(Fl_XMap& xmap, COLORREF c) {
Fl_Color fl_color_;
-void Fl_Device::color(Fl_Color i) {
+void Fl_Graphics_Driver::color(Fl_Color i) {
if (i & 0xffffff00) {
unsigned rgb = (unsigned)i;
fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
@@ -118,7 +118,7 @@ void Fl_Device::color(Fl_Color i) {
}
}
-void Fl_Device::color(uchar r, uchar g, uchar b) {
+void Fl_Graphics_Driver::color(uchar r, uchar g, uchar b) {
static Fl_XMap xmap;
COLORREF c = RGB(r,g,b);
fl_color_ = fl_rgb_color(r, g, b);
diff --git a/src/fl_curve.cxx b/src/fl_curve.cxx
index d9406787e..efacbd677 100644
--- a/src/fl_curve.cxx
+++ b/src/fl_curve.cxx
@@ -38,7 +38,7 @@
#include <FL/fl_draw.H>
#include <math.h>
-void Fl_Device::curve(double X0, double Y0,
+void Fl_Graphics_Driver::curve(double X0, double Y0,
double X1, double Y1,
double X2, double Y2,
double X3, double Y3) {
diff --git a/src/fl_draw_image.cxx b/src/fl_draw_image.cxx
index 9542a9f0a..aa0c09e54 100644
--- a/src/fl_draw_image.cxx
+++ b/src/fl_draw_image.cxx
@@ -543,17 +543,17 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
}
}
-void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
}
-void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
}
-void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
innards(buf,x,y,w,h,d,l,1,0,0);
}
-void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
innards(0,x,y,w,h,d,0,1,cb,data);
}
diff --git a/src/fl_draw_image_mac.cxx b/src/fl_draw_image_mac.cxx
index a7c14fa9e..6f781d2a5 100644
--- a/src/fl_draw_image_mac.cxx
+++ b/src/fl_draw_image_mac.cxx
@@ -148,17 +148,17 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
CGContextSetShouldAntialias(fl_gc, true);
}
-void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
}
-void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
}
-void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
innards(buf,x,y,w,h,d,l,1,0,0);
}
-void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
innards(0,x,y,w,h,d,0,1,cb,data);
}
diff --git a/src/fl_draw_image_win32.cxx b/src/fl_draw_image_win32.cxx
index 403dfd9fe..e1d970ad7 100644
--- a/src/fl_draw_image_win32.cxx
+++ b/src/fl_draw_image_win32.cxx
@@ -46,6 +46,7 @@
#include <config.h>
#include <FL/Fl.H>
+#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
@@ -254,7 +255,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
}
}
}
- if(Fl_Device::current()->type() == Fl_Device::gdi_printer) {
+ if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) {
// if print context, device and logical units are not equal, so SetDIBitsToDevice
// does not do the expected job, whereas StretchDIBits does it.
StretchDIBits(fl_gc, x, y+j-k, w, k, 0, 0, w, k,
@@ -283,7 +284,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
static int fl_abs(int v) { return v<0 ? -v : v; }
-void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
innards(buf,x,y,w,h,d,l,fl_abs(d),0,0);
@@ -292,7 +293,7 @@ void Fl_Device::draw_image(const uchar* buf, int x, int y, int w, int h, int d,
}
}
-void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
@@ -302,7 +303,7 @@ void Fl_Device::draw_image(Fl_Draw_Image_Cb cb, void* data,
}
}
-void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
innards(buf,x,y,w,h,d,l,1,0,0);
@@ -311,7 +312,7 @@ void Fl_Device::draw_image_mono(const uchar* buf, int x, int y, int w, int h, in
}
}
-void Fl_Device::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
diff --git a/src/fl_draw_pixmap.cxx b/src/fl_draw_pixmap.cxx
index 5df23a3a6..a8755938a 100644
--- a/src/fl_draw_pixmap.cxx
+++ b/src/fl_draw_pixmap.cxx
@@ -40,6 +40,9 @@
#include <FL/x.H>
#include <stdio.h>
#include "flstring.h"
+#ifdef __APPLE_QUARTZ__
+#include <FL/Fl_Printer.H>
+#endif
static int ncolors, chars_per_pixel;
@@ -139,8 +142,6 @@ struct pixmap_data {
};
};
-# ifndef __APPLE_QUARTZ__
-
// callback for 1 byte per pixel:
static void cb1(void*v, int x, int y, int w, uchar* buf) {
pixmap_data& d = *(pixmap_data*)v;
@@ -160,8 +161,6 @@ static void cb2(void*v, int x, int y, int w, uchar* buf) {
}
}
-# endif // !__APPLE_QUARTZ__
-
#endif // U64 else U32
uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
@@ -222,7 +221,7 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0;
const uchar*const* data = (const uchar*const*)(cdata+1);
int transparent_index = -1;
- uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
+ uchar *transparent_c; // such that transparent_c[0,1,2] are the RGB of the transparent color
#ifdef WIN32
color_count = 0;
used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar));
@@ -335,15 +334,43 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
}
d.data = data;
#ifdef WIN32
- if (transparent_c) {
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
+#endif
+
+#ifdef __APPLE_QUARTZ__
+ if (fl_surface->type() == Fl_Printer::device_type) {
+ bool transparent = (transparent_index>=0);
+ transparent = true;
+ U32 *array = new U32[d.w * d.h], *q = array;
+ for (int Y = 0; Y < d.h; Y++) {
+ const uchar* p = data[Y];
+ if (chars_per_pixel <= 1) {
+ for (int X = 0; X < d.w; X++) {
+ *q++ = d.colors[*p++];
+ }
+ } else {
+ for (int X = 0; X < d.w; X++) {
+ U32* colors = (U32*)d.byte1[*p++];
+ *q++ = colors[*p++];
+ }
+ }
}
- else {
- uchar r, g, b;
- make_unused_color(r, g, b);
+ CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
+ CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
+ lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
+ src, 0L, false, kCGRenderingIntentDefault);
+ CGColorSpaceRelease(lut);
+ CGDataProviderRelease(src);
+ CGRect rect = { { x, y} , { d.w, d.h } };
+ Fl_X::q_begin_image(rect, 0, 0, d.w, d.h);
+ CGContextDrawImage(fl_gc, rect, img);
+ Fl_X::q_end_image();
+ CGImageRelease(img);
+ delete array;
}
-#endif
-#ifndef __APPLE_QUARTZ__
+ else {
+#endif // __APPLE_QUARTZ__
// build the mask bitmap used by Fl_Pixmap:
if (fl_mask_bitmap && transparent_index >= 0) {
@@ -386,40 +413,9 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
}
fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
-
-#else // __APPLE_QUARTZ__
-
- bool transparent = (transparent_index>=0);
- transparent = true;
- U32 *array = new U32[d.w * d.h], *q = array;
- for (int Y = 0; Y < d.h; Y++) {
- const uchar* p = data[Y];
- if (chars_per_pixel <= 1) {
- for (int X = 0; X < d.w; X++) {
- *q++ = d.colors[*p++];
- }
- } else {
- for (int X = 0; X < d.w; X++) {
- U32* colors = (U32*)d.byte1[*p++];
- *q++ = colors[*p++];
- }
+#ifdef __APPLE_QUARTZ__
}
- }
- CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
- CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
- CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
- lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
- src, 0L, false, kCGRenderingIntentDefault);
- CGColorSpaceRelease(lut);
- CGDataProviderRelease(src);
- CGRect rect = { { x, y} , { d.w, d.h } };
- Fl_X::q_begin_image(rect, 0, 0, d.w, d.h);
- CGContextDrawImage(fl_gc, rect, img);
- Fl_X::q_end_image();
- CGImageRelease(img);
- delete array;
-
-#endif // !__APPLE_QUARTZ__
+#endif
if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
return 1;
diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx
index 92fd58055..cb6887827 100644
--- a/src/fl_font_mac.cxx
+++ b/src/fl_font_mac.cxx
@@ -239,7 +239,7 @@ Fl_Font fl_font_ = 0;
Fl_Fontsize fl_size_ = 0;
-void Fl_Device::font(Fl_Font fnum, Fl_Fontsize size) {
+void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
if (fnum==-1) {
fl_font_ = 0;
fl_size_ = 0;
@@ -402,7 +402,7 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) {
void fl_draw(const char *str, int n, float x, float y);
-void Fl_Device::draw(const char* str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) {
fl_draw(str, n, (float)x-0.0f, (float)y+0.5f);
}
@@ -480,7 +480,7 @@ void fl_draw(const char *str, int n, float x, float y) {
#endif
}
-void Fl_Device::draw(int angle, const char *str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
CGContextSaveGState(fl_gc);
CGContextTranslateCTM(fl_gc, x, y);
CGContextRotateCTM(fl_gc, - angle*(M_PI/180) );
diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx
index fd0e3fdbf..7220eb3b9 100644
--- a/src/fl_font_win32.cxx
+++ b/src/fl_font_win32.cxx
@@ -24,6 +24,9 @@
//
// http://www.fltk.org/str.php
//
+
+#include <FL/Fl_Printer.H>
+
static int fl_angle_ = 0;
#ifndef FL_DOXYGEN
@@ -143,7 +146,7 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) {
fl_fontsize = find(fnum, size, angle);
}
-void Fl_Device::font(Fl_Font fnum, Fl_Fontsize size) {
+void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
fl_font(fnum, size, 0);
}
@@ -247,7 +250,7 @@ static void on_printer_extents_update(int &dx, int &dy, int &w, int &h)
// if printer context, extents shd be converted to logical coords
#define EXTENTS_UPDATE(x,y,w,h) \
- if (Fl_Device::current()->type() == Fl_Device::gdi_printer) { on_printer_extents_update(x,y,w,h); }
+ if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { on_printer_extents_update(x,y,w,h); }
static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string
static unsigned wc_len = 0; // current string buffer dimension
@@ -331,7 +334,7 @@ exit_error:
return;
} // fl_text_extents
-void Fl_Device::draw(const char* str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(const char* str, int n, int x, int y) {
int i = 0;
int lx = 0;
char *end = (char *)&str[n];
@@ -359,7 +362,7 @@ void Fl_Device::draw(const char* str, int n, int x, int y) {
SetTextColor(fl_gc, oldColor);
}
-void Fl_Device::draw(int angle, const char* str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(int angle, const char* str, int n, int x, int y) {
fl_font(fl_font_, fl_size_, angle);
// fl_draw(str, n, (int)x, (int)y);
int i = 0, i2=0;
diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx
index 1e019f557..e6ccea79c 100644
--- a/src/fl_font_x.cxx
+++ b/src/fl_font_x.cxx
@@ -269,7 +269,7 @@ XFontStruct* Fl_XFont_On_Demand::value() {
return ptr;
}
-void Fl_Device::font(Fl_Font fnum, Fl_Fontsize size) {
+void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
if (fnum==-1) {
fl_font_ = 0; fl_size_ = 0;
return;
@@ -318,7 +318,7 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) {
} // fl_text_extents
-void Fl_Device::draw(const char* c, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(const char* c, int n, int x, int y) {
if (font_gc != fl_gc) {
if (!current_font) fl_font(FL_HELVETICA, 14);
font_gc = fl_gc;
@@ -327,7 +327,7 @@ void Fl_Device::draw(const char* c, int n, int x, int y) {
// XDrawString(fl_display, fl_window, fl_gc, x, y, c, n);
XUtf8DrawString(fl_display, fl_window, current_font, fl_gc, x, y, c, n);
}
-void Fl_Device::draw(int angle, const char *str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
fprintf(stderr,"ROTATING TEXT NOT IMPLIMENTED\n");
fl_draw(str, n, (int)x, (int)y);
}
diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx
index 4d7063f80..bf2ca3ee8 100644
--- a/src/fl_font_xft.cxx
+++ b/src/fl_font_xft.cxx
@@ -133,7 +133,7 @@ void fl_font(Fl_Font fnum, Fl_Fontsize size, int angle) {
fl_xftfont = (void*)f->font;
}
-void Fl_Device::font(Fl_Font fnum, Fl_Fontsize size) {
+void Fl_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
fl_font(fnum,size,0);
}
@@ -502,7 +502,7 @@ void fl_destroy_xft_draw(Window id) {
#endif
}
-void Fl_Device::draw(const char *str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(const char *str, int n, int x, int y) {
if ( !current_font ) {
fl_font(FL_HELVETICA, 14);
}
@@ -539,7 +539,7 @@ void Fl_Device::draw(const char *str, int n, int x, int y) {
XftDrawStringUtf8(draw_, &color, current_font, x, y, (XftChar8 *)str, n);
}
-void Fl_Device::draw(int angle, const char *str, int n, int x, int y) {
+void Fl_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
fl_font(fl_font_, fl_size_, angle);
fl_draw(str, n, (int)x, (int)y);
fl_font(fl_font_, fl_size_);
diff --git a/src/fl_line_style.cxx b/src/fl_line_style.cxx
index b2bf1fc12..2fed71480 100644
--- a/src/fl_line_style.cxx
+++ b/src/fl_line_style.cxx
@@ -33,8 +33,10 @@
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
+#include <FL/Fl_Printer.H>
#include "flstring.h"
#include <stdio.h>
+#include <FL/fl_ask.H>//TMP
#ifdef __APPLE_QUARTZ__
float fl_quartz_line_width_ = 1.0f;
@@ -50,7 +52,7 @@ void fl_quartz_restore_line_style_() {
}
#endif
-void Fl_Device::line_style(int style, int width, char* dashes) {
+void Fl_Graphics_Driver::line_style(int style, int width, char* dashes) {
#if defined(USE_X11)
int ndashes = dashes ? strlen(dashes) : 0;
@@ -117,7 +119,7 @@ void Fl_Device::line_style(int style, int width, char* dashes) {
fl_quartz_line_width_ = (float)width;
fl_quartz_line_cap_ = Cap[(style>>8)&3];
// when printing kCGLineCapSquare seems better for solid lines
- if (Fl_Device::current()->type() == quartz_printer && style == FL_SOLID && dashes == NULL) {
+ if ( Fl_Surface_Device::surface()->type() == Fl_Printer::device_type && style == FL_SOLID && dashes == NULL ) {
fl_quartz_line_cap_ = kCGLineCapSquare;
}
fl_quartz_line_join_ = Join[(style>>12)&3];
diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx
index df8cbef9a..5f12936d9 100644
--- a/src/fl_rect.cxx
+++ b/src/fl_rect.cxx
@@ -38,15 +38,16 @@
#include <config.h>
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
+#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#ifdef __APPLE_QUARTZ__
extern float fl_quartz_line_width_;
-#define USINGQUARTZPRINTER (Fl_Device::current()->type() == quartz_printer)
+#define USINGQUARTZPRINTER (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type)
#endif
-void Fl_Device::rect(int x, int y, int w, int h) {
+void Fl_Graphics_Driver::rect(int x, int y, int w, int h) {
if (w<=0 || h<=0) return;
#if defined(USE_X11)
@@ -67,7 +68,7 @@ void Fl_Device::rect(int x, int y, int w, int h) {
#endif
}
-void Fl_Device::rectf(int x, int y, int w, int h) {
+void Fl_Graphics_Driver::rectf(int x, int y, int w, int h) {
if (w<=0 || h<=0) return;
#if defined(USE_X11)
if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
@@ -86,7 +87,7 @@ void Fl_Device::rectf(int x, int y, int w, int h) {
#endif
}
-void Fl_Device::xyline(int x, int y, int x1) {
+void Fl_Graphics_Driver::xyline(int x, int y, int x1) {
#if defined(USE_X11)
XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
#elif defined(WIN32)
@@ -102,7 +103,7 @@ void Fl_Device::xyline(int x, int y, int x1) {
#endif
}
-void Fl_Device::xyline(int x, int y, int x1, int y2) {
+void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
#if defined (USE_X11)
XPoint p[3];
p[0].x = x; p[0].y = p[1].y = y;
@@ -126,7 +127,7 @@ void Fl_Device::xyline(int x, int y, int x1, int y2) {
#endif
}
-void Fl_Device::xyline(int x, int y, int x1, int y2, int x3) {
+void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
#if defined(USE_X11)
XPoint p[4];
p[0].x = x; p[0].y = p[1].y = y;
@@ -153,7 +154,7 @@ void Fl_Device::xyline(int x, int y, int x1, int y2, int x3) {
#endif
}
-void Fl_Device::yxline(int x, int y, int y1) {
+void Fl_Graphics_Driver::yxline(int x, int y, int y1) {
#if defined(USE_X11)
XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
#elif defined(WIN32)
@@ -171,7 +172,7 @@ void Fl_Device::yxline(int x, int y, int y1) {
#endif
}
-void Fl_Device::yxline(int x, int y, int y1, int x2) {
+void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
#if defined(USE_X11)
XPoint p[3];
p[0].x = p[1].x = x; p[0].y = y;
@@ -195,7 +196,7 @@ void Fl_Device::yxline(int x, int y, int y1, int x2) {
#endif
}
-void Fl_Device::yxline(int x, int y, int y1, int x2, int y3) {
+void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
#if defined(USE_X11)
XPoint p[4];
p[0].x = p[1].x = x; p[0].y = y;
@@ -222,7 +223,7 @@ void Fl_Device::yxline(int x, int y, int y1, int x2, int y3) {
#endif
}
-void Fl_Device::line(int x, int y, int x1, int y1) {
+void Fl_Graphics_Driver::line(int x, int y, int x1, int y1) {
#if defined(USE_X11)
XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
#elif defined(WIN32)
@@ -242,7 +243,7 @@ void Fl_Device::line(int x, int y, int x1, int y1) {
#endif
}
-void Fl_Device::line(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
#if defined(USE_X11)
XPoint p[3];
p[0].x = x; p[0].y = y;
@@ -268,7 +269,7 @@ void Fl_Device::line(int x, int y, int x1, int y1, int x2, int y2) {
#endif
}
-void Fl_Device::loop(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) {
#if defined(USE_X11)
XPoint p[4];
p[0].x = x; p[0].y = y;
@@ -294,7 +295,7 @@ void Fl_Device::loop(int x, int y, int x1, int y1, int x2, int y2) {
#endif
}
-void Fl_Device::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+void Fl_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
#if defined(USE_X11)
XPoint p[5];
p[0].x = x; p[0].y = y;
@@ -323,7 +324,7 @@ void Fl_Device::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y
#endif
}
-void Fl_Device::polygon(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) {
XPoint p[4];
p[0].x = x; p[0].y = y;
p[1].x = x1; p[1].y = y1;
@@ -348,7 +349,7 @@ void Fl_Device::polygon(int x, int y, int x1, int y1, int x2, int y2) {
#endif
}
-void Fl_Device::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+void Fl_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
XPoint p[5];
p[0].x = x; p[0].y = y;
p[1].x = x1; p[1].y = y1;
@@ -375,7 +376,7 @@ void Fl_Device::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, in
#endif
}
-void Fl_Device::point(int x, int y) {
+void Fl_Graphics_Driver::point(int x, int y) {
#if defined(USE_X11)
XDrawPoint(fl_display, fl_window, fl_gc, x, y);
#elif defined(WIN32)
@@ -450,7 +451,7 @@ Fl_Region fl_clip_region() {
return rstack[rstackptr];
}
-void Fl_Device::push_clip(int x, int y, int w, int h) {
+void Fl_Graphics_Driver::push_clip(int x, int y, int w, int h) {
Fl_Region r;
if (w > 0 && h > 0) {
r = XRectangleRegion(x,y,w,h);
@@ -487,14 +488,14 @@ void Fl_Device::push_clip(int x, int y, int w, int h) {
}
// make there be no clip (used by fl_begin_offscreen() only!)
-void Fl_Device::push_no_clip() {
+void Fl_Graphics_Driver::push_no_clip() {
if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
else Fl::warning("fl_push_no_clip: clip stack overflow!\n");
fl_restore_clip();
}
// pop back to previous clip:
-void Fl_Device::pop_clip() {
+void Fl_Graphics_Driver::pop_clip() {
if (rstackptr > 0) {
Fl_Region oldr = rstack[rstackptr--];
if (oldr) XDestroyRegion(oldr);
@@ -502,7 +503,7 @@ void Fl_Device::pop_clip() {
fl_restore_clip();
}
-int Fl_Device::not_clipped(int x, int y, int w, int h) {
+int Fl_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
if (x+w <= 0 || y+h <= 0) return 0;
Fl_Region r = rstack[rstackptr];
#if defined (USE_X11)
@@ -510,7 +511,7 @@ int Fl_Device::not_clipped(int x, int y, int w, int h) {
#elif defined(WIN32)
if (!r) return 1;
RECT rect;
- if (Fl_Device::current()->type() == Fl_Device::gdi_printer) { // in case of print context, convert coords from logical to device
+ if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // in case of print context, convert coords from logical to device
POINT pt[2] = { {x, y}, {x + w, y + h} };
LPtoDP(fl_gc, pt, 2);
rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y;
@@ -533,7 +534,7 @@ int Fl_Device::not_clipped(int x, int y, int w, int h) {
}
// return rectangle surrounding intersection of this rectangle and clip:
-int Fl_Device::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
+int Fl_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
X = x; Y = y; W = w; H = h;
Fl_Region r = rstack[rstackptr];
if (!r) return 0;
@@ -572,7 +573,7 @@ int Fl_Device::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int&
} else { // partial intersection
RECT rect;
GetRgnBox(temp, &rect);
- if(Fl_Device::current()->type() == Fl_Device::gdi_printer) { // if print context, convert coords from device to logical
+ if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // if print context, convert coords from device to logical
POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} };
DPtoLP(fl_gc, pt, 2);
X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y;
diff --git a/src/fl_vertex.cxx b/src/fl_vertex.cxx
index 014593dab..f62a8a263 100644
--- a/src/fl_vertex.cxx
+++ b/src/fl_vertex.cxx
@@ -145,13 +145,13 @@ static int n;
static int what;
enum {LINE, LOOP, POLYGON, POINT_};
-void Fl_Device::begin_points() {n = 0; what = POINT_;}
+void Fl_Graphics_Driver::begin_points() {n = 0; what = POINT_;}
-void Fl_Device::begin_line() {n = 0; what = LINE;}
+void Fl_Graphics_Driver::begin_line() {n = 0; what = LINE;}
-void Fl_Device::begin_loop() {n = 0; what = LOOP;}
+void Fl_Graphics_Driver::begin_loop() {n = 0; what = LOOP;}
-void Fl_Device::begin_polygon() {n = 0; what = POLYGON;}
+void Fl_Graphics_Driver::begin_polygon() {n = 0; what = POLYGON;}
/**
Transforms coordinate using the current transformation matrix.
@@ -189,7 +189,7 @@ static void fl_transformed_vertex(COORD_T x, COORD_T y) {
}
}
-void Fl_Device::transformed_vertex(double xf, double yf) {
+void Fl_Graphics_Driver::transformed_vertex(double xf, double yf) {
#ifdef __APPLE_QUARTZ__
fl_transformed_vertex(COORD_T(xf), COORD_T(yf));
#else
@@ -197,11 +197,11 @@ void Fl_Device::transformed_vertex(double xf, double yf) {
#endif
}
-void Fl_Device::vertex(double x,double y) {
+void Fl_Graphics_Driver::vertex(double x,double y) {
fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y);
}
-void Fl_Device::end_points() {
+void Fl_Graphics_Driver::end_points() {
#if defined(USE_X11)
if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0);
#elif defined(WIN32)
@@ -219,7 +219,7 @@ void Fl_Device::end_points() {
#endif
}
-void Fl_Device::end_line() {
+void Fl_Graphics_Driver::end_line() {
if (n < 2) {
fl_end_points();
return;
@@ -245,13 +245,13 @@ static void fixloop() { // remove equal points from closed path
while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
}
-void Fl_Device::end_loop() {
+void Fl_Graphics_Driver::end_loop() {
fixloop();
if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y);
fl_end_line();
}
-void Fl_Device::end_polygon() {
+void Fl_Graphics_Driver::end_polygon() {
fixloop();
if (n < 3) {
fl_end_line();
@@ -284,7 +284,7 @@ static int counts[20];
static int numcount;
#endif
-void Fl_Device::begin_complex_polygon() {
+void Fl_Graphics_Driver::begin_complex_polygon() {
fl_begin_polygon();
gap_ = 0;
#if defined(WIN32)
@@ -292,7 +292,7 @@ void Fl_Device::begin_complex_polygon() {
#endif
}
-void Fl_Device::gap() {
+void Fl_Graphics_Driver::gap() {
while (n>gap_+2 && p[n-1].x == p[gap_].x && p[n-1].y == p[gap_].y) n--;
if (n > gap_+2) {
fl_transformed_vertex((COORD_T)p[gap_].x, (COORD_T)p[gap_].y);
@@ -305,7 +305,7 @@ void Fl_Device::gap() {
}
}
-void Fl_Device::end_complex_polygon() {
+void Fl_Graphics_Driver::end_complex_polygon() {
fl_gap();
if (n < 3) {
fl_end_line();
@@ -336,7 +336,7 @@ void Fl_Device::end_complex_polygon() {
// warning: these do not draw rotated ellipses correctly!
// See fl_arc.c for portable version.
-void Fl_Device::circle(double x, double y,double r) {
+void Fl_Graphics_Driver::circle(double x, double y,double r) {
double xt = fl_transform_x(x,y);
double yt = fl_transform_y(x,y);
double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
diff --git a/src/ps_image.cxx b/src/ps_image.cxx
index 7958d2957..fa4a6fe2c 100644
--- a/src/ps_image.cxx
+++ b/src/ps_image.cxx
@@ -20,9 +20,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
#ifndef FL_DOXYGEN
@@ -31,12 +29,12 @@
#include <math.h>
#include <string.h>
-#include <FL/Fl_PSfile_Device.H>
+#include <FL/Fl_PostScript.H>
#include <FL/Fl.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Bitmap.H>
-int Fl_PSfile_Device::alpha_mask(const uchar * data, int w, int h, int D, int LD){
+int Fl_PostScript_Graphics_Driver::alpha_mask(const uchar * data, int w, int h, int D, int LD){
mask = 0;
if((D/2)*2 != D){ //no mask info
@@ -184,18 +182,27 @@ int Fl_PSfile_Device::alpha_mask(const uchar * data, int w, int h, int D, int LD
return 0;
}
-// bitwise inversion of all 4-bit quantities
-static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
-// bitwise inversion of a byte
-static inline uchar swap_byte(const uchar b){
- return (swapped[b & 0xF] << 4) | swapped[b >> 4];
- }
+
+// TODO: anybody has more efficient algoritm?
+static inline uchar swap_byte(const uchar i){
+ uchar b =0;
+ if(i & 1) b |= 128;
+ if(i & 2) b |= 64;
+ if(i & 4) b |= 32;
+ if(i & 8) b |= 16;
+ if(i & 16) b |= 8;
+ if(i & 32) b |= 4;
+ if(i & 64) b |= 2;
+ if(i & 128) b |= 1;
+ return b;
+}
+
extern uchar **fl_mask_bitmap;
-void Fl_PSfile_Device::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
+void Fl_PostScript_Graphics_Driver::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
if(D<3){ //mono
@@ -262,7 +269,7 @@ void Fl_PSfile_Device::draw_scaled_image(const uchar *data, double x, double y,
};
-void Fl_PSfile_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
+void Fl_PostScript_Graphics_Driver::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
int level2_mask = 0;
fprintf(output,"save\n");
@@ -350,7 +357,7 @@ void Fl_PSfile_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, doub
delete[] rgbdata;
}
-void Fl_PSfile_Device::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
+void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) {
fprintf(output,"save\n");
@@ -411,7 +418,7 @@ void Fl_PSfile_Device::draw_scaled_image_mono(const uchar *data, double x, doubl
-void Fl_PSfile_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
+void Fl_PostScript_Graphics_Driver::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) {
fprintf(output,"save\n");
int i,j,k;
@@ -460,7 +467,7 @@ void Fl_PSfile_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data,
////////////////////////////// Image classes //////////////////////
-void Fl_PSfile_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){
+void Fl_PostScript_Graphics_Driver::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){
const char * const * di =pxm->data();
int w,h;
if (!fl_measure_pixmap(di, w, h)) return;
@@ -476,7 +483,7 @@ void Fl_PSfile_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int
fl_mask_bitmap=0;
};
-void Fl_PSfile_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){
+void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){
const uchar * di = rgb->array;
int w = rgb->w();
int h = rgb->h();
@@ -490,7 +497,7 @@ void Fl_PSfile_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, i
mask=0;
};
-void Fl_PSfile_Device::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){
+void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){
const uchar * di = bitmap->array;
int w,h;
int LD=(bitmap->w()+7)/8;