Reorganized code to allow compilation with Fl_Device, Fl_Display but without Fl_Abstract_Printer

(may be useful for embarked devices)

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7330 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2010-03-25 13:59:00 +00:00
parent 309e478013
commit d748d323b9
10 changed files with 390 additions and 362 deletions

View File

@ -2,7 +2,7 @@
// "$Id$"
//
// Definition of classes Fl_Device, Fl_Display, Fl_Quartz_Display, Fl_GDI_Display,
// Fl_Xlib_Display and Fl_Device_Plugin for the Fast Light Tool Kit (FLTK).
// and Fl_Xlib_Display for the Fast Light Tool Kit (FLTK).
//
// Copyright 2010 by Bill Spitzak and others.
//
@ -25,12 +25,19 @@
//
// http://www.fltk.org/str.php
//
/** \file Fl_Device.H
\brief declaration of classes Fl_Device, Fl_Display.
*/
#ifndef Fl_Device_H
#define Fl_Device_H
#include <FL/x.H>
#include <FL/Fl_Plugin.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Bitmap.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_RGB_Image.H>
#ifdef WIN32
#include <commdlg.h>
#elif defined(__APPLE__)
@ -39,14 +46,23 @@
#endif
class Fl_Widget;
class Fl_Image;
class Fl_RGB_Image;
class Fl_Pixmap;
class Fl_Bitmap;
class Fl_Device;
class Fl_Display;
class Fl_Abstract_Printer;
extern FL_EXPORT Fl_Display *fl_display_device;
typedef void (*Fl_Draw_Image_Cb)(void* ,int,int,int,uchar*);
/** \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;
/**
signature of image generation callback function.
\param[in] data user data passed to function
\param[in] x,y,w position and width of scan line in image
\param[out] buf buffer for generated image data. You must copy \p w
pixels from scanline \p y, starting at pixel \p x
to this buffer.
*/
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.
@ -63,7 +79,7 @@ typedef void (*Fl_Draw_Image_Cb)(void* ,int,int,int,uchar*);
function of the \ref fl_drawings and \ref fl_attributes modules which bears the same name
prefixed with fl_ .
*/
class FL_EXPORT Fl_Device {
class Fl_Device {
protected:
/** \brief The device type */
int type_;
@ -73,6 +89,9 @@ protected:
uchar bg_g_;
/** \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 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);
@ -220,24 +239,9 @@ 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
/** \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.
*/
virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy);
/** \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.
*/
virtual void draw(Fl_RGB_Image * rgb,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.
*/
virtual void draw(Fl_Bitmap * bmp,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:
/**
@ -254,19 +258,10 @@ public:
/**
@brief An RTTI emulation of device classes. It returns values < 256 if it is a display device
*/
int type() {return type_;};
/**
@brief Sets this device (display, printer, local file) as the target of future graphics calls.
*
@return The current target device of graphics calls.
*/
virtual Fl_Device *set_current();
inline int type() {return type_;};
virtual Fl_Device *set_current(void);
virtual ~Fl_Device() {};
/**
@brief Returns the current target device of graphics calls.
*/
static Fl_Device *current();
/**
@ -312,28 +307,6 @@ public:
};
#endif
/**
This plugin socket allows the integration of new device drivers for special
window or screen types. It is currently used to provide an automated printing
service for OpenGL windows, if linked with fltk_gl.
*/
class Fl_Device_Plugin : public Fl_Plugin {
public:
/** \brief The constructor */
Fl_Device_Plugin(const char *name)
: Fl_Plugin(klass(), name) { }
/** \brief Returns the class name */
virtual const char *klass() { return "fltk:device"; }
/** \brief Returns the plugin name */
virtual const char *name() = 0;
/** \brief Prints a widget
\param p the printer
\param w the widget
\param x,y offsets where to print relatively to coordinates origin
*/
virtual int print(Fl_Abstract_Printer* p, Fl_Widget* w, int x, int y) { return 0; }
};
#endif // Fl_Device_H
//

View File

@ -24,6 +24,9 @@
//
// http://www.fltk.org/str.php
//
/** \file Fl_Printer.H
\brief declaration of classes Fl_Abstract_Printer, Fl_Printer, Fl_Device_Plugin.
*/
#ifndef Fl_Printer_H
#define Fl_Printer_H
@ -41,17 +44,19 @@
This class has no public constructor: don't instantiate it; use Fl_Printer or Fl_PSfile_Device instead.
\see class Fl_Printer for full documentation of member functions.
*/
class Fl_Abstract_Printer : public Fl_Device {
class Fl_Abstract_Printer : public Fl_Device {
friend class Fl_Pixmap;
friend class Fl_RGB_Image;
friend class Fl_Bitmap;
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 */
@ -64,41 +69,25 @@ protected:
void *gc;
/** \brief the constructor */
Fl_Abstract_Printer(void) { gc = NULL; bg_r_ = bg_g_ = bg_b_ = 0; };
#ifdef __APPLE__
/** \brief deletes the page image list */
void delete_image_list();
#endif
public:
/**
@brief Sets this printer as the target of future graphics calls.
@return The current target device of graphics calls.
*/
Fl_Device *set_current(void);
/** \brief see Fl_Printer::start_job(int pagecount, int *frompage, int *topage) */
virtual int start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
/** \brief see Fl_Printer::start_page() */
virtual int start_page(void);
/** \brief see Fl_Printer::printable_rect(int *w, int *h) */
virtual int printable_rect(int *w, int *h);
/** \brief see Fl_Printer::margins(int *left, int *top, int *right, int *bottom) */
virtual void margins(int *left, int *top, int *right, int *bottom);
/** \brief see Fl_Printer::origin(int x, int y) */
virtual void origin(int x, int y);
/** \brief see Fl_Printer::origin(int *x, int *y) */
void origin(int *x, int *y);
/** \brief see Fl_Printer::scale(float scale_x, float scale_y) */
virtual void scale(float scale_x, float scale_y);
/** \brief see Fl_Printer::rotate(float angle) */
virtual void rotate(float angle);
/** \brief see Fl_Printer::translate(int x, int y) */
virtual void translate(int x, int y);
/** \brief see Fl_Printer::untranslate(void) */
virtual void untranslate(void);
/** \brief see Fl_Printer::print_widget(Fl_Widget* widget, int delta_x, int delta_y) */
void print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
/** \brief see Fl_Printer::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y) */
void print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0);
/** \brief see Fl_Printer::end_page() */
virtual int end_page (void);
/** \brief see Fl_Printer::end_job() */
virtual void end_job (void);
};
@ -140,142 +129,23 @@ public:
@brief The constructor.
*/
Fl_Printer(void);
/**
@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 start_job(int pagecount, int *frompage = NULL, int *topage = NULL);
/**
@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 start_page (void);
/**
@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 printable_rect(int *w, int *h);
/**
@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 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 origin(int x, int y);
#ifdef FL_DOXYGEN
/**
@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 origin(int *x, int *y);
#endif
/**
@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 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.
On MSWindows, Fl_RGB_Image's don't rotate well; print_window_part() is an efficient workaround.
@param angle Rotation angle in counterclockwise degrees.
*/
void rotate(float angle);
/**
@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 translate(int x, int y);
/**
@brief Undoes the effect of a previous translate() call.
*/
void untranslate(void);
#ifdef FL_DOXYGEN
/**
@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().
<br>Under MSWindows and X11, Fl_RGB_Image's are printed without transparency.
A workaround is to use the print_window_part() call.
@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 print_widget(Fl_Widget* widget, int delta_x = 0, int delta_y = 0);
/**
@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 print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x = 0, int delta_y = 0);
#endif
/**
@brief To be called at the end of each page.
*
@return 0 iff OK.
*/
int end_page (void);
/**
@brief To be called at the end of a print job.
*/
void end_job (void);
};
@ -291,6 +161,28 @@ public:
};
#endif
/**
This plugin socket allows the integration of new device drivers for special
window or screen types. It is currently used to provide an automated printing
service for OpenGL windows, if linked with fltk_gl.
*/
class Fl_Device_Plugin : public Fl_Plugin {
public:
/** \brief The constructor */
Fl_Device_Plugin(const char *name)
: Fl_Plugin(klass(), name) { }
/** \brief Returns the class name */
virtual const char *klass() { return "fltk:device"; }
/** \brief Returns the plugin name */
virtual const char *name() = 0;
/** \brief Prints a widget
\param p the printer
\param w the widget
\param x,y offsets where to print relatively to coordinates origin
*/
virtual int print(Fl_Abstract_Printer* p, Fl_Widget* w, int x, int y) { return 0; }
};
#endif // Fl_Printer_H
//

View File

@ -42,8 +42,6 @@ class Fl_Image;
// Label flags...
FL_EXPORT extern char fl_draw_shortcut;
/** \brief The device that currently receives all graphics requests */
FL_EXPORT extern Fl_Device *fl_device;
/** \addtogroup fl_attributes
@{
@ -578,15 +576,6 @@ FL_EXPORT void fl_frame2(const char* s, int x, int y, int w, int h);
FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color);
// images:
/**
signature of image generation callback function.
\param[in] data user data passed to function
\param[in] x,y,w position and width of scan line in image
\param[out] buf buffer for generated image data. You must copy \p w
pixels from scanline \p y, starting at pixel \p x
to this buffer.
*/
typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf);
/**
Draw an 8-bit per color RGB or luminance image.

297
src/Fl_Abstract_Printer.cxx Normal file
View File

@ -0,0 +1,297 @@
//
// "$Id$"
//
// implementation of Fl_Abstract_Printer 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_Abstract_Printer.cxx
\brief implementation of class Fl_Abstract_Printer.
*/
#include <FL/Fl.H>
#include <FL/Fl_Printer.H>
/**
@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().
<br>Under MSWindows and X11, Fl_RGB_Image's are printed without transparency.
A workaround is to use the print_window_part() call.
@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_Abstract_Printer::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) drawn_by_plugin = pi->print(this, widget, 0, 0);
}
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_Abstract_Printer::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_Abstract_Printer::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_Abstract_Printer::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_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();
this->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_Abstract_Printer::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_Abstract_Printer::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
Fl_Device *Fl_Abstract_Printer::set_current(void)
{
#ifdef __APPLE__
fl_gc = (CGContextRef)gc;
#elif defined(WIN32)
fl_gc = (HDC)gc;
#else
fl_gc = (_XGC*)gc;
#endif
return this->Fl_Device::set_current();
}
/**
@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_Abstract_Printer::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_Abstract_Printer::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_Abstract_Printer::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_Abstract_Printer::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_Abstract_Printer::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_Abstract_Printer::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.
On MSWindows, Fl_RGB_Image's don't rotate well; print_window_part() is an efficient workaround.
@param angle Rotation angle in counterclockwise degrees.
*/
void Fl_Abstract_Printer::rotate(float angle) {}
/**
@brief To be called at the end of each page.
*
@return 0 iff OK.
*/
int Fl_Abstract_Printer::end_page (void) {return 1;}
/**
@brief To be called at the end of a print job.
*/
void Fl_Abstract_Printer::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_Abstract_Printer::translate(int x, int y) {}
/**
@brief Undoes the effect of a previous translate() call.
*/
void Fl_Abstract_Printer::untranslate(void) {}
//
// End of "$Id$".
//

