Using Fl_Plugin feature to automatically draw OpenGL (sub)windows. No extra coding needs to be done. Just call Fl_Printer::print_widget(...). The Fl_Gl_Printer device can (and should) be removed or at least made inaccessible.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7280 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2010-03-16 22:51:31 +00:00
parent 1b6e7bd812
commit 762d02fb62
8 changed files with 72 additions and 11 deletions

View File

@ -7,6 +7,7 @@
#define Fl_Device_H
#include <FL/x.H>
#include <FL/Fl_Plugin.H>
#ifdef WIN32
#include <Commdlg.h>
#elif defined(__APPLE__)
@ -19,6 +20,7 @@ class Fl_RGB_Image;
class Fl_Pixmap;
class Fl_Bitmap;
class Fl_Display;
class Fl_Virtual_Printer;
extern Fl_Display *fl_display_device;
typedef void (*Fl_Draw_Image_Cb)(void* ,int,int,int,uchar*);
@ -200,4 +202,18 @@ 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:
Fl_Device_Plugin(const char *name)
: Fl_Plugin(klass(), name) { }
virtual const char *klass() { return "fltk:device"; }
virtual const char *name() = 0;
virtual int print(Fl_Virtual_Printer*, Fl_Widget*, int x, int y) { return 0; }
};
#endif // Fl_Device_H

View File

@ -205,6 +205,13 @@ public:
*/
void make_overlay_current();
/** Returns an Fl_Gl_Window pointer if this widget is an Fl_Gl_Window.
\retval NULL if this widget is not derived from Fl_Gl_Window.
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual Fl_Gl_Window* as_gl_window() {return this;}
~Fl_Gl_Window();
/**
Creates a new Fl_Gl_Window widget using the given size, and label string.

View File

@ -182,7 +182,7 @@ public:
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual Fl_Group* as_group() const { return (Fl_Group*)this; }
virtual Fl_Group* as_group() { return this; }
// back compatibility functions:

View File

@ -930,16 +930,23 @@ public:
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual Fl_Group* as_group() const {return 0;}
virtual Fl_Group* as_group() {return 0;}
/** Returns an Fl_Window pointer if this widget is an Fl_Window.
\retval NULL if this widget is not derived from Fl_Window.
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
\retval NULL if this widget is not derived from Fl_Window.
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual Fl_Window* as_window() const {return 0;}
virtual Fl_Window* as_window() {return 0;}
/** Returns an Fl_Gl_Window pointer if this widget is an Fl_Gl_Window.
\retval NULL if this widget is not derived from Fl_Gl_Window.
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual class Fl_Gl_Window* as_gl_window() {return 0;}
/** For back compatibility only.
\deprecated Use selection_color() instead.
*/

View File

@ -421,7 +421,7 @@ public:
\note This method is provided to avoid dynamic_cast.
\todo More documentation ...
*/
virtual Fl_Window* as_window() const { return (Fl_Window*)this; }
virtual Fl_Window* as_window() { return this; }
// for back-compatibility only:
/**

View File

@ -52,7 +52,16 @@ void Fl_Virtual_Printer::print_widget(Fl_Widget* widget, int delta_x, int delta_
#else
_XGC *save_gc = fl_gc; // FIXME
#endif
widget->draw();
// 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();
fl_gc = save_gc;
if (is_window) fl_pop_clip();
// find subwindows of widget and print them

View File

@ -89,3 +89,25 @@ void Fl_Gl_Printer::print_gl_window(Fl_Gl_Window *glw, int x, int y)
free(baseAddress);
#endif // __APPLE__
}
/*
This class will make sure that OpenGL printing is availbale if fltk_gl
was linked to the programm.
*/
class Fl_Gl_Device_Plugin : public Fl_Device_Plugin {
public:
Fl_Gl_Device_Plugin() : Fl_Device_Plugin(name()) { }
virtual const char *name() { return "opengl.device.fltk.org"; }
virtual int print(Fl_Virtual_Printer *p, Fl_Widget *w, int x, int y) {
Fl_Gl_Window *glw = w->as_gl_window();
if (!glw) return 0;
// FIXME: this is a dangerous cast! Remove Fl_Gl_Printer entirely and add
// FIXME: a static function (may be a friend of Fl_Printer).
Fl_Gl_Printer *glp = (Fl_Gl_Printer*)p;
glp->print_gl_window(glw, x, y);
return 1;
}
};
static Fl_Gl_Device_Plugin Gl_Device_Plugin;

View File

@ -168,7 +168,7 @@ void print_cb(Fl_Widget *w, void *data)
if(!win) return;
if( printer.start_job(1) ) return;
if( printer.start_page() ) return;
printer.scale(0.68,0.68);
printer.scale(0.5,0.5);
printer.print_widget( win );
printer.print_gl_window( cube, cube->x(), cube->y() );
printer.print_gl_window( cube2, cube2->x(), cube2->y() );