diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H index bc757ee2e..c51e99c1d 100644 --- a/FL/Fl_Device.H +++ b/FL/Fl_Device.H @@ -33,6 +33,7 @@ #ifndef Fl_Device_H #define Fl_Device_H +#include #include #include #include @@ -53,6 +54,27 @@ FL_EXPORT extern Fl_Graphics_Driver *fl_graphics_driver; */ typedef void (*Fl_Draw_Image_Cb)(void* data,int x,int y,int w,uchar* buf); +#define REGION_STACK_SIZE 10 +#define REGION_STACK_MAX (REGION_STACK_SIZE - 1) + +#define MATRIX_STACK_SIZE 32 +#define MATRIX_STACK_MAX (MATRIX_STACK_SIZE - 1) +struct matrix {double a, b, c, d, x, y;}; + +// typedef what the x,y fields in a point are: +#ifdef WIN32 +typedef int COORD_T; +# define XPOINT XPoint +#elif defined(__APPLE__) +typedef float COORD_T; +typedef struct { float x; float y; } QPoint; +# define XPOINT QPoint +extern float fl_quartz_line_width_; +#else +typedef short COORD_T; +# define XPOINT XPoint +#endif + /** \brief All graphical output devices and all graphics systems. */ @@ -88,6 +110,23 @@ public: in the \ref fl_drawings and \ref fl_attributes modules. */ class FL_EXPORT Fl_Graphics_Driver : public Fl_Device { + enum {LINE, LOOP, POLYGON, POINT_}; + int sptr; + matrix stack[MATRIX_STACK_SIZE]; + matrix m; + int n, p_size, gap_; + XPOINT *p; + int what; + int fl_clip_state_number; + int rstackptr; + Fl_Region rstack[REGION_STACK_MAX]; +#ifdef WIN32 + int numcount; + int counts[20]; +#endif + void transformed_vertex0(COORD_T x, COORD_T y); + void fixloop(); + protected: /* ** \brief red color for background and/or mixing if device does not support masking or alpha * uchar bg_r_; @@ -143,13 +182,27 @@ protected: friend void fl_begin_complex_polygon(); friend void fl_gap(); friend void fl_end_complex_polygon(); + friend void fl_push_matrix(); + friend void fl_pop_matrix(); + friend void fl_mult_matrix(double a, double b, double c, double d, double x, double y); + friend double fl_transform_x(double x, double y); + friend double fl_transform_y(double x, double y); + friend double fl_transform_dx(double x, double y); + friend double fl_transform_dy(double x, double y); + friend Fl_Region fl_clip_region(); + friend void fl_clip_region(Fl_Region r); + friend void fl_restore_clip(); + friend void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L); friend void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L); 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); - + friend void gl_start(); + + matrix *fl_matrix; + /** \brief The constructor. */ - Fl_Graphics_Driver() {}; + 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). */ @@ -238,6 +291,28 @@ protected: virtual void push_no_clip(); /** \brief see fl_pop_clip(). */ virtual void pop_clip(); + + /** \brief see fl_push_matrix(). */ + void push_matrix(); + /** \brief see fl_pop_matrix(). */ + void pop_matrix(); + /** \brief see fl_mult_matrix(double a, double b, double c, double d, double x, double y). */ + void mult_matrix(double a, double b, double c, double d, double x, double y); + /** \brief see fl_transform_x(double x, double y). */ + double transform_x(double x, double y); + /** \brief see fl_transform_y(double x, double y). */ + double transform_y(double x, double y); + /** \brief see fl_transform_dx(double x, double y). */ + double transform_dx(double x, double y); + /** \brief see fl_transform_dy(double x, double y). */ + double transform_dy(double x, double y); + /** \brief see fl_clip_region(). */ + Fl_Region clip_region(); + /** \brief see fl_clip_region(Fl_Region r). */ + void clip_region(Fl_Region r); + /** \brief see fl_restore_clip(). */ + void restore_clip(); + // Images /** \brief see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L). */ virtual void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) = 0; diff --git a/FL/fl_draw.H b/FL/fl_draw.H index 3413af1c0..a17737d3f 100644 --- a/FL/fl_draw.H +++ b/FL/fl_draw.H @@ -133,18 +133,18 @@ inline int fl_not_clipped(int x, int y, int w, int h) {return fl_graphics_driver inline int fl_clip_box(int x , int y, int w, int h, int& X, int& Y, int& W, int& H) {return fl_graphics_driver->clip_box(x,y,w,h,X,Y,W,H); } /** Undoes any clobbering of clip done by your program */ -extern void fl_restore_clip(); +inline void fl_restore_clip() { fl_graphics_driver->restore_clip(); }; /** Replaces the top of the clipping stack with a clipping region of any shape. Fl_Region is an operating system specific type. \param[in] r clipping region */ -FL_EXPORT void fl_clip_region(Fl_Region r); +inline void fl_clip_region(Fl_Region r) { fl_graphics_driver->clip_region(r); }; /** returns the current clipping region. */ -extern Fl_Region fl_clip_region(); +inline Fl_Region fl_clip_region() { return fl_graphics_driver->clip_region(); }; // points: @@ -326,13 +326,27 @@ inline void fl_pie(int x, int y, int w, int h, double a1, double a2) {fl_graphic FL_EXPORT void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi // scalable drawing code (code in fl_vertex.C and fl_arc.C): -FL_EXPORT void fl_push_matrix(); -FL_EXPORT void fl_pop_matrix(); +/** + Saves the current transformation matrix on the stack. + The maximum depth of the stack is 4. + */ +inline void fl_push_matrix() { fl_graphics_driver->push_matrix(); }; +/** + Restores the current transformation matrix from the stack. + */ +inline void fl_pop_matrix() { fl_graphics_driver->pop_matrix(); }; FL_EXPORT void fl_scale(double x, double y); FL_EXPORT void fl_scale(double x); FL_EXPORT void fl_translate(double x, double y); FL_EXPORT void fl_rotate(double d); -FL_EXPORT void fl_mult_matrix(double a, double b, double c, double d, double x,double y); +/** + Concatenates another transformation onto the current one. + + \param[in] a,b,c,d,x,y transformation matrix elements such that + X' = aX + cY + x and Y' = bX +dY + y + */ +inline void fl_mult_matrix(double a, double b, double c, double d, double x,double y) + { fl_graphics_driver->mult_matrix(a, b, c, d, x, y); }; /** Starts drawing a list of points. Points are added to the list with fl_vertex() */ @@ -424,10 +438,26 @@ inline void fl_gap() {fl_graphics_driver->gap(); } */ inline void fl_end_complex_polygon() {fl_graphics_driver->end_complex_polygon(); } // get and use transformed positions: -FL_EXPORT double fl_transform_x(double x, double y); -FL_EXPORT double fl_transform_y(double x, double y); -FL_EXPORT double fl_transform_dx(double x, double y); -FL_EXPORT double fl_transform_dy(double x, double y); +/** + Transforms coordinate using the current transformation matrix. + \param[in] x,y coordinate + */ +inline double fl_transform_x(double x, double y) {return fl_graphics_driver->transform_x(x, y); }; +/** + Transform coordinate using the current transformation matrix. + \param[in] x,y coordinate + */ +inline double fl_transform_y(double x, double y) {return fl_graphics_driver->transform_y(x, y); }; +/** + Transforms distance using current transformation matrix. + \param[in] x,y coordinate + */ +inline double fl_transform_dx(double x, double y) {return fl_graphics_driver->transform_dx(x, y); }; +/** + Transforms distance using current transformation matrix. + \param[in] x,y coordinate + */ +inline double fl_transform_dy(double x, double y) {return fl_graphics_driver->transform_dy(x, y); }; /** Adds coordinate pair to the vertex list without further transformations. \param[in] xf,yf transformed coordinate diff --git a/FL/win32.H b/FL/win32.H index ac484db6b..702299b17 100644 --- a/FL/win32.H +++ b/FL/win32.H @@ -37,6 +37,7 @@ #include typedef HRGN Fl_Region; typedef HWND Window; +typedef POINT XPoint; // this part is included only when compiling the FLTK library or if requested explicitly #if defined(FL_LIBRARY) || defined(FL_INTERNALS) @@ -52,7 +53,6 @@ typedef HWND Window; #endif // some random X equivalents -typedef POINT XPoint; struct XRectangle {int x, y, width, height;}; extern Fl_Region XRectangleRegion(int x, int y, int w, int h); inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);} diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index 0a099bc85..790545703 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -51,6 +51,16 @@ void Fl_Surface_Device::set_current(void) _surface = this; } +static matrix m0 = {1, 0, 0, 1, 0, 0}; + +Fl_Graphics_Driver::Fl_Graphics_Driver() { + sptr=0; rstackptr=0; + fl_clip_state_number=0; + m = m0; + fl_matrix = &m; + p = (XPOINT *)0; +}; + // // End of "$Id$". // diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx index 135ec78a2..ffb714014 100644 --- a/src/Fl_Gl_Device_Plugin.cxx +++ b/src/Fl_Gl_Device_Plugin.cxx @@ -53,7 +53,9 @@ static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height) _XGC *save_gc = fl_gc; const int bytesperpixel = 3; #endif + Fl_Surface_Device *save_surface = Fl_Surface_Device::surface(); fl_gc = NULL; + Fl_Display_Device::display_device()->set_current(); #ifdef WIN32 Fl::check(); Fl_Window *win = (Fl_Window*)glw; @@ -89,6 +91,7 @@ static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height) #endif baseAddress); glPopClientAttrib(); + save_surface->set_current(); fl_gc = save_gc; #if defined(__APPLE__) // kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4 diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx index c317beeef..aecfe9af8 100644 --- a/src/Fl_PostScript.cxx +++ b/src/Fl_PostScript.cxx @@ -1115,9 +1115,6 @@ void Fl_PostScript_Graphics_Driver::rtl_draw(const char* str, int n, int x, int delete [] out; } -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); } diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx index ea9c10949..703dd82bd 100644 --- a/src/fl_rect.cxx +++ b/src/fl_rect.cxx @@ -507,12 +507,6 @@ void Fl_Graphics_Driver::point(int x, int y) { //////////////////////////////////////////////////////////////// -#define STACK_SIZE 10 -#define STACK_MAX (STACK_SIZE - 1) -static Fl_Region rstack[STACK_SIZE]; -static int rstackptr=0; -int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip - #if !defined(WIN32) && !defined(__APPLE__) // Missing X call: (is this the fastest way to init a 1-rectangle region?) // MSWindows equivalent exists, implemented inline in win32.H @@ -526,7 +520,7 @@ Fl_Region XRectangleRegion(int x, int y, int w, int h) { } #endif -void fl_restore_clip() { +void Fl_Graphics_Driver::restore_clip() { fl_clip_state_number++; Fl_Region r = rstack[rstackptr]; #if defined(USE_X11) @@ -554,14 +548,14 @@ void fl_restore_clip() { #endif } -void fl_clip_region(Fl_Region r) { +void Fl_Graphics_Driver::clip_region(Fl_Region r) { Fl_Region oldr = rstack[rstackptr]; if (oldr) XDestroyRegion(oldr); rstack[rstackptr] = r; fl_restore_clip(); } -Fl_Region fl_clip_region() { +Fl_Region Fl_Graphics_Driver::clip_region() { return rstack[rstackptr]; } @@ -596,14 +590,14 @@ void Fl_Graphics_Driver::push_clip(int x, int y, int w, int h) { # error unsupported platform #endif } - if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; + if (rstackptr < REGION_STACK_MAX) rstack[++rstackptr] = r; else Fl::warning("fl_push_clip: clip stack overflow!\n"); fl_restore_clip(); } // make there be no clip (used by fl_begin_offscreen() only!) void Fl_Graphics_Driver::push_no_clip() { - if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; + if (rstackptr < REGION_STACK_MAX) rstack[++rstackptr] = 0; else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); fl_restore_clip(); } diff --git a/src/fl_vertex.cxx b/src/fl_vertex.cxx index 69db92944..bb123e9a0 100644 --- a/src/fl_vertex.cxx +++ b/src/fl_vertex.cxx @@ -44,42 +44,21 @@ #include #include -struct matrix {double a, b, c, d, x, y;}; - -static matrix m = {1, 0, 0, 1, 0, 0}; - -static matrix stack[32]; -matrix * fl_matrix = &m; -static int sptr = 0; - -/** - Saves the current transformation matrix on the stack. - The maximum depth of the stack is 4. -*/ -void fl_push_matrix() { - if (sptr==32) +void Fl_Graphics_Driver::push_matrix() { + if (sptr==MATRIX_STACK_SIZE) Fl::error("fl_push_matrix(): matrix stack overflow."); else stack[sptr++] = m; } -/** - Restores the current transformation matrix from the stack. -*/ -void fl_pop_matrix() { +void Fl_Graphics_Driver::pop_matrix() { if (sptr==0) Fl::error("fl_pop_matrix(): matrix stack underflow."); else m = stack[--sptr]; } -/** - Concatenates another transformation onto the current one. - - \param[in] a,b,c,d,x,y transformation matrix elements such that - X' = aX + cY + x and Y' = bX +dY + y -*/ -void fl_mult_matrix(double a, double b, double c, double d, double x, double y) { +void Fl_Graphics_Driver::mult_matrix(double a, double b, double c, double d, double x, double y) { matrix o; o.a = a*m.a + b*m.c; o.b = a*m.b + b*m.d; @@ -124,27 +103,6 @@ void fl_rotate(double d) { } } -// typedef what the x,y fields in a point are: -#ifdef WIN32 -typedef int COORD_T; -# define XPOINT XPoint -#elif defined(__APPLE_QUARTZ__) -typedef float COORD_T; -typedef struct { float x; float y; } QPoint; -# define XPOINT QPoint -extern float fl_quartz_line_width_; -#else -typedef short COORD_T; -# define XPOINT XPoint -#endif - -static XPOINT *p = (XPOINT *)0; - -static int p_size; -static int n; -static int what; -enum {LINE, LOOP, POLYGON, POINT_}; - void Fl_Graphics_Driver::begin_points() {n = 0; what = POINT_;} void Fl_Graphics_Driver::begin_line() {n = 0; what = LINE;} @@ -153,31 +111,15 @@ void Fl_Graphics_Driver::begin_loop() {n = 0; what = LOOP;} void Fl_Graphics_Driver::begin_polygon() {n = 0; what = POLYGON;} -/** - Transforms coordinate using the current transformation matrix. - \param[in] x,y coordinate -*/ -double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;} +double Fl_Graphics_Driver::transform_x(double x, double y) {return x*m.a + y*m.c + m.x;} -/** - Transform coordinate using the current transformation matrix. - \param[in] x,y coordinate -*/ -double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;} +double Fl_Graphics_Driver::transform_y(double x, double y) {return x*m.b + y*m.d + m.y;} -/** - Transforms distance using current transformation matrix. - \param[in] x,y coordinate -*/ -double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;} +double Fl_Graphics_Driver::transform_dx(double x, double y) {return x*m.a + y*m.c;} -/** - Transforms distance using current transformation matrix. - \param[in] x,y coordinate -*/ -double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;} +double Fl_Graphics_Driver::transform_dy(double x, double y) {return x*m.b + y*m.d;} -static void fl_transformed_vertex(COORD_T x, COORD_T y) { +void Fl_Graphics_Driver::transformed_vertex0(COORD_T x, COORD_T y) { if (!n || x != p[n-1].x || y != p[n-1].y) { if (n >= p_size) { p_size = p ? 2*p_size : 16; @@ -191,14 +133,14 @@ static void fl_transformed_vertex(COORD_T x, COORD_T y) { void Fl_Graphics_Driver::transformed_vertex(double xf, double yf) { #ifdef __APPLE_QUARTZ__ - fl_transformed_vertex(COORD_T(xf), COORD_T(yf)); + transformed_vertex0(COORD_T(xf), COORD_T(yf)); #else - fl_transformed_vertex(COORD_T(rint(xf)), COORD_T(rint(yf))); + transformed_vertex0(COORD_T(rint(xf)), COORD_T(rint(yf))); #endif } 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); + transformed_vertex0(COORD_T(x*m.a + y*m.c + m.x), COORD_T(x*m.b + y*m.d + m.y)); } void Fl_Graphics_Driver::end_points() { @@ -241,7 +183,7 @@ void Fl_Graphics_Driver::end_line() { #endif } -static void fixloop() { // remove equal points from closed path +void Fl_Graphics_Driver::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--; } @@ -278,12 +220,6 @@ void Fl_Graphics_Driver::end_polygon() { #endif } -static int gap_; -#if defined(WIN32) -static int counts[20]; -static int numcount; -#endif - void Fl_Graphics_Driver::begin_complex_polygon() { fl_begin_polygon(); gap_ = 0; diff --git a/src/gl_start.cxx b/src/gl_start.cxx index 7338f4494..22674e428 100644 --- a/src/gl_start.cxx +++ b/src/gl_start.cxx @@ -46,8 +46,6 @@ #include #include "Fl_Gl_Choice.H" -extern int fl_clip_state_number; // in fl_rect.cxx - static GLContext context; static int clip_state_number=-1; static int pw, ph; @@ -89,8 +87,8 @@ void gl_start() { glOrtho(0, pw, 0, ph, -1, 1); glDrawBuffer(GL_FRONT); } - if (clip_state_number != fl_clip_state_number) { - clip_state_number = fl_clip_state_number; + if (clip_state_number != fl_graphics_driver->fl_clip_state_number) { + clip_state_number = fl_graphics_driver->fl_clip_state_number; int x, y, w, h; if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(), x, y, w, h)) {