View File

@ -37,7 +37,6 @@
#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__)
@ -266,7 +265,7 @@ Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array)
void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
if(fl_device->type() == Fl_Device::postscript_device) {
((Fl_Abstract_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
return;
}
if (!array) {

View File

@ -1,7 +1,7 @@
//
// "$Id$"
//
// implementation of Fl_Device and Fl_Abstract_Printer classes for the Fast Light Tool Kit (FLTK).
// implementation of Fl_Device class for the Fast Light Tool Kit (FLTK).
//
// Copyright 2010 by Bill Spitzak and others.
//
@ -27,166 +27,44 @@
#include <FL/Fl.H>
#include <FL/Fl_Device.H>
#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
//#include <FL/fl_draw.H>
#include <FL/Fl_Image.H>
extern Fl_Device *fl_device;
/** \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_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy)
{
// presently, never gets called
pxm->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)
{
// presently, never gets called
bm->draw(XP, YP, WP, HP, cx, 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.
*/
void Fl_Device::draw(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy)
{
// presently, never gets called
rgb->draw(XP, YP, WP, HP, cx, cy);
}
void Fl_Abstract_Printer::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) drawn_by_plugin = pi->print(this, widget, 0, 0);
}
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_Abstract_Printer::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);
}
}
void Fl_Abstract_Printer::origin(int *x, int *y)
{
if (x) *x = x_offset;
if (y) *y = y_offset;
}
void Fl_Abstract_Printer::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_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();
this->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
}
}
void Fl_Abstract_Printer::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_Abstract_Printer::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;
}
}
Fl_Device *Fl_Abstract_Printer::set_current(void)
{
#ifdef __APPLE__
fl_gc = (CGContextRef)gc;
#elif defined(WIN32)
fl_gc = (HDC)gc;
#else
fl_gc = (_XGC*)gc;
#endif
return this->Fl_Device::set_current();
}
int Fl_Abstract_Printer::start_job(int pagecount, int *frompage, int *topage) {return 1;}
int Fl_Abstract_Printer::start_page (void) {return 1;}
int Fl_Abstract_Printer::printable_rect(int *w, int *h) {return 1;}
void Fl_Abstract_Printer::margins(int *left, int *top, int *right, int *bottom) {}
void Fl_Abstract_Printer::origin(int x, int y) {}
void Fl_Abstract_Printer::scale (float scale_x, float scale_y) {}
void Fl_Abstract_Printer::rotate(float angle) {}
int Fl_Abstract_Printer::end_page (void) {return 1;}
void Fl_Abstract_Printer::end_job (void) {}
void Fl_Abstract_Printer::translate(int x, int y) {}
void Fl_Abstract_Printer::untranslate(void) {}
/**
@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;
@ -194,6 +72,9 @@ Fl_Device *Fl_Device::set_current(void)
return current;
}
/**
@brief Returns the current target device of graphics calls.
*/
Fl_Device *Fl_Device::current(void)
{
return fl_device;

View File

@ -234,7 +234,6 @@ int Fl_Printer::end_page (void)
rsult = 1;
}
}
delete_image_list();
gc = NULL;
return rsult;
}

View File

@ -31,7 +31,6 @@
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Printer.H>
#include "flstring.h"
#ifdef WIN32
@ -436,7 +435,7 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
if(fl_device->type() == Fl_Device::postscript_device) {
((Fl_Abstract_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
return;
}
// Don't draw an empty image...

View File

@ -68,7 +68,7 @@ const Fl_PSfile_Device::page_format Fl_PSfile_Device::page_formats[NO_PAGE_FORMA
{ 127, 181, "B9"},
{ 91, 127, "B10"},
// others (look at Fl_Printer.H} //
// others
{ 459, 649, "EnvC5"}, // envelope
{ 312, 624, "EnvDL"}, // envelope
{ 522, 756, "Executive"},

View File

@ -47,7 +47,6 @@
#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"
@ -76,7 +75,7 @@ void Fl_Pixmap::measure() {
void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
if(fl_device->type() == Fl_Device::postscript_device) {
((Fl_Abstract_Printer*)fl_device)->draw(this, XP, YP, WP, HP, cx, cy);
fl_device->draw(this, XP, YP, WP, HP, cx, cy);
return;
}
// ignore empty or bad pixmap data: