diff options
Diffstat (limited to 'src')
53 files changed, 740 insertions, 692 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx index 7f7e2076c..8556424ed 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -3,7 +3,7 @@ // // Main event handling code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2015 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -60,6 +60,7 @@ #endif // DEBUG || DEBUG_WATCH #ifdef WIN32 +#include <FL/Fl_Graphics_Driver.H> // for fl_graphics_driver #elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - window driver and main loop #elif defined(FL_PORTING) # pragma message "FL_PORTING: implement global variables for your platform here" @@ -1618,10 +1619,10 @@ void Fl_Window::hide() { // Send a message to myself so that I'll get out of the event loop... PostMessage(ip->xid, WM_APP, 0, 0); if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc); - if (ip->xid == fl_window && fl_gc) { - fl_release_dc(fl_window, fl_gc); + if (ip->xid == fl_window && fl_graphics_driver->get_gc()) { + fl_release_dc(fl_window, (HDC)fl_graphics_driver->get_gc()); fl_window = (HWND)-1; - fl_gc = 0; + fl_graphics_driver->set_gc(0); # ifdef FLTK_USE_CAIRO if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); # endif diff --git a/src/Fl_Copy_Surface.cxx b/src/Fl_Copy_Surface.cxx index b1cc00b8b..c91695883 100644 --- a/src/Fl_Copy_Surface.cxx +++ b/src/Fl_Copy_Surface.cxx @@ -49,15 +49,15 @@ Fl_GDI_Surface_::~Fl_GDI_Surface_() { } void Fl_GDI_Surface_::translate(int x, int y) { - GetWindowOrgEx(fl_gc, origins+depth); - SetWindowOrgEx(fl_gc, origins[depth].x - x, origins[depth].y - y, NULL); + GetWindowOrgEx((HDC)driver()->get_gc(), origins+depth); + SetWindowOrgEx((HDC)driver()->get_gc(), origins[depth].x - x, origins[depth].y - y, NULL); if (depth < sizeof(origins)/sizeof(POINT)) depth++; else Fl::warning("Fl_GDI_Surface_: translate stack overflow!"); } void Fl_GDI_Surface_::untranslate() { if (depth > 0) depth--; - SetWindowOrgEx(fl_gc, origins[depth].x, origins[depth].y, NULL); + SetWindowOrgEx((HDC)driver()->get_gc(), origins[depth].x, origins[depth].y, NULL); } const char *Fl_GDI_Surface_::class_id = "Fl_GDI_Surface_"; @@ -79,11 +79,10 @@ Fl_Copy_Surface::Fl_Copy_Surface(int w, int h) : Fl_Surface_Device(NULL) helper = new Fl_Quartz_Surface_(width, height); driver(helper->driver()); prepare_copy_pdf_and_tiff(w, h); - oldgc = fl_gc; #elif defined(WIN32) helper = new Fl_GDI_Surface_(); driver(helper->driver()); - oldgc = fl_gc; + oldgc = (HDC)Fl_Surface_Device::surface()->driver()->get_gc(); // exact computation of factor from screen units to EnhMetaFile units (0.01 mm) HDC hdc = GetDC(NULL); int hmm = GetDeviceCaps(hdc, HORZSIZE); @@ -122,10 +121,9 @@ Fl_Copy_Surface::~Fl_Copy_Surface() { #ifdef __APPLE__ // PORTME: Fl_Surface_Driver - platform copy surface complete_copy_pdf_and_tiff(); - fl_gc = oldgc; delete (Fl_Quartz_Surface_*)helper; #elif defined(WIN32) - if(oldgc == fl_gc) oldgc = NULL; + if (oldgc == (HDC)Fl_Surface_Device::surface()->driver()->get_gc()) oldgc = NULL; HENHMETAFILE hmf = CloseEnhMetaFile (gc); if ( hmf != NULL ) { if ( OpenClipboard (NULL) ){ @@ -136,7 +134,7 @@ Fl_Copy_Surface::~Fl_Copy_Surface() DeleteEnhMetaFile(hmf); } DeleteDC(gc); - fl_gc = oldgc; + Fl_Surface_Device::surface()->driver()->set_gc(oldgc); delete (Fl_GDI_Surface_*)helper; #elif defined(FL_PORTING) # pragma message "FL_PORTING: free resources in destructor of Fl_Copy_Surface" @@ -166,7 +164,7 @@ void Fl_Copy_Surface::draw(Fl_Widget* widget, int delta_x, int delta_y) void Fl_Copy_Surface::set_current() { #if defined(__APPLE__) || defined(WIN32) // PORTME: Fl_Surface_Driver - platform copy surface - fl_gc = gc; + driver()->set_gc(gc); fl_window = (Window)1; Fl_Surface_Device::set_current(); #elif defined(FL_PORTING) diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index bfb60d789..67a9b4256 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -3,7 +3,7 @@ // // implementation of Fl_Device class for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2012 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -62,6 +62,7 @@ void Fl_Surface_Device::set_current(void) { fl_graphics_driver = _driver; _surface = this; + _driver->global_gc(); } Fl_Surface_Device* Fl_Surface_Device::_surface; // the current target surface of graphics operations @@ -86,7 +87,7 @@ Fl_Surface_Device *Fl_Surface_Device::default_surface() } -Fl_Display_Device *Fl_Display_Device::_display = Fl_Display_Device::display_device(); +Fl_Display_Device *Fl_Display_Device::_display; // diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx index 6403fc6fa..79e848a46 100644 --- a/src/Fl_Double_Window.cxx +++ b/src/Fl_Double_Window.cxx @@ -3,7 +3,7 @@ // // Double-buffered window code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2012 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -176,14 +176,15 @@ void Fl_Double_Window::flush(int eraseoverlay) { if (damage() & ~FL_DAMAGE_EXPOSE) { fl_clip_region(myi->region); myi->region = 0; #ifdef WIN32 - HDC _sgc = fl_gc; - fl_gc = fl_makeDC(myi->other_xid); - int save = SaveDC(fl_gc); + void* _sgc = fl_graphics_driver->get_gc(); + HDC gc = fl_makeDC(myi->other_xid); + fl_graphics_driver->set_gc(gc); + int save = SaveDC(gc); fl_restore_clip(); // duplicate region into new gc draw(); - RestoreDC(fl_gc, save); - DeleteDC(fl_gc); - fl_gc = _sgc; + RestoreDC(gc, save); + DeleteDC(gc); + fl_graphics_driver->set_gc(_sgc); //# if defined(FLTK_USE_CAIRO) //if Fl::cairo_autolink_context() Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately //# endif diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx index 76bbd0ea2..4f69b290b 100644 --- a/src/Fl_GDI_Printer.cxx +++ b/src/Fl_GDI_Printer.cxx @@ -3,7 +3,7 @@ // // Support for WIN32 printing for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2012 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -43,7 +43,6 @@ static void WIN_SetupPrinterDeviceContext(HDC prHDC) if ( !prHDC ) return; fl_window = 0; - fl_gc = prHDC; SetGraphicsMode(prHDC, GM_ADVANCED); // to allow for rotations SetMapMode(prHDC, MM_ANISOTROPIC); SetTextAlign(prHDC, TA_BASELINE|TA_LEFT); @@ -110,7 +109,7 @@ int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage) x_offset = 0; y_offset = 0; WIN_SetupPrinterDeviceContext (hPr); - gc = (void *)fl_gc; + driver()->set_gc(hPr); this->set_current(); } return err; @@ -144,9 +143,10 @@ void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h) XFORM transform; if (hPr == NULL) return; - GetWorldTransform(fl_gc, &transform); - ModifyWorldTransform(fl_gc, NULL, MWT_IDENTITY); - SetWindowOrgEx(fl_gc, 0, 0, NULL); + HDC gc = (HDC)driver()->get_gc(); + GetWorldTransform(gc, &transform); + ModifyWorldTransform(gc, NULL, MWT_IDENTITY); + SetWindowOrgEx(gc, 0, 0, NULL); physPageSize.x = GetDeviceCaps(hPr, HORZRES); physPageSize.y = GetDeviceCaps(hPr, VERTRES); @@ -164,7 +164,7 @@ void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h) *x = left_margin; *y = top_margin; origin(x_offset, y_offset); - SetWorldTransform(fl_gc, &transform); + SetWorldTransform(gc, &transform); } void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom) @@ -199,14 +199,13 @@ int Fl_System_Printer::start_page (void) printable_rect(&w, &h); origin(0, 0); fl_clip_region(0); - gc = (void *)fl_gc; } return rsult; } void Fl_System_Printer::origin (int deltax, int deltay) { - SetWindowOrgEx(fl_gc, - left_margin - deltax, - top_margin - deltay, NULL); + SetWindowOrgEx( (HDC)driver()->get_gc(), - left_margin - deltax, - top_margin - deltay, NULL); x_offset = deltax; y_offset = deltay; } @@ -215,7 +214,7 @@ void Fl_System_Printer::scale (float scalex, float scaley) { if (scaley == 0.) scaley = scalex; int w, h; - SetWindowExtEx(fl_gc, (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); + SetWindowExtEx((HDC)driver()->get_gc(), (int)(720 / scalex + 0.5), (int)(720 / scaley + 0.5), NULL); printable_rect(&w, &h); origin(0, 0); } @@ -230,7 +229,7 @@ void Fl_System_Printer::rotate (float rot_angle) mat.eM21 = - mat.eM12; mat.eM22 = mat.eM11; mat.eDx = mat.eDy = 0; - SetWorldTransform(fl_gc, &mat); + SetWorldTransform((HDC)driver()->get_gc(), &mat); } int Fl_System_Printer::end_page (void) @@ -246,7 +245,6 @@ int Fl_System_Printer::end_page (void) rsult = 1; } } - gc = NULL; return rsult; } @@ -255,19 +253,19 @@ const int translate_stack_max = 5; static int translate_stack_x[translate_stack_max]; static int translate_stack_y[translate_stack_max]; -static void do_translate(int x, int y) +static void do_translate(int x, int y, HDC gc) { XFORM tr; tr.eM11 = tr.eM22 = 1; tr.eM12 = tr.eM21 = 0; tr.eDx = (FLOAT) x; tr.eDy = (FLOAT) y; - ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY); + ModifyWorldTransform(gc, &tr, MWT_LEFTMULTIPLY); } void Fl_System_Printer::translate (int x, int y) { - do_translate(x, y); + do_translate(x, y, (HDC)driver()->get_gc()); if (translate_stack_depth < translate_stack_max) { translate_stack_x[translate_stack_depth] = x; translate_stack_y[translate_stack_depth] = y; @@ -279,7 +277,7 @@ void Fl_System_Printer::untranslate (void) { if (translate_stack_depth > 0) { translate_stack_depth--; - do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth] ); + do_translate( - translate_stack_x[translate_stack_depth], - translate_stack_y[translate_stack_depth], (HDC)driver()->get_gc() ); } } diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index 0be0ad651..25ef78a5c 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -3,7 +3,7 @@ // // OpenGL visual selection code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -21,6 +21,7 @@ # include <FL/Fl.H> # include <FL/x.H> +# include <FL/Fl_Graphics_Driver.H> # include <stdlib.h> # include "Fl_Gl_Choice.H" # include <FL/gl_draw.H> @@ -118,12 +119,13 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) { // Replacement for ChoosePixelFormat() that finds one with an overlay // if possible: - if (!fl_gc) fl_GetDC(0); + HDC gc = (HDC)fl_graphics_driver->get_gc(); + if (!gc) gc = fl_GetDC(0); int pixelformat = 0; PIXELFORMATDESCRIPTOR chosen_pfd; for (int i = 1; ; i++) { PIXELFORMATDESCRIPTOR pfd; - if (!DescribePixelFormat(fl_gc, i, sizeof(pfd), &pfd)) break; + if (!DescribePixelFormat(gc, i, sizeof(pfd), &pfd)) break; // continue if it does not satisfy our requirements: if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue; if (pfd.iPixelType != ((m&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue; diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx index df68a6000..709a1a0ad 100644 --- a/src/Fl_Gl_Device_Plugin.cxx +++ b/src/Fl_Gl_Device_Plugin.cxx @@ -3,7 +3,7 @@ // // implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2014 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -126,7 +126,8 @@ public: provider, NULL, false, kCGRenderingIntentDefault); CGColorSpaceRelease(cSpace); CGDataProviderRelease(provider); - CGContextDrawImage(fl_gc, CGRectMake(0, 0, glw->w(), glw->h()), cgimg); + CGContextDrawImage((CGContextRef)Fl_Surface_Device::surface()->driver()->get_gc(), + CGRectMake(0, 0, glw->w(), glw->h()), cgimg); CFRelease(cgimg); return 1; } else if (img->w() > glw->w()) { diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 07c9e6bf6..933c7f341 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -3,7 +3,7 @@ // // OpenGL window code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2015 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -23,6 +23,7 @@ extern int fl_gl_load_plugin; #include <FL/Fl.H> +#include <FL/Fl_Graphics_Driver.H> #include <FL/x.H> #include "Fl_Gl_Choice.H" #ifdef __APPLE__ // PORTME: platform OpenGL management @@ -210,8 +211,8 @@ void Fl_Gl_Window::make_current() { #if defined(WIN32) && USE_COLORMAP if (fl_palette) { fl_GetDC(fl_xid(this)); - SelectPalette(fl_gc, fl_palette, FALSE); - RealizePalette(fl_gc); + SelectPalette((HDC)fl_graphics_driver->get_gc(), fl_palette, FALSE); + RealizePalette((HDC)fl_graphics_driver->get_gc()); } #endif // USE_COLORMAP if (mode_ & FL_FAKE_SINGLE) { diff --git a/src/Fl_Image_Surface.cxx b/src/Fl_Image_Surface.cxx index f69d129fb..90bea2bbc 100644 --- a/src/Fl_Image_Surface.cxx +++ b/src/Fl_Image_Surface.cxx @@ -65,12 +65,6 @@ Fl_Image_Surface::Fl_Image_Surface(int w, int h, int highres) : Fl_Surface_Devic #elif defined(FL_PORTING) # pragma message "FL_PORTING: implement Fl_Image_Surface" #else - gc = 0; - if (!fl_gc) { // allows use of this class before any window is shown - fl_open_display(); - gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0); - fl_gc = gc; - } offscreen = fl_create_offscreen(w, h); helper = new Fl_Xlib_Surface_(); driver(helper->driver()); @@ -92,7 +86,6 @@ Fl_Image_Surface::~Fl_Image_Surface() { # pragma message "FL_PORTING: implement Fl_Image_Surface" #else fl_delete_offscreen(offscreen); - if (gc) { XFreeGC(fl_display, gc); fl_gc = 0; } delete (Fl_Xlib_Surface_*)helper; #endif } @@ -111,15 +104,15 @@ Fl_RGB_Image* Fl_Image_Surface::image() H = CGBitmapContextGetHeight(offscreen); Fl_X::set_high_resolution(0); data = fl_read_image(NULL, 0, 0, W, H, 0); - fl_gc = 0; #elif defined(WIN32) fl_pop_clip(); data = fl_read_image(NULL, 0, 0, width, height, 0); - RestoreDC(fl_gc, _savedc); - DeleteDC(fl_gc); + HDC gc = (HDC)driver()->get_gc(); + RestoreDC(gc, _savedc); + DeleteDC(gc); _ss->set_current(); fl_window=_sw; - fl_gc = _sgc; + _ss->driver()->set_gc(_sgc); #elif defined(FL_PORTING) # pragma message "FL_PORTING: implement Fl_Image_Surface" #else @@ -163,16 +156,18 @@ void Fl_Image_Surface::draw(Fl_Widget *widget, int delta_x, int delta_y) void Fl_Image_Surface::set_current() { #if defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform image surface - fl_gc = offscreen; fl_window = 0; + driver()->set_gc(offscreen); + fl_window = 0; Fl_Surface_Device::set_current(); Fl_X::set_high_resolution( CGBitmapContextGetWidth(offscreen) > width ); #elif defined(WIN32) - _sgc=fl_gc; - _sw=fl_window; + _sw = fl_window; _ss = Fl_Surface_Device::surface(); + _sgc = (HDC)_ss->driver()->get_gc(); + HDC gc = fl_makeDC(offscreen); Fl_Surface_Device::set_current(); - fl_gc = fl_makeDC(offscreen); - _savedc = SaveDC(fl_gc); + driver()->set_gc(gc); + _savedc = SaveDC(gc); fl_window=(HWND)offscreen; fl_push_no_clip(); #elif defined(FL_PORTING) @@ -192,16 +187,17 @@ Fl_Quartz_Flipped_Surface_::Fl_Quartz_Flipped_Surface_(int w, int h) : Fl_Quartz } void Fl_Quartz_Flipped_Surface_::translate(int x, int y) { - CGContextRestoreGState(fl_gc); - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, x, -y); - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, 0, height); - CGContextScaleCTM(fl_gc, 1.0f, -1.0f); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, x, -y); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, 0, height); + CGContextScaleCTM(gc, 1.0f, -1.0f); } void Fl_Quartz_Flipped_Surface_::untranslate() { - CGContextRestoreGState(fl_gc); + CGContextRestoreGState((CGContextRef)driver()->get_gc()); } const char *Fl_Quartz_Flipped_Surface_::class_id = "Fl_Quartz_Flipped_Surface_"; diff --git a/src/Fl_Menu_Window.cxx b/src/Fl_Menu_Window.cxx index 02bee699e..f170cb7fa 100644 --- a/src/Fl_Menu_Window.cxx +++ b/src/Fl_Menu_Window.cxx @@ -3,7 +3,7 @@ // // Menu window code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -35,7 +35,6 @@ extern XVisualInfo *fl_find_overlay_visual(); extern XVisualInfo *fl_overlay_visual; extern Colormap fl_overlay_colormap; extern unsigned long fl_transparent_pixel; -static GC gc; // the GC used by all X windows extern uchar fl_overlay; // changes how fl_color(x) works #endif @@ -59,13 +58,10 @@ void Fl_Menu_Window::flush() { if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;} Fl_X *myi = Fl_X::i(this); fl_window = myi->xid; - if (!gc) { - gc = XCreateGC(fl_display, myi->xid, 0, 0); # if defined(FLTK_USE_CAIRO) - if(Fl::autolink_context()) Fl::cairo_make_current(gc); // capture gc changes automatically to update the cairo context adequately + // capture gc changes automatically to update the cairo context adequately + if(Fl::autolink_context()) Fl::cairo_make_current(fl_graphics_driver->get_gc()); # endif - } - fl_gc = gc; fl_overlay = 1; fl_clip_region(myi->region); myi->region = 0; current_ = this; draw(); @@ -78,7 +74,7 @@ void Fl_Menu_Window::flush() { /** Erases the window, does nothing if HAVE_OVERLAY is not defined config.h */ void Fl_Menu_Window::erase() { #if HAVE_OVERLAY - if (!gc || !shown()) return; + if (!shown()) return; //XSetForeground(fl_display, gc, 0); //XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h()); XClearWindow(fl_display, fl_xid(this)); diff --git a/src/Fl_Overlay_Window.cxx b/src/Fl_Overlay_Window.cxx index 65ab3beaa..c5257abd7 100644 --- a/src/Fl_Overlay_Window.cxx +++ b/src/Fl_Overlay_Window.cxx @@ -3,7 +3,7 @@ // // Overlay window code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -87,7 +87,6 @@ extern XVisualInfo *fl_find_overlay_visual(); extern XVisualInfo *fl_overlay_visual; extern Colormap fl_overlay_colormap; extern unsigned long fl_transparent_pixel; -static GC gc; // the GC used by all X windows extern uchar fl_overlay; // changes how fl_color(x) works class _Fl_Overlay : public Fl_Window { @@ -116,10 +115,6 @@ void _Fl_Overlay::show() { void _Fl_Overlay::flush() { fl_window = fl_xid(this); - if (!gc) { - gc = XCreateGC(fl_display, fl_xid(this), 0, 0); - } - fl_gc = gc; #if defined(FLTK_USE_CAIRO) if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately #endif diff --git a/src/Fl_Paged_Device.cxx b/src/Fl_Paged_Device.cxx index 76637d787..8fadd7b73 100644 --- a/src/Fl_Paged_Device.cxx +++ b/src/Fl_Paged_Device.cxx @@ -64,8 +64,8 @@ void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y) if (is_window && !widget->window()) { fl_push_clip(0, 0, widget->w(), widget->h() ); #ifdef __APPLE__ // for Mac OS X 10.6 and above, make window with rounded bottom corners - if ( fl_mac_os_version >= 100600 && driver()->class_name() == Fl_Quartz_Graphics_Driver::class_id ) { - Fl_X::clip_to_rounded_corners(fl_gc, widget->w(), widget->h()); + if ( fl_mac_os_version >= 100600 && driver()->has_feature(Fl_Graphics_Driver::NATIVE) ) { + Fl_X::clip_to_rounded_corners((CGContextRef)driver()->get_gc(), widget->w(), widget->h()); } #endif } @@ -137,7 +137,6 @@ void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int 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; @@ -150,8 +149,9 @@ void Fl_Paged_Device::print_window_part(Fl_Window *win, int x, int y, int w, int fl_draw_image(image_data, delta_x, delta_y, w, h, 3); delete[] image_data; #ifdef WIN32 - fl_gc = GetDC(fl_xid(win)); - ReleaseDC(fl_xid(win), fl_gc); + HDC gc = GetDC(fl_xid(win)); + fl_graphics_driver->set_gc(gc); + ReleaseDC(fl_xid(win), gc); #endif } diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx index df5a52fdf..58a1bef7e 100644 --- a/src/Fl_PostScript.cxx +++ b/src/Fl_PostScript.cxx @@ -3,7 +3,7 @@ // // PostScript device support for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2015 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -61,9 +61,6 @@ Fl_PostScript_Graphics_Driver::~Fl_PostScript_Graphics_Driver() { */ Fl_PostScript_File_Device::Fl_PostScript_File_Device(void) { -#ifdef __APPLE__ // PORTME: Fl_Surface_Driver - platform PostScript - gc = fl_gc; // the display context is used by fl_text_extents() -#endif Fl_Surface_Device::driver( new Fl_PostScript_Graphics_Driver() ); } diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx index 55f95cd6d..92ddbfafc 100644 --- a/src/Fl_Printer.cxx +++ b/src/Fl_Printer.cxx @@ -127,15 +127,6 @@ const char *Fl_PostScript_Printer::class_id = Fl_Printer::class_id; #endif #if defined(__APPLE__) || defined(WIN32) // PORTME: Fl_Screen_Driver - platform printing -void Fl_System_Printer::set_current(void) -{ -#ifdef __APPLE__ // PORTME: Fl_Screen_Driver - platform printing - fl_gc = (CGContextRef)gc; -#elif defined(WIN32) - fl_gc = (HDC)gc; -#endif - this->Fl_Surface_Device::set_current(); -} void Fl_System_Printer::origin(int *x, int *y) { diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm index 866ff60b1..65ee90055 100644 --- a/src/Fl_Quartz_Printer.mm +++ b/src/Fl_Quartz_Printer.mm @@ -3,7 +3,7 @@ // // Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2014 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -40,14 +40,13 @@ typedef OSStatus CFStringRef graphicsContextType, void ** graphicsContext); -extern void fl_quartz_restore_line_style_(); +extern void fl_quartz_restore_line_style_(CGContextRef gc); Fl_System_Printer::Fl_System_Printer(void) { x_offset = 0; y_offset = 0; scale_x = scale_y = 1.; - gc = 0; driver(new Fl_Quartz_Printer_Graphics_Driver); } @@ -189,13 +188,14 @@ void Fl_System_Printer::origin(int x, int y) { x_offset = x; y_offset = y; - CGContextRestoreGState(fl_gc); - CGContextRestoreGState(fl_gc); - CGContextSaveGState(fl_gc); - CGContextScaleCTM(fl_gc, scale_x, scale_y); - CGContextTranslateCTM(fl_gc, x, y); - CGContextRotateCTM(fl_gc, angle); - CGContextSaveGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextTranslateCTM(gc, x, y); + CGContextRotateCTM(gc, angle); + CGContextSaveGState(gc); } void Fl_System_Printer::scale (float s_x, float s_y) @@ -203,46 +203,51 @@ void Fl_System_Printer::scale (float s_x, float s_y) if (s_y == 0.) s_y = s_x; scale_x = s_x; scale_y = s_y; - CGContextRestoreGState(fl_gc); - CGContextRestoreGState(fl_gc); - CGContextSaveGState(fl_gc); - CGContextScaleCTM(fl_gc, scale_x, scale_y); - CGContextRotateCTM(fl_gc, angle); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextRotateCTM(gc, angle); x_offset = y_offset = 0; - CGContextSaveGState(fl_gc); + CGContextSaveGState(gc); } void Fl_System_Printer::rotate (float rot_angle) { angle = - rot_angle * M_PI / 180.; - CGContextRestoreGState(fl_gc); - CGContextRestoreGState(fl_gc); - CGContextSaveGState(fl_gc); - CGContextScaleCTM(fl_gc, scale_x, scale_y); - CGContextTranslateCTM(fl_gc, x_offset, y_offset); - CGContextRotateCTM(fl_gc, angle); - CGContextSaveGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); + CGContextSaveGState(gc); + CGContextScaleCTM(gc, scale_x, scale_y); + CGContextTranslateCTM(gc, x_offset, y_offset); + CGContextRotateCTM(gc, angle); + CGContextSaveGState(gc); } void Fl_System_Printer::translate(int x, int y) { - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, x, y ); - CGContextSaveGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, x, y ); + CGContextSaveGState(gc); } void Fl_System_Printer::untranslate(void) { - CGContextRestoreGState(fl_gc); - CGContextRestoreGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); } int Fl_System_Printer::start_page (void) { OSStatus status = PMSessionBeginPageNoDialog(printSession, pageFormat, NULL); + CGContextRef gc; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if ( &PMSessionGetCGGraphicsContext != NULL ) { - status = PMSessionGetCGGraphicsContext(printSession, &fl_gc); + status = PMSessionGetCGGraphicsContext(printSession, &gc); } else #endif @@ -250,9 +255,10 @@ int Fl_System_Printer::start_page (void) #if ! __LP64_ PMSessionGetGraphicsContext_type PMSessionGetGraphicsContext = (PMSessionGetGraphicsContext_type)Fl_X::get_carbon_function("PMSessionGetGraphicsContext"); - status = PMSessionGetGraphicsContext(printSession, NULL, (void **)&fl_gc); + status = PMSessionGetGraphicsContext(printSession, NULL, (void **)&gc); #endif } + driver()->set_gc(gc); PMRect pmRect; float win_scale_x, win_scale_y; @@ -271,26 +277,26 @@ int Fl_System_Printer::start_page (void) scale_x = scale_y = 1; win_scale_x = win_scale_y = 1; if(orientation == kPMPortrait) - CGContextTranslateCTM(fl_gc, margins.left, margins.bottom + h); + CGContextTranslateCTM(gc, margins.left, margins.bottom + h); else - CGContextTranslateCTM(fl_gc, margins.top, margins.right + h); - CGContextScaleCTM(fl_gc, win_scale_x, - win_scale_y); - fl_quartz_restore_line_style_(); - CGContextSetShouldAntialias(fl_gc, false); - CGContextSaveGState(fl_gc); - CGContextSaveGState(fl_gc); + CGContextTranslateCTM(gc, margins.top, margins.right + h); + CGContextScaleCTM(gc, win_scale_x, - win_scale_y); + fl_quartz_restore_line_style_(gc); + CGContextSetShouldAntialias(gc, false); + CGContextSaveGState(gc); + CGContextSaveGState(gc); fl_line_style(FL_SOLID); fl_window = (Window)1; // TODO: something better fl_clip_region(0); - if( status == noErr) gc = fl_gc; return status != noErr; } int Fl_System_Printer::end_page (void) { - CGContextFlush(fl_gc); - CGContextRestoreGState(fl_gc); - CGContextRestoreGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextFlush(gc); + CGContextRestoreGState(gc); + CGContextRestoreGState(gc); OSStatus status = PMSessionEndPageNoDialog(printSession); gc = NULL; return status != noErr; @@ -313,7 +319,7 @@ void Fl_System_Printer::end_job (void) } #endif Fl_Display_Device::display_device()->set_current(); - fl_gc = 0; + driver()->set_gc(0); Fl_Window *w = Fl::first_window(); if (w) w->show(); } @@ -325,7 +331,6 @@ void Fl_System_Printer::print_window_part(Fl_Window *win, int x, int y, int w, i Fl_Display_Device::display_device()->set_current(); Fl_Window *save_front = Fl::first_window(); win->show(); - fl_gc = NULL; Fl::check(); CGImageRef img = Fl_X::CGImage_from_window_rect(win, x, y, w, h); if (save_front != win) save_front->show(); diff --git a/src/Fl_Window_shape.cxx b/src/Fl_Window_shape.cxx index 4e71197f3..5dee92238 100644 --- a/src/Fl_Window_shape.cxx +++ b/src/Fl_Window_shape.cxx @@ -3,7 +3,7 @@ // // Implementation of Fl_Window::shape(Fl_Image*) for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2015 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -342,12 +342,15 @@ void Fl_Window::shape(const Fl_Image* img) { } void Fl_Window::draw() { +#if defined(__APPLE__) + CGContextRef gc = (CGContextRef)Fl_Display_Device::display_device()->driver()->get_gc(); +#endif if (shape_data_) { # if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if (shape_data_->mask && (&CGContextClipToMask != NULL)) { - CGContextClipToMask(fl_gc, CGRectMake(0,0,w(),h()), shape_data_->mask); // requires Mac OS 10.4 + CGContextClipToMask(gc, CGRectMake(0,0,w(),h()), shape_data_->mask); // requires Mac OS 10.4 } - CGContextSaveGState(fl_gc); + CGContextSaveGState(gc); #elif defined(WIN32) if ((shape_data_->lw_ != w() || shape_data_->lh_ != h()) && shape_data_->shape_) { // size of window has changed since last time @@ -394,7 +397,7 @@ void Fl_Window::draw() { #ifdef __APPLE_QUARTZ__ // PORTME: Fl_Window_Driver - platform window driver // on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right // corner. This code draws a little ribbed triangle for dragging. - if (fl_mac_os_version < 100700 && fl_gc && !parent() && resizable() && + if (fl_mac_os_version < 100700 && gc && !parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { int dx = Fl::box_dw(box())-Fl::box_dx(box()); int dy = Fl::box_dh(box())-Fl::box_dy(box()); @@ -415,7 +418,7 @@ void Fl_Window::draw() { } #endif # if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (shape_data_) CGContextRestoreGState(fl_gc); + if (shape_data_) CGContextRestoreGState(gc); # endif # if defined(FLTK_USE_CAIRO) diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 02a5b4a35..f4d6fd094 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -89,7 +89,6 @@ class Fl_Widget *fl_selection_requestor; int fl_mac_os_version = Fl_X::calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4) // public variables -CGContextRef fl_gc = 0; void *fl_capture = 0; // (NSWindow*) we need this to compensate for a missing(?) mouse capture bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state //int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR @@ -864,9 +863,7 @@ double fl_mac_flush_and_wait(double time_to_wait) { if (Fl::idle && !in_idle) // 'idle' may have been set within flush() time_to_wait = 0.0; double retval = fl_wait(time_to_wait); - if (fl_gc) { - Fl_X::q_release_context(); - } + Fl_X::q_release_context(); [pool release]; return retval; } @@ -3279,21 +3276,21 @@ void Fl_Window::make_current() #endif nsgc = through_Fl_X_flush ? [NSGraphicsContext currentContext] : [NSGraphicsContext graphicsContextWithWindow:fl_window]; i->gc = (CGContextRef)[nsgc graphicsPort]; - fl_gc = i->gc; - CGContextSaveGState(fl_gc); // native context + Fl_Display_Device::display_device()->driver()->set_gc(i->gc); + CGContextSaveGState(i->gc); // native context // antialiasing must be deactivated because it applies to rectangles too // and escapes even clipping!!! // it gets activated when needed (e.g., draw text) - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(i->gc, false); CGFloat hgt = [[fl_window contentView] frame].size.height; - CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); - CGContextScaleCTM(fl_gc, 1.0f, -1.0f); // now 0,0 is top-left point of the window + CGContextTranslateCTM(i->gc, 0.5, hgt-0.5f); + CGContextScaleCTM(i->gc, 1.0f, -1.0f); // now 0,0 is top-left point of the window // for subwindows, limit drawing to inside of parent window // half pixel offset is necessary for clipping as done by fl_cgrectmake_cocoa() - if (i->subRect()) CGContextClipToRect(fl_gc, CGRectOffset(*(i->subRect()), -0.5, -0.5)); + if (i->subRect()) CGContextClipToRect(i->gc, CGRectOffset(*(i->subRect()), -0.5, -0.5)); // this is the context with origin at top left of (sub)window - CGContextSaveGState(fl_gc); + CGContextSaveGState(i->gc); #if defined(FLTK_USE_CAIRO) if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately #endif @@ -3307,13 +3304,14 @@ void Fl_Window::make_current() // Give the Quartz context back to the system void Fl_X::q_release_context(Fl_X *x) { - if (x && x->gc!=fl_gc) return; - if (!fl_gc) return; - CGContextRestoreGState(fl_gc); // match the CGContextSaveGState's of make_current - CGContextRestoreGState(fl_gc); + CGContextRef gc = (CGContextRef)Fl_Display_Device::display_device()->driver()->get_gc(); + if (x && x->gc!=gc) return; + if (!gc) return; + CGContextRestoreGState(gc); // match the CGContextSaveGState's of make_current + CGContextRestoreGState(gc); Fl_X::set_high_resolution(false); - CGContextFlush(fl_gc); - fl_gc = 0; + CGContextFlush(gc); + Fl_Display_Device::display_device()->driver()->set_gc(0); #if defined(FLTK_USE_CAIRO) if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately #endif @@ -4380,11 +4378,12 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset) CALayer *layer = get_titlebar_layer(win); if (layer) { // if title bar uses a layer if (to_quartz) { // to Quartz printer - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, x_offset - 0.5, y_offset + bt - 0.5); - CGContextScaleCTM(fl_gc, 1, -1); - draw_layer_to_context(layer, fl_gc, win->w(), bt); - CGContextRestoreGState(fl_gc); + CGContextRef gc = (CGContextRef)driver()->get_gc(); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, x_offset - 0.5, y_offset + bt - 0.5); + CGContextScaleCTM(gc, 1, -1); + draw_layer_to_context(layer, gc, win->w(), bt); + CGContextRestoreGState(gc); } else { CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB (); @@ -4411,7 +4410,6 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset) const char *title = win->label(); win->label(""); // temporarily set a void window title win->show(); - fl_gc = NULL; Fl::check(); // capture the window title bar with no title Fl_Shared_Image *top, *left, *bottom, *right; @@ -4426,7 +4424,7 @@ void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset) if (fl_mac_os_version >= 100400 && to_quartz) { // use Cocoa string drawing with exact title bar font // the exact font is LucidaGrande 13 pts (and HelveticaNeueDeskInterface-Regular with 10.10) NSGraphicsContext *current = [NSGraphicsContext currentContext]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:fl_gc flipped:YES]];//10.4 + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:driver()->get_gc() flipped:YES]];//10.4 NSDictionary *attr = [NSDictionary dictionaryWithObject:[NSFont titleBarFontOfSize:0] forKey:NSFontAttributeName]; NSString *title_s = [fl_xid(win) title]; diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 1310c0a8d..057bc5362 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -740,7 +740,7 @@ void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) { else if (lpBI->bmiHeader.biClrUsed > 0) pDIBBits = (void*)(lpBI->bmiColors + lpBI->bmiHeader.biClrUsed); Fl_Offscreen off = fl_create_offscreen(width, height); fl_begin_offscreen(off); - SetDIBitsToDevice(fl_gc, 0, 0, width, height, 0, 0, 0, height, pDIBBits, lpBI, DIB_RGB_COLORS); + SetDIBitsToDevice((HDC)fl_graphics_driver->get_gc(), 0, 0, width, height, 0, 0, 0, height, pDIBBits, lpBI, DIB_RGB_COLORS); rgb = fl_read_image(NULL, 0, 0, width, height); depth = 3; fl_end_offscreen(); @@ -766,7 +766,7 @@ void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) { Fl_Offscreen off = fl_create_offscreen(width, height); fl_begin_offscreen(off); fl_color(FL_WHITE); fl_rectf(0,0,width, height); // draw white background - PlayEnhMetaFile(fl_gc, (HENHMETAFILE)h, &rect); // draw metafile to offscreen buffer + PlayEnhMetaFile((HDC)fl_graphics_driver->get_gc(), (HENHMETAFILE)h, &rect); // draw metafile to offscreen buffer rgb = fl_read_image(NULL, 0, 0, width, height); // read pixels from offscreen buffer depth = 3; fl_end_offscreen(); @@ -1426,8 +1426,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar break; case WM_PALETTECHANGED: - fl_GetDC(hWnd); - if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc); + //fl_GetDC(hWnd); + //if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc); + if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_GetDC(hWnd)); break; case WM_CREATE : @@ -2521,25 +2522,26 @@ void Fl_Window::show() { Fl_Window *Fl_Window::current_; // the current context -HDC fl_gc = 0; // the current window handle, initially set to -1 so we can correctly // allocate fl_GetDC(0) HWND fl_window = NULL; // Here we ensure only one GetDC is ever in place. HDC fl_GetDC(HWND w) { - if (fl_gc) { - if (w == fl_window && fl_window != NULL) return fl_gc; - if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC - } - fl_gc = GetDC(w); - fl_save_dc(w, fl_gc); + HDC gc = (HDC)Fl_Display_Device::display_device()->driver()->get_gc(); + if (gc) { + if (w == fl_window && fl_window != NULL) return gc; + if (fl_window) fl_release_dc(fl_window, gc); // ReleaseDC + } + gc = GetDC(w); + Fl_Display_Device::display_device()->driver()->set_gc(gc); + fl_save_dc(w, gc); fl_window = w; // calling GetDC seems to always reset these: (?) - SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT); - SetBkMode(fl_gc, TRANSPARENT); + SetTextAlign(gc, TA_BASELINE|TA_LEFT); + SetBkMode(gc, TRANSPARENT); - return fl_gc; + return gc; } // make X drawing go into this window (called by subclass flush() impl.) @@ -2660,7 +2662,7 @@ Fl_Region XRectangleRegion(int x, int y, int w, int h) { if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) 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); + LPtoDP((HDC)fl_graphics_driver->get_gc(), pt, 4); return CreatePolygonRgn(pt, 4, ALTERNATE); } @@ -2721,14 +2723,13 @@ void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Im int wsides, hbottom, bt; RECT r = border_width_title_bar_height(this, wsides, hbottom, bt); int htop = bt + hbottom; - HDC save_gc = fl_gc; - Window save_win = fl_window; Fl_Surface_Device *previous = Fl_Surface_Device::surface(); + Window save_win = fl_window; Fl_Display_Device::display_device()->set_current(); show(); Fl::check(); - make_current(); - fl_gc = GetDC(NULL); // get the screen device context + void* save_gc = fl_graphics_driver->get_gc(); + fl_graphics_driver->set_gc(GetDC(NULL)); int ww = w() + 2 * wsides; // capture the 4 window sides from screen fl_window = NULL; // force use of read_win_rectangle() by fl_read_image() @@ -2753,9 +2754,9 @@ void Fl_Window::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Shared_Im r_bottom->alloc_array = 1; bottom = Fl_Shared_Image::get(r_bottom); } - ReleaseDC(NULL, fl_gc); + ReleaseDC(NULL, (HDC)fl_graphics_driver->get_gc()); fl_window = save_win; - fl_gc = save_gc; + fl_graphics_driver->set_gc(save_gc); previous->Fl_Surface_Device::set_current(); } diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 16f3816b5..23b75c44a 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -2919,18 +2919,14 @@ preparePrintFront(); Window fl_window; Fl_Window *Fl_Window::current_; -GC fl_gc; // make X drawing go into this window (called by subclass flush() impl.) void Fl_Window::make_current() { - static GC gc; // the GC used by all X windows if (!shown()) { fl_alert("Fl_Window::make_current(), but window is not shown()."); Fl::fatal("Fl_Window::make_current(), but window is not shown()."); } - if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0); fl_window = i->xid; - fl_gc = gc; current_ = this; fl_clip_region(0); diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index f11672de7..ca6de3f60 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -21,6 +21,7 @@ #include "Fl_Cocoa_Screen_Driver.h" #include <FL/Fl.H> #include <FL/x.H> +#include <FL/Fl_Graphics_Driver.H> #include <FL/fl_ask.H> #include <stdio.h> @@ -120,8 +121,9 @@ void Fl_Cocoa_Screen_Driver::beep(int type) { void Fl_Cocoa_Screen_Driver::flush() { - if (fl_gc) - CGContextFlush(fl_gc); + CGContextRef gc = (CGContextRef)Fl_Display_Device::display_device()->driver()->get_gc(); + if (gc) + CGContextFlush(gc); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index 3bc9fedbe..74cd6a69d 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx @@ -27,6 +27,17 @@ const char *Fl_GDI_Graphics_Driver::class_id = "Fl_GDI_Graphics_Driver"; // FIXME: move to printer graphics driver const char *Fl_GDI_Printer_Graphics_Driver::class_id = "Fl_GDI_Printer_Graphics_Driver"; +/* Reference to the current device context + For back-compatibility only. The preferred procedure to get this reference is + Fl_Surface_Device::surface()->driver()->get_gc(). + */ +HDC fl_gc = 0; + +void Fl_Graphics_Driver::global_gc() +{ + fl_gc = (HDC)get_gc(); +} + /* * By linking this module, the following static method will instatiate the * MSWindows GDI Graphics driver as the main display driver. @@ -87,7 +98,7 @@ char Fl_GDI_Graphics_Driver::can_do_alpha_blending() { } HDC fl_makeDC(HBITMAP bitmap) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC((HDC)fl_graphics_driver->get_gc()); SetTextAlign(new_gc, TA_BASELINE|TA_LEFT); SetBkMode(new_gc, TRANSPARENT); #if USE_COLORMAP @@ -98,26 +109,26 @@ HDC fl_makeDC(HBITMAP bitmap) { } void Fl_GDI_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC(gc); int save = SaveDC(new_gc); SelectObject(new_gc, bitmap); - BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + BitBlt(gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); RestoreDC(new_gc, save); DeleteDC(new_gc); } void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC(gc); int save = SaveDC(new_gc); SelectObject(new_gc, bitmap); BOOL alpha_ok = 0; // first try to alpha blend if ( can_do_alpha_blending() ) { - alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); + alpha_ok = fl_alpha_blend(gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); } // if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1 if (!alpha_ok) { - BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + BitBlt(gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); } RestoreDC(new_gc, save); DeleteDC(new_gc); diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.h b/src/drivers/GDI/Fl_GDI_Graphics_Driver.h index 2dbdbe430..722c7410a 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.h +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.h @@ -35,6 +35,7 @@ */ class FL_EXPORT Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver { protected: + HDC gc; int numcount; int counts[20]; public: @@ -42,6 +43,8 @@ public: const char *class_name() {return class_id;}; virtual int has_feature(driver_feature mask) { return mask & NATIVE; } char can_do_alpha_blending(); + virtual void set_gc(void *ctxt) {gc = (HDC)ctxt;} + virtual void *get_gc() {return gc;} // --- bitmap stuff Fl_Bitmask create_bitmask(int w, int h, const uchar *array); diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx index 976c6f5c3..de8729d74 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx @@ -41,9 +41,9 @@ void Fl_GDI_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) { int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); if (fabs(a1 - a2) < 90) { - if (xa == xb && ya == yb) SetPixel(fl_gc, xa, ya, fl_RGB()); - else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); - } else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + if (xa == xb && ya == yb) SetPixel(gc, xa, ya, fl_RGB()); + else Arc(gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Arc(gc, x, y, x+w, y+h, xa, ya, xb, yb); } void Fl_GDI_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { @@ -53,14 +53,14 @@ void Fl_GDI_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { int ya = y+h/2-int(h*sin(a1/180.0*M_PI)); int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); - SelectObject(fl_gc, fl_brush()); + SelectObject(gc, fl_brush()); if (fabs(a1 - a2) < 90) { if (xa == xb && ya == yb) { - MoveToEx(fl_gc, x+w/2, y+h/2, 0L); - LineTo(fl_gc, xa, ya); - SetPixel(fl_gc, xa, ya, fl_RGB()); - } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); - } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + MoveToEx(gc, x+w/2, y+h/2, 0L); + LineTo(gc, xa, ya); + SetPixel(gc, xa, ya, fl_RGB()); + } else Pie(gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Pie(gc, x, y, x+w, y+h, xa, ya, xb, yb); } #endif // FL_CFG_GFX_GDI_ARCI_CXX diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx index ab7bf9332..8216d14ca 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_color.cxx @@ -53,11 +53,11 @@ void fl_cleanup_pens(void) { void fl_save_pen(void) { if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); - savepen = (HPEN)SelectObject(fl_gc, tmppen); + savepen = (HPEN)SelectObject((HDC)fl_graphics_driver->get_gc(), tmppen); } void fl_restore_pen(void) { - if (savepen) SelectObject(fl_gc, savepen); + if (savepen) SelectObject((HDC)fl_graphics_driver->get_gc(), savepen); DeleteObject(tmppen); tmppen = 0; savepen = 0; @@ -65,9 +65,10 @@ void fl_restore_pen(void) { static void clear_xmap(Fl_XMap& xmap) { if (xmap.pen) { + HDC gc = (HDC)fl_graphics_driver->get_gc(); HGDIOBJ tmppen = GetStockObject(BLACK_PEN); - HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc - if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete + HGDIOBJ oldpen = SelectObject(gc, tmppen); // Push out the current pen of the gc + if(oldpen != xmap.pen) SelectObject(gc, oldpen); // Put it back if it is not the one we are about to delete DeleteObject((HGDIOBJ)(xmap.pen)); xmap.pen = 0; xmap.brush = -1; @@ -77,8 +78,9 @@ static void clear_xmap(Fl_XMap& xmap) { static void set_xmap(Fl_XMap& xmap, COLORREF c) { xmap.rgb = c; if (xmap.pen) { - HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one - if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back + HDC gc = (HDC)fl_graphics_driver->get_gc(); + HGDIOBJ oldpen = SelectObject(gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one + if (oldpen != xmap.pen)SelectObject(gc,oldpen); // if old one not xmap.pen, need to put it back DeleteObject(xmap.pen); // delete pen } xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen @@ -105,7 +107,7 @@ void Fl_GDI_Graphics_Driver::color(Fl_Color i) { #endif } fl_current_xmap = ⟼ - SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); + SelectObject(gc, (HGDIOBJ)(xmap.pen)); } } @@ -118,7 +120,7 @@ void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) { set_xmap(xmap, c); } fl_current_xmap = ⟼ - SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); + SelectObject(gc, (HGDIOBJ)(xmap.pen)); } HBRUSH fl_brush() { @@ -127,6 +129,7 @@ HBRUSH fl_brush() { HBRUSH fl_brush_action(int action) { Fl_XMap *xmap = fl_current_xmap; + HDC gc = (HDC)fl_graphics_driver->get_gc(); // Wonko: we use some statistics to cache only a limited number // of brushes: #define FL_N_BRUSH 16 @@ -137,7 +140,7 @@ HBRUSH fl_brush_action(int action) { } brushes[FL_N_BRUSH]; if (action) { - SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object + SelectObject(gc, GetStockObject(BLACK_BRUSH)); // Load stock object for (int i=0; i<FL_N_BRUSH; i++) { if (brushes[i].brush) DeleteObject(brushes[i].brush); // delete all brushes in array @@ -168,8 +171,8 @@ HBRUSH fl_brush_action(int action) { } i = imin; HGDIOBJ tmpbrush = GetStockObject(BLACK_BRUSH); // get a stock brush - HGDIOBJ oldbrush = SelectObject(fl_gc,tmpbrush); // load in into current context - if (oldbrush != brushes[i].brush) SelectObject(fl_gc,oldbrush); // reload old one + HGDIOBJ oldbrush = SelectObject(gc,tmpbrush); // load in into current context + if (oldbrush != brushes[i].brush) SelectObject(gc,oldbrush); // reload old one DeleteObject(brushes[i].brush); // delete the one in list brushes[i].brush = NULL; brushes[i].backref->brush = -1; @@ -203,11 +206,11 @@ HPALETTE fl_select_palette(void) { static char beenhere; + HDC gc = (HDC)fl_graphics_driver->get_gc(); if (!beenhere) { beenhere = 1; - //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; - int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); + int nColors = GetDeviceCaps(gc, SIZEPALETTE); if (nColors <= 0 || nColors > 256) return NULL; // this will try to work on < 256 color screens, but will probably // come out quite badly. @@ -232,8 +235,8 @@ fl_select_palette(void) fl_palette = CreatePalette(pPal); } if (fl_palette) { - SelectPalette(fl_gc, fl_palette, FALSE); - RealizePalette(fl_gc); + SelectPalette(gc, fl_palette, FALSE); + RealizePalette(gc); } return fl_palette; } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx index 07d9fbdba..e31f38234 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx @@ -113,10 +113,11 @@ enumcbw(CONST LOGFONTW *lpelf, } /* enumcbw */ Fl_Font Fl::set_fonts(const char* xstarname) { + HDC gc = (HDC)fl_graphics_driver->get_gc(); if (fl_free_font == FL_FREE_FONT) {// if not already been called - if (!fl_gc) fl_GetDC(0); + if (!gc) gc = fl_GetDC(0); - EnumFontFamiliesW(fl_gc, NULL, (FONTENUMPROCW)enumcbw, xstarname != 0); + EnumFontFamiliesW(gc, NULL, (FONTENUMPROCW)enumcbw, xstarname != 0); } return (Fl_Font)fl_free_font; @@ -168,8 +169,9 @@ Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { Fl_Fontdesc *s = fl_fonts+fnum; if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 - if (!fl_gc) fl_GetDC(0); - cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY); + HDC gc = (HDC)fl_graphics_driver->get_gc(); + if (!gc) gc = fl_GetDC(0); + cyPerInch = GetDeviceCaps(gc, LOGPIXELSY); if (cyPerInch < 1) cyPerInch = 1; // int l = fl_utf_nb_char((unsigned char*)s->name+1, strlen(s->name+1)); @@ -181,7 +183,7 @@ Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { unsigned short *b = (unsigned short*) malloc((l + 1) * sizeof(short)); l = fl_utf8toUtf16(nm, (unsigned) len, b, (l+1)); // Now do the conversion b[l] = 0; - EnumFontFamiliesW(fl_gc, (WCHAR*)b, (FONTENUMPROCW)EnumSizeCbW, 0); + EnumFontFamiliesW(gc, (WCHAR*)b, (FONTENUMPROCW)EnumSizeCbW, 0); free(b); sizep = sizes; @@ -242,9 +244,10 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize) { name // pointer to typeface name string ); angle = fl_angle_; - if (!fl_gc) fl_GetDC(0); - SelectObject(fl_gc, fid); - GetTextMetrics(fl_gc, &metr); + HDC gc = (HDC)fl_graphics_driver->get_gc(); + if (!gc) gc = fl_GetDC(0); + SelectObject(gc, fid); + GetTextMetrics(gc, &metr); // BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar); // ...would be the right call, but is not implemented into Window95! (WinNT?) //GetCharWidth(fl_gc, 0, 255, width); @@ -380,7 +383,7 @@ double Fl_GDI_Graphics_Driver::width(unsigned int c) { // This code assumes that these glyphs are rarely used and simply // measures them explicitly if they occur - This will be slow... if(c > 0x0000FFFF) { // UTF16 surrogate pair is needed - if (!fl_gc) { // We have no valid gc, so nothing to measure - bail out + if (!gc) { // We have no valid gc, so nothing to measure - bail out return 0.0; } int cc; // cell count @@ -388,9 +391,9 @@ double Fl_GDI_Graphics_Driver::width(unsigned int c) { // Creates a UTF16 string from a UCS code point. cc = fl_ucs_to_Utf16(c, u16, 4); // Make sure the current font is selected before we make the measurement - SelectObject(fl_gc, fl_fontsize->fid); + SelectObject(gc, fl_fontsize->fid); // measure the glyph width - GetTextExtentPoint32W(fl_gc, (WCHAR*)u16, cc, &s); + GetTextExtentPoint32W(gc, (WCHAR*)u16, cc, &s); return (double)s.cx; } // else - this falls through to the lookup-table for glyph widths @@ -411,19 +414,19 @@ double Fl_GDI_Graphics_Driver::width(unsigned int c) { // If that is null then we attempt to obtain the gc from the current screen // using (GetDC(NULL)). // This should resolve STR #2086 - HDC gc = fl_gc; + HDC gc2 = gc; HWND hWnd = 0; - if (!gc) { // We have no valid gc, try and obtain one + if (!gc2) { // We have no valid gc, try and obtain one // Use our first fltk window, or fallback to using the screen via GetDC(NULL) hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL; - gc = GetDC(hWnd); + gc2 = GetDC(hWnd); } - if (!gc) Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!"); - SelectObject(gc, fl_fontsize->fid); + if (!gc2) Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!"); + SelectObject(gc2, fl_fontsize->fid); ii += c &0x03FF; - GetTextExtentPoint32W(gc, (WCHAR*)&ii, 1, &s); + GetTextExtentPoint32W(gc2, (WCHAR*)&ii, 1, &s); fl_fontsize->width[r][c&0x03FF] = s.cx; - if (gc && gc!=fl_gc) ReleaseDC(hWnd, gc); + if (gc2 && gc2 != gc) ReleaseDC(hWnd, gc2); return (double) fl_fontsize->width[r][c & 0x03FF]; } @@ -447,11 +450,11 @@ static void GetGlyphIndices_init() { have_loaded_GetGlyphIndices = -1; // set this non-zero when we have attempted to load GetGlyphIndicesW } // GetGlyphIndices_init function -static void on_printer_extents_update(int &dx, int &dy, int &w, int &h) +static void on_printer_extents_update(int &dx, int &dy, int &w, int &h, HDC gc) // converts text extents from device coords to logical coords { POINT pt[3] = { {0, 0}, {dx, dy}, {dx+w, dy+h} }; - DPtoLP(fl_gc, pt, 3); + DPtoLP(gc, pt, 3); w = pt[2].x - pt[1].x; h = pt[2].y - pt[1].y; dx = pt[1].x - pt[0].x; @@ -459,8 +462,10 @@ 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_Surface_Device::surface() != Fl_Display_Device::display_device()) { on_printer_extents_update(x,y,w,h); } +#define EXTENTS_UPDATE(x,y,w,h,gc) \ + if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { \ + on_printer_extents_update(x,y,w,h,gc); \ + } // Function to determine the extent of the "inked" area of the glyphs in a string void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { @@ -481,7 +486,7 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy int minx = 0, miny = -999999; unsigned len = 0, idx = 0; HWND hWnd = 0; - HDC gc = fl_gc; // local copy of current gc - make a copy in case we change it... + HDC gc2 = gc; // local copy of current gc - make a copy in case we change it... int has_surrogates; // will be set if the string contains surrogate pairs // Have we loaded the GetGlyphIndicesW function yet? @@ -493,12 +498,12 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy // The following code makes a best effort attempt to obtain a valid fl_gc. // See description in fl_width() above for an explanation. - if (!gc) { // We have no valid gc, try and obtain one + if (!gc2) { // We have no valid gc, try and obtain one // Use our first fltk window, or fallback to using the screen via GetDC(NULL) hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL; - gc = GetDC(hWnd); + gc2 = GetDC(hWnd); } - if (!gc) goto exit_error; // no valid gc, attempt to use fallback measure + if (!gc2) goto exit_error; // no valid gc, attempt to use fallback measure // now convert the string to WCHAR and measure it len = fl_utf8toUtf16(c, n, ext_buff, wc_len); @@ -510,7 +515,7 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy w_buff = new WORD[wc_len]; len = fl_utf8toUtf16(c, n, ext_buff, wc_len); } - SelectObject(gc, fl_fontsize->fid); + SelectObject(gc2, fl_fontsize->fid); // Are there surrogate-pairs in this string? If so GetGlyphIndicesW will fail // since it can only handle the BMP range. @@ -533,7 +538,7 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy gcp_res.nGlyphs = wc_len; gcp_res.lStructSize = sizeof(gcp_res); - DWORD dr = GetCharacterPlacementW(gc, (WCHAR*)ext_buff, len, 0, &gcp_res, GCP_GLYPHSHAPE); + DWORD dr = GetCharacterPlacementW(gc2, (WCHAR*)ext_buff, len, 0, &gcp_res, GCP_GLYPHSHAPE); if(dr) { len = gcp_res.nGlyphs; } else goto exit_error; @@ -546,7 +551,7 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy // now we have the glyph array we measure each glyph in turn... for(idx = 0; idx < len; idx++){ - if (GetGlyphOutlineW (gc, w_buff[idx], GGO_METRICS | GGO_GLYPH_INDEX, + if (GetGlyphOutlineW (gc2, w_buff[idx], GGO_METRICS | GGO_GLYPH_INDEX, &metrics, 0, NULL, &matrix) == GDI_ERROR) { goto exit_error; } @@ -562,7 +567,7 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy h = maxh + miny; dx = minx; dy = -miny; - EXTENTS_UPDATE(dx, dy, w, h); + EXTENTS_UPDATE(dx, dy, w, h, gc); return; // normal exit exit_error: @@ -571,38 +576,38 @@ exit_error: h = height(); dx = 0; dy = descent() - h; - EXTENTS_UPDATE(dx, dy, w, h); + EXTENTS_UPDATE(dx, dy, w, h, gc); return; } // fl_text_extents void Fl_GDI_Graphics_Driver::draw(const char* str, int n, int x, int y) { - COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); + COLORREF oldColor = SetTextColor(gc, fl_RGB()); // avoid crash if no font has been set yet if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE); - SelectObject(fl_gc, font_descriptor()->fid); + SelectObject(gc, font_descriptor()->fid); int wn = fl_utf8toUtf16(str, n, wstr, wstr_len); if(wn >= wstr_len) { wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1)); wstr_len = wn + 1; wn = fl_utf8toUtf16(str, n, wstr, wstr_len); } - TextOutW(fl_gc, x, y, (WCHAR*)wstr, wn); - SetTextColor(fl_gc, oldColor); // restore initial state + TextOutW(gc, x, y, (WCHAR*)wstr, wn); + SetTextColor(gc, oldColor); // restore initial state } void Fl_GDI_Graphics_Driver::draw(int angle, const char* str, int n, int x, int y) { fl_font(this, Fl_Graphics_Driver::font(), size(), angle); int wn = 0; // count of UTF16 cells to render full string - COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); - SelectObject(fl_gc, font_descriptor()->fid); + COLORREF oldColor = SetTextColor(gc, fl_RGB()); + SelectObject(gc, font_descriptor()->fid); wn = fl_utf8toUtf16(str, n, wstr, wstr_len); if(wn >= wstr_len) { // Array too small wstr = (unsigned short*) realloc(wstr, sizeof(unsigned short) * (wn + 1)); wstr_len = wn + 1; wn = fl_utf8toUtf16(str, n, wstr, wstr_len); // respin the translation } - TextOutW(fl_gc, x, y, (WCHAR*)wstr, wn); - SetTextColor(fl_gc, oldColor); + TextOutW(gc, x, y, (WCHAR*)wstr, wn); + SetTextColor(gc, oldColor); fl_font(this, Fl_Graphics_Driver::font(), size(), 0); } @@ -615,26 +620,26 @@ void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { wn = fl_utf8toUtf16(c, n, wstr, wstr_len); } - COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); - SelectObject(fl_gc, font_descriptor()->fid); + COLORREF oldColor = SetTextColor(gc, fl_RGB()); + SelectObject(gc, font_descriptor()->fid); #ifdef RTL_CHAR_BY_CHAR int i = 0; int lx = 0; while (i < wn) { // output char by char is very bad for Arabic but coherent with fl_width() lx = (int) width(wstr[i]); x -= lx; - TextOutW(fl_gc, x, y, (WCHAR*)wstr + i, 1); + TextOutW(gc, x, y, (WCHAR*)wstr + i, 1); if (fl_nonspacing(wstr[i])) { x += lx; } i++; } #else - UINT old_align = SetTextAlign(fl_gc, TA_RIGHT | TA_RTLREADING); - TextOutW(fl_gc, x, y - height() + descent(), (WCHAR*)wstr, wn); - SetTextAlign(fl_gc, old_align); + UINT old_align = SetTextAlign(gc, TA_RIGHT | TA_RTLREADING); + TextOutW(gc, x, y - height() + descent(), (WCHAR*)wstr, wn); + SetTextAlign(gc, old_align); #endif - SetTextColor(fl_gc, oldColor); + SetTextColor(gc, oldColor); } #endif // diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx index eecb07fd7..3a128b69f 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx @@ -108,7 +108,7 @@ static void monodither(uchar* to, const uchar* from, int w, int delta) { static void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int depth, - Fl_Draw_Image_Cb cb, void* userdata) + Fl_Draw_Image_Cb cb, void* userdata, HDC gc) { char indexed = 0; @@ -254,7 +254,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // 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, + StretchDIBits(gc, x, y+j-k, w, k, 0, 0, w, k, (LPSTR)((uchar*)buffer+(blocking-k)*linesize), &bmi, #if USE_COLORMAP @@ -268,7 +268,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, buffer_size = 0; } else { - SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, + SetDIBitsToDevice(gc, x, y+j-k, w, k, 0, 0, 0, k, (LPSTR)((uchar*)buffer+(blocking-k)*linesize), &bmi, #if USE_COLORMAP @@ -286,9 +286,9 @@ static int fl_abs(int v) { return v<0 ? -v : v; } void Fl_GDI_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); + innards(buf,x,y,w,h,d,l,fl_abs(d),0,0, gc); } else { - innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0, gc); } } @@ -296,18 +296,18 @@ void Fl_GDI_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; - innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data, gc); } else { - innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data, gc); } } void Fl_GDI_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); + innards(buf,x,y,w,h,d,l,1,0,0, gc); } else { - innards(buf,x,y,w,h,d,l,1,0,0); + innards(buf,x,y,w,h,d,l,1,0,0, gc); } } @@ -315,9 +315,9 @@ void Fl_GDI_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; - innards(0,x,y,w,h,d,0,1,cb,data); + innards(0,x,y,w,h,d,0,1,cb,data, gc); } else { - innards(0,x,y,w,h,d,0,1,cb,data); + innards(0,x,y,w,h,d,0,1,cb,data, gc); } } @@ -327,7 +327,7 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { if (fl_palette) { uchar c[3]; c[0] = r; c[1] = g; c[2] = b; - innards(c,x,y,w,h,0,0,0,0,0); + innards(c,x,y,w,h,0,0,0,0,0,(HDC)fl_graphics_driver->get_gc()); return; } #endif @@ -346,8 +346,8 @@ Fl_Bitmask Fl_GDI_Graphics_Driver::create_bitmask(int w, int h, const uchar *dat static uchar loNibble[16] = { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f }; - int np = GetDeviceCaps(fl_gc, PLANES); //: was always one on sample machines - int bpp = GetDeviceCaps(fl_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff? + int np = GetDeviceCaps(gc, PLANES); //: was always one on sample machines + int bpp = GetDeviceCaps(gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff? int Bpr = (bpp*w+7)/8; //: bytes per row int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1; if (bpp==4) shr = (shr+1)/2; @@ -404,12 +404,12 @@ void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, return; } - HDC tempdc = CreateCompatibleDC(fl_gc); + HDC tempdc = CreateCompatibleDC(gc); int save = SaveDC(tempdc); SelectObject(tempdc, (HGDIOBJ)bm->id_); - SelectObject(fl_gc, fl_brush()); + SelectObject(gc, fl_brush()); // secret bitblt code found in old MSWindows reference manual: - BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); + BitBlt(gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); RestoreDC(tempdc, save); DeleteDC(tempdc); } @@ -447,15 +447,16 @@ void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, fl_color(background); fl_rectf(0,0,W,H); // use this color as offscreen background fl_color(save_c); // back to bitmap's color - tempdc = CreateCompatibleDC(fl_gc); + HDC off_gc = (HDC)fl_graphics_driver->get_gc(); + tempdc = CreateCompatibleDC(off_gc); save = SaveDC(tempdc); 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 + SelectObject(off_gc, fl_brush()); // use bitmap's desired color + BitBlt(off_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, bm->w(), bm->h(), RGB(r, g, b) ); + fl_TransparentBlt(gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) ); fl_delete_offscreen(tmp_id); RestoreDC(tempdc, save); DeleteDC(tempdc); @@ -510,12 +511,12 @@ void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int } if (!img->id_) img->id_ = (fl_uintptr_t)build_id(img, (void**)&(img->mask_)); if (img->mask_) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC(gc); int save = SaveDC(new_gc); SelectObject(new_gc, (void*)img->mask_); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + BitBlt(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); + BitBlt(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) { @@ -527,15 +528,15 @@ void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int int Fl_GDI_Printer_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) { XFORM old_tr, tr; - GetWorldTransform(fl_gc, &old_tr); // storing old transform + GetWorldTransform(gc, &old_tr); // storing old transform tr.eM11 = float(WP)/float(img->w()); tr.eM22 = float(HP)/float(img->h()); tr.eM12 = tr.eM21 = 0; tr.eDx = float(XP); tr.eDy = float(YP); - ModifyWorldTransform(fl_gc, &tr, MWT_LEFTMULTIPLY); + ModifyWorldTransform(gc, &tr, MWT_LEFTMULTIPLY); img->draw(0, 0, img->w(), img->h(), 0, 0); - SetWorldTransform(fl_gc, &old_tr); + SetWorldTransform(gc, &old_tr); return 1; } @@ -592,12 +593,12 @@ void Fl_GDI_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP int X, Y, W, H; if (pxm->prepare(XP, YP, WP, HP, cx, cy, X, Y, W, H)) return; if (pxm->mask_) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC(gc); int save = SaveDC(new_gc); SelectObject(new_gc, (void*)pxm->mask_); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + BitBlt(gc, X, Y, W, H, new_gc, cx, cy, SRCAND); SelectObject(new_gc, (void*)pxm->id_); - BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + BitBlt(gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); RestoreDC(new_gc,save); DeleteDC(new_gc); } else { @@ -617,11 +618,11 @@ void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); } if (fl_TransparentBlt) { - HDC new_gc = CreateCompatibleDC(fl_gc); + HDC new_gc = CreateCompatibleDC(gc); int save = SaveDC(new_gc); SelectObject(new_gc, (void*)pxm->id_); // print all of offscreen but its parts in background color - fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, W, H, pxm->pixmap_bg_color ); + fl_TransparentBlt(gc, X, Y, W, H, new_gc, cx, cy, W, H, pxm->pixmap_bg_color ); RestoreDC(new_gc,save); DeleteDC(new_gc); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx index 385586b2c..b855a1349 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx @@ -63,7 +63,7 @@ void Fl_GDI_Graphics_Driver::line_style(int style, int width, char* dashes) { Fl::error("fl_line_style(): Could not create GDI pen object."); return; } - HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen); + HPEN oldpen = (HPEN)SelectObject(gc, newpen); DeleteObject(oldpen); DeleteObject(fl_current_xmap->pen); fl_current_xmap->pen = newpen; diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx index 796896cdd..78b3482aa 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx @@ -36,16 +36,16 @@ // --- line and polygon drawing with integer coordinates void Fl_GDI_Graphics_Driver::point(int x, int y) { - SetPixel(fl_gc, x, y, fl_RGB()); + SetPixel(gc, x, y, fl_RGB()); } void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h) { if (w<=0 || h<=0) return; - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x+w-1, y); - LineTo(fl_gc, x+w-1, y+h-1); - LineTo(fl_gc, x, y+h-1); - LineTo(fl_gc, x, y); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x+w-1, y); + LineTo(gc, x+w-1, y+h-1); + LineTo(gc, x, y+h-1); + LineTo(gc, x, y); } void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) { @@ -64,79 +64,79 @@ void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) { RECT rect; rect.left = x; rect.top = y; rect.right = x + w; rect.bottom = y + h; - FillRect(fl_gc, &rect, fl_brush()); + FillRect(gc, &rect, fl_brush()); } void Fl_GDI_Graphics_Driver::line(int x, int y, int x1, int y1) { - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y1); - SetPixel(fl_gc, x1, y1, fl_RGB()); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y1); + SetPixel(gc, x1, y1, fl_RGB()); } void Fl_GDI_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y1); - LineTo(fl_gc, x2, y2); - SetPixel(fl_gc, x2, y2, fl_RGB()); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y1); + LineTo(gc, x2, y2); + SetPixel(gc, x2, y2, fl_RGB()); } void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1) { - MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); + MoveToEx(gc, x, y, 0L); LineTo(gc, x1+1, y); } void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2) { if (y2 < y) y2--; else y2++; - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y); - LineTo(fl_gc, x1, y2); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y); + LineTo(gc, x1, y2); } void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { if(x3 < x1) x3--; else x3++; - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y); - LineTo(fl_gc, x1, y2); - LineTo(fl_gc, x3, y2); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y); + LineTo(gc, x1, y2); + LineTo(gc, x3, y2); } void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1) { if (y1 < y) y1--; else y1++; - MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); + MoveToEx(gc, x, y, 0L); LineTo(gc, x, y1); } void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2) { if (x2 > x) x2++; else x2--; - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x, y1); - LineTo(fl_gc, x2, y1); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x, y1); + LineTo(gc, x2, y1); } void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { if(y3<y1) y3--; else y3++; - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x, y1); - LineTo(fl_gc, x2, y1); - LineTo(fl_gc, x2, y3); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x, y1); + LineTo(gc, x2, y1); + LineTo(gc, x2, y3); } void Fl_GDI_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y1); - LineTo(fl_gc, x2, y2); - LineTo(fl_gc, x, y); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y1); + LineTo(gc, x2, y2); + LineTo(gc, x, y); } void Fl_GDI_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { - MoveToEx(fl_gc, x, y, 0L); - LineTo(fl_gc, x1, y1); - LineTo(fl_gc, x2, y2); - LineTo(fl_gc, x3, y3); - LineTo(fl_gc, x, y); + MoveToEx(gc, x, y, 0L); + LineTo(gc, x1, y1); + LineTo(gc, x2, y2); + LineTo(gc, x3, y3); + LineTo(gc, x, y); } void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { @@ -144,8 +144,8 @@ void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y p[0].x = x; p[0].y = y; p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; - SelectObject(fl_gc, fl_brush()); - Polygon(fl_gc, p, 3); + SelectObject(gc, fl_brush()); + Polygon(gc, p, 3); } void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { @@ -154,8 +154,8 @@ void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; p[3].x = x3; p[3].y = y3; - SelectObject(fl_gc, fl_brush()); - Polygon(fl_gc, p, 4); + SelectObject(gc, fl_brush()); + Polygon(gc, p, 4); } // --- clipping @@ -197,7 +197,7 @@ int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, GetRgnBox(temp, &rect); if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // 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); + DPtoLP(gc, pt, 2); X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y; } else { @@ -217,7 +217,7 @@ int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) { RECT rect; if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // 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); + LPtoDP(gc, pt, 2); rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y; } else { rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; @@ -244,7 +244,7 @@ void Fl_GDI_Graphics_Driver::pop_clip() { void Fl_GDI_Graphics_Driver::restore_clip() { fl_clip_state_number++; Fl_Region r = rstack[rstackptr]; - SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared + SelectClipRgn(gc, r); //if r is NULL, clip is automatically cleared } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx index ee12c9ad8..4107a47fc 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx @@ -41,7 +41,7 @@ void Fl_GDI_Graphics_Driver::vertex(double x,double y) { } void Fl_GDI_Graphics_Driver::end_points() { - for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB()); + for (int i=0; i<n; i++) SetPixel(gc, p[i].x, p[i].y, fl_RGB()); } void Fl_GDI_Graphics_Driver::end_line() { @@ -49,7 +49,7 @@ void Fl_GDI_Graphics_Driver::end_line() { end_points(); return; } - if (n>1) Polyline(fl_gc, p, n); + if (n>1) Polyline(gc, p, n); } void Fl_GDI_Graphics_Driver::end_loop() { @@ -65,8 +65,8 @@ void Fl_GDI_Graphics_Driver::end_polygon() { return; } if (n>2) { - SelectObject(fl_gc, fl_brush()); - Polygon(fl_gc, p, n); + SelectObject(gc, fl_brush()); + Polygon(gc, p, n); } } @@ -94,8 +94,8 @@ void Fl_GDI_Graphics_Driver::end_complex_polygon() { return; } if (n>2) { - SelectObject(fl_gc, fl_brush()); - PolyPolygon(fl_gc, p, counts, numcount); + SelectObject(gc, fl_brush()); + PolyPolygon(gc, p, counts, numcount); } } @@ -114,10 +114,10 @@ void Fl_GDI_Graphics_Driver::circle(double x, double y,double r) { int h = (int)rint(yt+ry)-lly; if (what==POLYGON) { - SelectObject(fl_gc, fl_brush()); - Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); + SelectObject(gc, fl_brush()); + Pie(gc, llx, lly, llx+w, lly+h, 0,0, 0,0); } else - Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); + Arc(gc, llx, lly, llx+w, lly+h, 0,0, 0,0); } #endif // FL_CFG_GFX_GDI_VERTEX_CXX diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index 44fe57403..657e7eb26 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx @@ -23,6 +23,16 @@ const char *Fl_Quartz_Graphics_Driver::class_id = "Fl_Quartz_Graphics_Driver"; +/* Reference to the current CGContext + For back-compatibility only. The preferred procedure to get this reference is + Fl_Surface_Device::surface()->driver()->get_gc(). + */ +CGContextRef fl_gc = 0; + +void Fl_Graphics_Driver::global_gc() +{ + fl_gc = (CGContextRef)get_gc(); +} /* * By linking this module, the following static method will instatiate the @@ -118,15 +128,15 @@ void fl_begin_offscreen(Fl_Offscreen ctx) { _ss = Fl_Surface_Device::surface(); Fl_Display_Device::display_device()->set_current(); if (stack_ix<stack_max) { - stack_gc[stack_ix] = fl_gc; + stack_gc[stack_ix] = (CGContextRef)fl_graphics_driver->get_gc(); stack_window[stack_ix] = fl_window; } else fprintf(stderr, "FLTK CGContext Stack overflow error\n"); stack_ix++; - fl_gc = (CGContextRef)ctx; + fl_graphics_driver->set_gc(ctx); fl_window = 0; - CGContextSaveGState(fl_gc); + CGContextSaveGState(ctx); fl_graphics_driver->push_no_clip(); } @@ -135,14 +145,16 @@ void fl_begin_offscreen(Fl_Offscreen ctx) { */ void fl_end_offscreen() { fl_graphics_driver->pop_clip(); - CGContextRestoreGState(fl_gc); // matches CGContextSaveGState in fl_begin_offscreen() - CGContextFlush(fl_gc); + CGContextRef gc = (CGContextRef)fl_graphics_driver->get_gc(); + + CGContextRestoreGState(gc); // matches CGContextSaveGState in fl_begin_offscreen() + CGContextFlush(gc); if (stack_ix>0) stack_ix--; else fprintf(stderr, "FLTK CGContext Stack underflow error\n"); if (stack_ix<stack_max) { - fl_gc = stack_gc[stack_ix]; + fl_graphics_driver->set_gc(stack_gc[stack_ix]); fl_window = stack_window[stack_ix]; } _ss->set_current(); diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h index 93fbbfeb3..c9a6c916e 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h @@ -39,10 +39,13 @@ This class is implemented only on the Mac OS X platform. */ class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver { + CGContextRef gc; public: static const char *class_id; const char *class_name() {return class_id;}; virtual int has_feature(driver_feature mask) { return mask & NATIVE; } + virtual void set_gc(void *ctxt) {gc = (CGContextRef)ctxt;} + virtual void *get_gc() {return gc;} char can_do_alpha_blending(); // --- bitmap stuff diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx index 892baf859..4b1a164df 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx @@ -30,42 +30,42 @@ void Fl_Quartz_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) if (w <= 0 || h <= 0) return; a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; - CGContextSetShouldAntialias(fl_gc, true); + CGContextSetShouldAntialias(gc, true); if (w!=h) { - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, cx, cy); - CGContextScaleCTM(fl_gc, w-1.0f, h-1.0f); - CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); - CGContextRestoreGState(fl_gc); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, cx, cy); + CGContextScaleCTM(gc, w-1.0f, h-1.0f); + CGContextAddArc(gc, 0, 0, 0.5, a1, a2, 1); + CGContextRestoreGState(gc); } else { float r = (w+h)*0.25f-0.5f; - CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); + CGContextAddArc(gc, cx, cy, r, a1, a2, 1); } - CGContextStrokePath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextStrokePath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { if (w <= 0 || h <= 0) return; a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; - CGContextSetShouldAntialias(fl_gc, true); + CGContextSetShouldAntialias(gc, true); if (w!=h) { - CGContextSaveGState(fl_gc); - CGContextTranslateCTM(fl_gc, cx, cy); - CGContextScaleCTM(fl_gc, w, h); - CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); - CGContextAddLineToPoint(fl_gc, 0, 0); - CGContextClosePath(fl_gc); - CGContextRestoreGState(fl_gc); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, cx, cy); + CGContextScaleCTM(gc, w, h); + CGContextAddArc(gc, 0, 0, 0.5, a1, a2, 1); + CGContextAddLineToPoint(gc, 0, 0); + CGContextClosePath(gc); + CGContextRestoreGState(gc); } else { float r = (w+h)*0.25f; - CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); - CGContextAddLineToPoint(fl_gc, cx, cy); - CGContextClosePath(fl_gc); + CGContextAddArc(gc, cx, cy, r, a1, a2, 1); + CGContextAddLineToPoint(gc, cx, cy); + CGContextClosePath(gc); } - CGContextFillPath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextFillPath(gc); + CGContextSetShouldAntialias(gc, false); } #endif // FL_CFG_GFX_QUARTZ diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx index a5c489a5c..c321419ee 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx @@ -53,12 +53,12 @@ void Fl_Quartz_Graphics_Driver::color(Fl_Color i) { g = c>>16; b = c>> 8; } - if (!fl_gc) return; // no context yet? We will assign the color later. + if (!gc) return; // no context yet? We will assign the color later. float fr = r/255.0f; float fg = g/255.0f; float fb = b/255.0f; - CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); - CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBFillColor(gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(gc, fr, fg, fb, 1.0f); } void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) { @@ -66,9 +66,9 @@ void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) { float fr = r/255.0f; float fg = g/255.0f; float fb = b/255.0f; - if (!fl_gc) return; // no context yet? We will assign the color later. - CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); - CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); + if (!gc) return; // no context yet? We will assign the color later. + CGContextSetRGBFillColor(gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(gc, fr, fg, fb, 1.0f); } // FIXME: this function should not be here! It's not part of the driver. diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx index d3fc9e79d..1d909b488 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx @@ -580,7 +580,7 @@ if (fl_mac_os_version >= Fl_X::CoreText_threshold) { // activate the current GC iSize = sizeof(CGContextRef); iTag = kATSUCGContextTag; - iValuePtr = &fl_gc; + iValuePtr = &gc; ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); // now measure the bounding box err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n); @@ -632,10 +632,10 @@ if (fl_mac_os_version >= Fl_X::CoreText_threshold) { CFRelease(str16); CTLineRef ctline = CTLineCreateWithAttributedString(mastr); CFRelease(mastr); - CGContextSetTextPosition(fl_gc, 0, 0); - CGContextSetShouldAntialias(fl_gc, true); - CGRect rect = CTLineGetImageBounds(ctline, fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetTextPosition(gc, 0, 0); + CGContextSetShouldAntialias(gc, true); + CGRect rect = CTLineGetImageBounds(ctline, gc); + CGContextSetShouldAntialias(gc, false); CFRelease(ctline); dx = floor(rect.origin.x + 0.5); dy = floor(- rect.origin.y - rect.size.height + 0.5); @@ -657,7 +657,7 @@ else { // activate the current GC iSize = sizeof(CGContextRef); iTag = kATSUCGContextTag; - iValuePtr = &fl_gc; + iValuePtr = &gc; ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); // now measure the bounding box err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n); @@ -704,11 +704,12 @@ static void fl_mac_draw(const char *str, int n, float x, float y, Fl_Graphics_Dr CFRelease(color); CTLineRef ctline = CTLineCreateWithAttributedString(mastr); CFRelease(mastr); - CGContextSetTextMatrix(fl_gc, font_mx); - CGContextSetTextPosition(fl_gc, x, y); - CGContextSetShouldAntialias(fl_gc, true); - CTLineDraw(ctline, fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextRef gc = (CGContextRef)driver->get_gc(); + CGContextSetTextMatrix(gc, font_mx); + CGContextSetTextPosition(gc, x, y); + CGContextSetShouldAntialias(gc, true); + CTLineDraw(ctline, gc); + CGContextSetShouldAntialias(gc, false); CFRelease(ctline); } else { #endif @@ -719,13 +720,13 @@ static void fl_mac_draw(const char *str, int n, float x, float y, Fl_Graphics_Dr ByteCount iSize = sizeof(CGContextRef); ATSUAttributeTag iTag = kATSUCGContextTag; - ATSUAttributeValuePtr iValuePtr=&fl_gc; + ATSUAttributeValuePtr iValuePtr=&gc; ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); - CGContextSetShouldAntialias(fl_gc, true); + CGContextSetShouldAntialias(gc, true); err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y)); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, false); #endif #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 } @@ -745,11 +746,11 @@ void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) { } void Fl_Quartz_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) ); + CGContextSaveGState(gc); + CGContextTranslateCTM(gc, x, y); + CGContextRotateCTM(gc, - angle*(M_PI/180) ); draw(str, n, 0, 0); - CGContextRestoreGState(fl_gc); + CGContextRestoreGState(gc); } void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx index e1fa62e42..a36f34c82 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx @@ -51,7 +51,7 @@ static void dataReleaseCB(void *info, const void *data, size_t size) */ static void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int mono, - Fl_Draw_Image_Cb cb, void* userdata) + Fl_Draw_Image_Cb cb, void* userdata, CGContextRef gc) { if (!linedelta) linedelta = W*delta; @@ -79,7 +79,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, lut = CGColorSpaceCreateDeviceGray(); else lut = CGColorSpaceCreateDeviceRGB(); - // a release callback is necessary when the fl_gc is a print context because the image data + // a release callback is necessary when the gc is a print context because the image data // must be kept until the page is closed. Thus tmpBuf can't be deleted here. It's too early. CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, tmpBuf ? dataReleaseCB : NULL @@ -98,7 +98,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, CGDataProviderRelease(src); if (img) return; // else fall through to slow mode // following the very save (and very slow) way to write the image into the give port - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, false); if ( cb ) { uchar *tmpBuf = new uchar[ W*4 ]; @@ -112,9 +112,9 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, { fl_color( src[0], src[0], src[0] ); } else { fl_color( src[0], src[1], src[2] ); } - CGContextMoveToPoint(fl_gc, X+j, Y+i); - CGContextAddLineToPoint(fl_gc, X+j, Y+i); - CGContextStrokePath(fl_gc); + CGContextMoveToPoint(gc, X+j, Y+i); + CGContextAddLineToPoint(gc, X+j, Y+i); + CGContextStrokePath(gc); src+=delta; } } @@ -131,29 +131,29 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, fl_color( src[0], src[0], src[0] ); else fl_color( src[0], src[1], src[2] ); - CGContextMoveToPoint(fl_gc, X+j, Y+i); - CGContextAddLineToPoint(fl_gc, X+j, Y+i); - CGContextStrokePath(fl_gc); + CGContextMoveToPoint(gc, X+j, Y+i); + CGContextAddLineToPoint(gc, X+j, Y+i); + CGContextStrokePath(gc); src += delta; } } } - CGContextSetShouldAntialias(fl_gc, true); + CGContextSetShouldAntialias(gc, true); } void Fl_Quartz_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); + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0,gc); } void Fl_Quartz_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); + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data,gc); } void Fl_Quartz_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); + innards(buf,x,y,w,h,d,l,1,0,0,gc); } void Fl_Quartz_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); + innards(0,x,y,w,h,d,0,1,cb,data,gc); } void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { @@ -166,7 +166,7 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) { return; } - if (bm->id_ && fl_gc) { + if (bm->id_ && gc) { draw_CGImage((CGImageRef)bm->id_, X,Y,W,H, cx, cy, bm->w(), bm->h()); } } @@ -223,7 +223,7 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, CGColorSpaceRelease(lut); CGDataProviderRelease(src); } - if (img->id_ && fl_gc) { + if (img->id_ && gc) { if (!img->alloc_array && has_feature(PRINTER) && !CGImageGetShouldInterpolate((CGImageRef)img->id_)) { // When printing, the image data is used when the page is completed, that is, after return from this function. // If the image has alloc_array = 0, we must protect against image data being freed before it is used: @@ -252,12 +252,12 @@ int Fl_Quartz_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP fl_clip_box(XP,YP,WP,HP,X,Y,W,H); // X,Y,W,H will give the unclipped area of XP,YP,WP,HP if (W == 0 || H == 0) return 1; fl_push_no_clip(); // remove the FLTK clip that can't be rescaled - CGContextSaveGState(fl_gc); - CGContextClipToRect(fl_gc, CGRectMake(X, Y, W, H)); // this clip path will be rescaled & translated - CGContextTranslateCTM(fl_gc, XP, YP); - CGContextScaleCTM(fl_gc, float(WP)/img->w(), float(HP)/img->h()); + CGContextSaveGState(gc); + CGContextClipToRect(gc, CGRectMake(X, Y, W, H)); // this clip path will be rescaled & translated + CGContextTranslateCTM(gc, XP, YP); + CGContextScaleCTM(gc, float(WP)/img->w(), float(HP)/img->h()); img->draw(0, 0, img->w(), img->h(), 0, 0); - CGContextRestoreGState(fl_gc); + CGContextRestoreGState(gc); fl_pop_clip(); // restore FLTK's clip return 1; } @@ -317,14 +317,14 @@ fl_uintptr_t Fl_Quartz_Graphics_Driver::cache(Fl_Pixmap *img, int w, int h, cons void Fl_Quartz_Graphics_Driver::draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh) { CGRect rect = CGRectMake(x, y, w, h); - CGContextSaveGState(fl_gc); - CGContextClipToRect(fl_gc, CGRectOffset(rect, -0.5, -0.5 )); + CGContextSaveGState(gc); + CGContextClipToRect(gc, CGRectOffset(rect, -0.5, -0.5 )); // move graphics context to origin of vertically reversed image // The 0.5 here cancels the 0.5 offset present in Quartz graphics contexts. // Thus, image and surface pixels are in phase if there's no scaling. - CGContextTranslateCTM(fl_gc, rect.origin.x - srcx - 0.5, rect.origin.y - srcy + sh - 0.5); - CGContextScaleCTM(fl_gc, 1, -1); - CGAffineTransform at = CGContextGetCTM(fl_gc); + CGContextTranslateCTM(gc, rect.origin.x - srcx - 0.5, rect.origin.y - srcy + sh - 0.5); + CGContextScaleCTM(gc, 1, -1); + CGAffineTransform at = CGContextGetCTM(gc); if (at.a == at.d && at.b == 0 && at.c == 0) { // proportional scaling, no rotation // We handle x2 and /2 scalings that occur when drawing to // a double-resolution bitmap, and when drawing a double-resolution bitmap to display. @@ -345,10 +345,10 @@ void Fl_Quartz_Graphics_Driver::draw_CGImage(CGImageRef cgimg, int x, int y, int deltay = (at.ty - round(at.ty))*2; } } - if (doit) CGContextTranslateCTM(fl_gc, -deltax, -deltay); + if (doit) CGContextTranslateCTM(gc, -deltax, -deltay); } - CGContextDrawImage(fl_gc, CGRectMake(0, 0, sw, sh), cgimg); - CGContextRestoreGState(fl_gc); + CGContextDrawImage(gc, CGRectMake(0, 0, sw, sh), cgimg); + CGContextRestoreGState(gc); } // diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx index b30743a1a..9231b0581 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx @@ -36,11 +36,11 @@ static /*enum*/ CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter; static CGFloat *fl_quartz_line_pattern = 0; static int fl_quartz_line_pattern_size = 0; -void fl_quartz_restore_line_style_() { - CGContextSetLineWidth(fl_gc, fl_quartz_line_width_); - CGContextSetLineCap(fl_gc, fl_quartz_line_cap_); - CGContextSetLineJoin(fl_gc, fl_quartz_line_join_); - CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size); +void fl_quartz_restore_line_style_(CGContextRef gc) { + CGContextSetLineWidth(gc, fl_quartz_line_width_); + CGContextSetLineCap(gc, fl_quartz_line_cap_); + CGContextSetLineJoin(gc, fl_quartz_line_join_); + CGContextSetLineDash(gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size); } void Fl_Quartz_Graphics_Driver::line_style(int style, int width, char* dashes) { @@ -94,7 +94,7 @@ void Fl_Quartz_Graphics_Driver::line_style(int style, int width, char* dashes) { fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0; } - fl_quartz_restore_line_style_(); + fl_quartz_restore_line_style_((CGContextRef)get_gc()); } #endif // FL_CFG_GFX_QUARTZ diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx index debf15606..e641767d4 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx @@ -38,162 +38,162 @@ extern float fl_quartz_line_width_; // --- line and polygon drawing with integer coordinates void Fl_Quartz_Graphics_Driver::point(int x, int y) { - CGContextFillRect(fl_gc, CGRectMake(x - 0.5, y - 0.5, 1, 1) ); + CGContextFillRect(gc, CGRectMake(x - 0.5, y - 0.5, 1, 1) ); } void Fl_Quartz_Graphics_Driver::rect(int x, int y, int w, int h) { if (w<=0 || h<=0) return; - if ( (!has_feature(PRINTER)) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + if ( (!has_feature(PRINTER)) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); CGRect rect = CGRectMake(x, y, w-1, h-1); - CGContextStrokeRect(fl_gc, rect); - if ( (!has_feature(PRINTER)) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + CGContextStrokeRect(gc, rect); + if ( (!has_feature(PRINTER)) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::rectf(int x, int y, int w, int h) { if (w<=0 || h<=0) return; CGRect rect = CGRectMake(x - 0.5, y - 0.5, w , h); - CGContextFillRect(fl_gc, rect); + CGContextFillRect(gc, rect); } void Fl_Quartz_Graphics_Driver::line(int x, int y, int x1, int y1) { - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextStrokePath(gc); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextAddLineToPoint(fl_gc, x2, y2); - CGContextStrokePath(fl_gc); - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextAddLineToPoint(gc, x2, y2); + CGContextStrokePath(gc); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { /* On retina displays, all xyline() and yxline() functions produce lines that are half-unit (or one pixel) too short at both ends. This is corrected by filling at both ends rectangles of size one unit by line-width. */ - CGContextFillRect(fl_gc, CGRectMake(x-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); - CGContextFillRect(fl_gc, CGRectMake(x1-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x1-0.5 , y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1, int y2) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y); - CGContextAddLineToPoint(fl_gc, x1, y2); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y); + CGContextAddLineToPoint(gc, x1, y2); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { - CGContextFillRect(fl_gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); - CGContextFillRect(fl_gc, CGRectMake(x1 - fl_quartz_line_width_/2, y2-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x1 - fl_quartz_line_width_/2, y2-0.5, fl_quartz_line_width_, 1)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y); - CGContextAddLineToPoint(fl_gc, x1, y2); - CGContextAddLineToPoint(fl_gc, x3, y2); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y); + CGContextAddLineToPoint(gc, x1, y2); + CGContextAddLineToPoint(gc, x3, y2); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { - CGContextFillRect(fl_gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); - CGContextFillRect(fl_gc, CGRectMake(x3-0.5, y2 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x-0.5, y - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x3-0.5, y2 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x, y1); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x, y1); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { - CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); - CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y1-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x - fl_quartz_line_width_/2, y1-0.5, fl_quartz_line_width_, 1)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1, int x2) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x, y1); - CGContextAddLineToPoint(fl_gc, x2, y1); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x, y1); + CGContextAddLineToPoint(gc, x2, y1); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { - CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); - CGContextFillRect(fl_gc, CGRectMake(x2-0.5, y1 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); + CGContextFillRect(gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x2-0.5, y1 - fl_quartz_line_width_/2, 1 , fl_quartz_line_width_)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x, y1); - CGContextAddLineToPoint(fl_gc, x2, y1); - CGContextAddLineToPoint(fl_gc, x2, y3); - CGContextStrokePath(fl_gc); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x, y1); + CGContextAddLineToPoint(gc, x2, y1); + CGContextAddLineToPoint(gc, x2, y3); + CGContextStrokePath(gc); if (Fl_Display_Device::high_resolution()) { - CGContextFillRect(fl_gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); - CGContextFillRect(fl_gc, CGRectMake(x2 - fl_quartz_line_width_/2, y3-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x - fl_quartz_line_width_/2, y-0.5, fl_quartz_line_width_, 1)); + CGContextFillRect(gc, CGRectMake(x2 - fl_quartz_line_width_/2, y3-0.5, fl_quartz_line_width_, 1)); } - if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (has_feature(PRINTER) || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextAddLineToPoint(fl_gc, x2, y2); - CGContextClosePath(fl_gc); - CGContextStrokePath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextAddLineToPoint(gc, x2, y2); + CGContextClosePath(gc); + CGContextStrokePath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextAddLineToPoint(fl_gc, x2, y2); - CGContextAddLineToPoint(fl_gc, x3, y3); - CGContextClosePath(fl_gc); - CGContextStrokePath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextAddLineToPoint(gc, x2, y2); + CGContextAddLineToPoint(gc, x3, y3); + CGContextClosePath(gc); + CGContextStrokePath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextAddLineToPoint(fl_gc, x2, y2); - CGContextClosePath(fl_gc); - CGContextFillPath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextAddLineToPoint(gc, x2, y2); + CGContextClosePath(gc); + CGContextFillPath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, x, y); - CGContextAddLineToPoint(fl_gc, x1, y1); - CGContextAddLineToPoint(fl_gc, x2, y2); - CGContextAddLineToPoint(fl_gc, x3, y3); - CGContextClosePath(fl_gc); - CGContextFillPath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, x, y); + CGContextAddLineToPoint(gc, x1, y1); + CGContextAddLineToPoint(gc, x2, y2); + CGContextAddLineToPoint(gc, x3, y3); + CGContextClosePath(gc); + CGContextFillPath(gc); + CGContextSetShouldAntialias(gc, false); } // --- clipping @@ -265,34 +265,34 @@ void Fl_Quartz_Graphics_Driver::pop_clip() { restore_clip(); } -// helper function to manage the current CGContext fl_gc -extern void fl_quartz_restore_line_style_(); +// helper function to manage the current CGContext gc +extern void fl_quartz_restore_line_style_(CGContextRef gc); void Fl_Quartz_Graphics_Driver::restore_clip() { fl_clip_state_number++; Fl_Region r = rstack[rstackptr]; - if ( fl_window || fl_gc ) { // clipping for a true window or an offscreen buffer - if (fl_gc) { - CGContextRestoreGState(fl_gc); - CGContextSaveGState(fl_gc); + if ( fl_window || gc ) { // clipping for a true window or an offscreen buffer + if (gc) { + CGContextRestoreGState(gc); + CGContextSaveGState(gc); } // FLTK has only one global graphics state. // This copies the FLTK state into the current Quartz context if ( ! fl_window ) { // a bitmap context - CGFloat hgt = CGBitmapContextGetHeight(fl_gc); - CGAffineTransform at = CGContextGetCTM(fl_gc); + CGFloat hgt = CGBitmapContextGetHeight(gc); + CGAffineTransform at = CGContextGetCTM(gc); CGFloat offset = 0.5; if (at.a != 1 && at.a == at.d && at.b == 0 && at.c == 0) { // proportional scaling, no rotation hgt /= at.a; offset /= at.a; } - CGContextTranslateCTM(fl_gc, offset, hgt-offset); - CGContextScaleCTM(fl_gc, 1.0f, -1.0f); // now 0,0 is top-left point of the context + CGContextTranslateCTM(gc, offset, hgt-offset); + CGContextScaleCTM(gc, 1.0f, -1.0f); // now 0,0 is top-left point of the context } color(color()); - fl_quartz_restore_line_style_(); + fl_quartz_restore_line_style_(gc); if (r) { //apply program clip - CGContextClipToRects(fl_gc, r->rects, r->count); + CGContextClipToRects(gc, r->rects, r->count); } } } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx index ad6977e12..6400c5056 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx @@ -41,13 +41,13 @@ void Fl_Quartz_Graphics_Driver::vertex(double x,double y) { } void Fl_Quartz_Graphics_Driver::end_points() { - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, true); for (int i=0; i<n; i++) { - CGContextMoveToPoint(fl_gc, p[i].x, p[i].y); - CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y); - CGContextStrokePath(fl_gc); + CGContextMoveToPoint(gc, p[i].x, p[i].y); + CGContextAddLineToPoint(gc, p[i].x, p[i].y); + CGContextStrokePath(gc); } - if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false); + if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::end_line() { @@ -56,12 +56,12 @@ void Fl_Quartz_Graphics_Driver::end_line() { return; } if (n<=1) return; - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, p[0].x, p[0].y); for (int i=1; i<n; i++) - CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y); - CGContextStrokePath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextAddLineToPoint(gc, p[i].x, p[i].y); + CGContextStrokePath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::end_loop() { @@ -77,13 +77,13 @@ void Fl_Quartz_Graphics_Driver::end_polygon() { return; } if (n<=1) return; - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, p[0].x, p[0].y); for (int i=1; i<n; i++) - CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y); - CGContextClosePath(fl_gc); - CGContextFillPath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextAddLineToPoint(gc, p[i].x, p[i].y); + CGContextClosePath(gc); + CGContextFillPath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::begin_complex_polygon() { @@ -108,13 +108,13 @@ void Fl_Quartz_Graphics_Driver::end_complex_polygon() { return; } if (n<=1) return; - CGContextSetShouldAntialias(fl_gc, true); - CGContextMoveToPoint(fl_gc, p[0].x, p[0].y); + CGContextSetShouldAntialias(gc, true); + CGContextMoveToPoint(gc, p[0].x, p[0].y); for (int i=1; i<n; i++) - CGContextAddLineToPoint(fl_gc, p[i].x, p[i].y); - CGContextClosePath(fl_gc); - CGContextFillPath(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextAddLineToPoint(gc, p[i].x, p[i].y); + CGContextClosePath(gc); + CGContextFillPath(gc); + CGContextSetShouldAntialias(gc, false); } void Fl_Quartz_Graphics_Driver::circle(double x, double y,double r) { @@ -129,10 +129,10 @@ void Fl_Quartz_Graphics_Driver::circle(double x, double y,double r) { // Quartz warning: circle won't scale to current matrix! // Last argument must be 0 (counter-clockwise) or it draws nothing under __LP64__ !!!! - CGContextSetShouldAntialias(fl_gc, true); - CGContextAddArc(fl_gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 0); - (what == POLYGON ? CGContextFillPath : CGContextStrokePath)(fl_gc); - CGContextSetShouldAntialias(fl_gc, false); + CGContextSetShouldAntialias(gc, true); + CGContextAddArc(gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 0); + (what == POLYGON ? CGContextFillPath : CGContextStrokePath)(gc); + CGContextSetShouldAntialias(gc, false); } #endif // FL_CFG_GFX_QUARTZ diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index 52bb3f79f..cc0df0957 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx @@ -21,6 +21,7 @@ #include "Fl_WinAPI_Screen_Driver.h" #include <FL/Fl.H> #include <FL/x.H> +#include <FL/Fl_Graphics_Driver.H> #include <FL/fl_ask.H> #include <stdio.h> @@ -58,9 +59,10 @@ int Fl_WinAPI_Screen_Driver::visual(int flags) { fl_GetDC(0); if (flags & FL_DOUBLE) return 0; + HDC gc = (HDC)Fl_Display_Device::display_device()->driver()->get_gc(); if (!(flags & FL_INDEX) && - GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0; - if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0; + GetDeviceCaps(gc,BITSPIXEL) <= 8) return 0; + if ((flags & FL_RGB8) && GetDeviceCaps(gc,BITSPIXEL)<24) return 0; return 1; } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index dc8e84d00..b9ac31eff 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -3,7 +3,7 @@ // // Rectangle drawing routines for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2012 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -29,6 +29,17 @@ const char *Fl_Xlib_Graphics_Driver::class_id = "Fl_Xlib_Graphics_Driver"; +/* Reference to the current graphics context + For back-compatibility only. The preferred procedure to get this pointer is + Fl_Surface_Device::surface()->driver()->get_gc(). + */ +GC fl_gc = 0; + +void Fl_Graphics_Driver::global_gc() +{ + fl_gc = (GC)get_gc(); +} + /* * By linking this module, the following static method will instatiate the @@ -39,13 +50,23 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver() return new Fl_Xlib_Graphics_Driver(); } +GC Fl_Xlib_Graphics_Driver::gc = NULL; + +Fl_Xlib_Graphics_Driver::Fl_Xlib_Graphics_Driver(void) { + if (!gc) { + fl_open_display(); + // the unique GC used by all X windows + gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0); + } +} + char Fl_Xlib_Graphics_Driver::can_do_alpha_blending() { return Fl_X::xrender_supported(); } void Fl_Xlib_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) { - XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y); + XCopyArea(fl_display, pixmap, fl_window, gc, srcx, srcy, w, h, x, y); } void Fl_Xlib_Graphics_Driver::copy_offscreen_with_alpha(int x, int y, int w, int h, diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h index 8cd086a2a..f1e34cc38 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h @@ -4,7 +4,7 @@ // Definition of classes Fl_Device, Fl_Graphics_Driver, Fl_Surface_Device, Fl_Display_Device // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2014 by Bill Spitzak and others. +// Copyright 2010-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -33,10 +33,14 @@ This class is implemented only on the Xlib platform. */ class FL_EXPORT Fl_Xlib_Graphics_Driver : public Fl_Graphics_Driver { +protected: + static GC gc; public: static const char *class_id; + Fl_Xlib_Graphics_Driver(void); const char *class_name() {return class_id;}; virtual int has_feature(driver_feature mask) { return mask & NATIVE; } + virtual void *get_gc() { return gc; } char can_do_alpha_blending(); // --- bitmap stuff diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx index 8bc9bfc66..d7ee9a8e2 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx @@ -26,13 +26,13 @@ void Fl_Xlib_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) { if (w <= 0 || h <= 0) return; - XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); + XDrawArc(fl_display, fl_window, gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); } void Fl_Xlib_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { if (w <= 0 || h <= 0) return; - XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); - XFillArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); + XDrawArc(fl_display, fl_window, gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); + XFillArc(fl_display, fl_window, gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); } // diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx index b36ce8a41..56c24bdef 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx @@ -115,15 +115,15 @@ void Fl_Xlib_Graphics_Driver::color(Fl_Color i) { fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); } else { Fl_Graphics_Driver::color(i); - 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(i)); + if(!gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, gc, fl_xpixel(i)); } } void Fl_Xlib_Graphics_Driver::color(uchar r,uchar g,uchar b) { Fl_Graphics_Driver::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)); + if(!gc) return; // don't get a default gc if current window is not yet created/valid + XSetForeground(fl_display, gc, fl_xpixel(r,g,b)); } /** \addtogroup fl_attributes diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx index 691c1f0d2..d275d7bba 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx @@ -642,14 +642,14 @@ double Fl_Xlib_Graphics_Driver::width(unsigned int c) { } void Fl_Xlib_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) { - if (font_gc != fl_gc) { + if (font_gc != gc) { if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); - font_gc = fl_gc; - XSetFont(fl_display, fl_gc, font_descriptor()->font->fid); + font_gc = gc; + XSetFont(fl_display, gc, font_descriptor()->font->fid); } int xx, yy, ww, hh; xx = yy = ww = hh = 0; - if (fl_gc) XUtf8_measure_extents(fl_display, fl_window, font_descriptor()->font, fl_gc, &xx, &yy, &ww, &hh, c, n); + if (gc) XUtf8_measure_extents(fl_display, fl_window, font_descriptor()->font, gc, &xx, &yy, &ww, &hh, c, n); W = ww; H = hh; dx = xx; dy = yy; // This is the safe but mostly wrong thing we used to do... @@ -660,12 +660,12 @@ void Fl_Xlib_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &d } void Fl_Xlib_Graphics_Driver::draw(const char* c, int n, int x, int y) { - if (font_gc != fl_gc) { + if (font_gc != gc) { if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE); - font_gc = fl_gc; - XSetFont(fl_display, fl_gc, font_descriptor()->font->fid); + font_gc = gc; + XSetFont(fl_display, gc, font_descriptor()->font->fid); } - if (fl_gc) XUtf8DrawString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n); + if (gc) XUtf8DrawString(fl_display, fl_window, font_descriptor()->font, gc, x, y, c, n); } void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { @@ -674,11 +674,11 @@ void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int } void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { - if (font_gc != fl_gc) { + if (font_gc != gc) { if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE); - font_gc = fl_gc; + font_gc = gc; } - if (fl_gc) XUtf8DrawRtlString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n); + if (gc) XUtf8DrawRtlString(fl_display, fl_window, font_descriptor()->font, gc, x, y, c, n); } #endif // FL_DOXYGEN // diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx index 924ddec3e..7e41bcb47 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx @@ -456,7 +456,7 @@ static void figure_out_visual() { static void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int mono, Fl_Draw_Image_Cb cb, void* userdata, - const bool alpha) + const bool alpha, GC gc) { if (!linedelta) linedelta = W*delta; @@ -468,7 +468,6 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, if (!bytes_per_pixel) figure_out_visual(); const unsigned oldbpp = bytes_per_pixel; - const GC oldgc = fl_gc; static GC gc32 = None; xi.width = w; xi.height = h; @@ -486,7 +485,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, if (fl_visual->depth != 32) { if (gc32 == None) gc32 = XCreateGC(fl_display, fl_window, 0, NULL); - fl_gc = gc32; + gc = gc32; } } @@ -538,7 +537,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, buf += linedelta; to += linesize; } - XPutImage(fl_display,fl_window,fl_gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k); + XPutImage(fl_display,fl_window,gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k); } } else { STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)]; @@ -550,7 +549,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, conv((uchar*)linebuf, (uchar*)to, w, delta); to += linesize; } - XPutImage(fl_display,fl_window,fl_gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k); + XPutImage(fl_display,fl_window,gc, &xi, 0, 0, X+dx, Y+dy+j-k, w, k); } delete[] linebuf; @@ -561,10 +560,6 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, bytes_per_pixel = oldbpp; xi.depth = fl_visual->depth; xi.bits_per_pixel = oldbpp * 8; - - if (fl_visual->depth != 32) { - fl_gc = oldgc; - } } } @@ -573,7 +568,7 @@ void Fl_Xlib_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, const bool alpha = !!(d & FL_IMAGE_WITH_ALPHA); d &= ~FL_IMAGE_WITH_ALPHA; - innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0,alpha); + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0,alpha,gc); } void Fl_Xlib_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { @@ -581,14 +576,14 @@ void Fl_Xlib_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, const bool alpha = !!(d & FL_IMAGE_WITH_ALPHA); d &= ~FL_IMAGE_WITH_ALPHA; - innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data,alpha); + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data,alpha,gc); } void Fl_Xlib_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,0); + innards(buf,x,y,w,h,d,l,1,0,0,0,gc); } void Fl_Xlib_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,0); + innards(0,x,y,w,h,d,0,1,cb,data,0,gc); } void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { @@ -598,7 +593,7 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { } else { uchar c[3]; c[0] = r; c[1] = g; c[2] = b; - innards(c,x,y,w,h,0,0,0,0,0,0); + innards(c,x,y,w,h,0,0,0,0,0,0,(GC)fl_graphics_driver->get_gc()); } } @@ -617,13 +612,13 @@ void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP return; } - XSetStipple(fl_display, fl_gc, bm->id_); + XSetStipple(fl_display, 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); + XSetTSOrigin(fl_display, gc, ox, oy); + XSetFillStyle(fl_display, gc, FillStippled); + XFillRectangle(fl_display, fl_window, gc, X, Y, W, H); + XSetFillStyle(fl_display, gc, FillSolid); } @@ -734,10 +729,10 @@ void Fl_Xlib_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, in 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_); + XSetClipMask(fl_display, 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); + XSetClipOrigin(fl_display, gc, X-cx, Y-cy); } if (img->d() == 4 && fl_can_do_alpha_blending()) @@ -747,7 +742,7 @@ void Fl_Xlib_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, in if (img->mask_) { // put the old clip region back - XSetClipOrigin(fl_display, fl_gc, 0, 0); + XSetClipOrigin(fl_display, gc, 0, 0); fl_restore_clip(); } } else { @@ -783,8 +778,8 @@ void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int H if (pxm->prepare(XP, YP, WP, HP, cx, cy, X, Y, W, H)) return; if (pxm->mask_) { // make X use the bitmap as a mask: - XSetClipMask(fl_display, fl_gc, pxm->mask_); - XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + XSetClipMask(fl_display, gc, pxm->mask_); + XSetClipOrigin(fl_display, gc, X-cx, Y-cy); if (clip_region()) { // At this point, XYWH is the bounding box of the intersection between // the current clip region and the (portion of the) pixmap we have to draw. @@ -810,7 +805,7 @@ void Fl_Xlib_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int H copy_offscreen(X, Y, W, H, pxm->id_, cx, cy); } // put the old clip region back - XSetClipOrigin(fl_display, fl_gc, 0, 0); + XSetClipOrigin(fl_display, gc, 0, 0); restore_clip(); } else copy_offscreen(X, Y, W, H, pxm->id_, cx, cy); diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx index 834682ea3..4aabe44b5 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx @@ -71,10 +71,10 @@ void Fl_Xlib_Graphics_Driver::line_style(int style, int width, char* dashes) { } static int Cap[4] = {CapButt, CapButt, CapRound, CapProjecting}; static int Join[4] = {JoinMiter, JoinMiter, JoinRound, JoinBevel}; - XSetLineAttributes(fl_display, fl_gc, width, + XSetLineAttributes(fl_display, gc, width, ndashes ? LineOnOffDash : LineSolid, Cap[(style>>8)&3], Join[(style>>12)&3]); - if (ndashes) XSetDashes(fl_display, fl_gc, 0, dashes, ndashes); + if (ndashes) XSetDashes(fl_display, gc, 0, dashes, ndashes); } #endif // FL_CFG_GFX_XLIB_LINE_STYLE_CXX diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx index 92328b088..04dbb5b05 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx @@ -162,23 +162,23 @@ Fl_Region XRectangleRegion(int x, int y, int w, int h) { // --- line and polygon drawing with integer coordinates void Fl_Xlib_Graphics_Driver::point(int x, int y) { - XDrawPoint(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y)); + XDrawPoint(fl_display, fl_window, gc, clip_x(x), clip_x(y)); } void Fl_Xlib_Graphics_Driver::rect(int x, int y, int w, int h) { if (w<=0 || h<=0) return; if (!clip_to_short(x, y, w, h)) - XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); + XDrawRectangle(fl_display, fl_window, gc, x, y, w-1, h-1); } void Fl_Xlib_Graphics_Driver::rectf(int x, int y, int w, int h) { if (w<=0 || h<=0) return; if (!clip_to_short(x, y, w, h)) - XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); + XFillRectangle(fl_display, fl_window, gc, x, y, w, h); } void Fl_Xlib_Graphics_Driver::line(int x, int y, int x1, int y1) { - XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1); + XDrawLine(fl_display, fl_window, gc, x, y, x1, y1); } void Fl_Xlib_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { @@ -186,18 +186,18 @@ void Fl_Xlib_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) p[0].x = x; p[0].y = y; p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; - XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); + XDrawLines(fl_display, fl_window, gc, p, 3, 0); } void Fl_Xlib_Graphics_Driver::xyline(int x, int y, int x1) { - XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x1), clip_x(y)); + XDrawLine(fl_display, fl_window, gc, clip_x(x), clip_x(y), clip_x(x1), clip_x(y)); } void Fl_Xlib_Graphics_Driver::xyline(int x, int y, int x1, int y2) { XPoint p[3]; p[0].x = clip_x(x); p[0].y = p[1].y = clip_x(y); p[1].x = p[2].x = clip_x(x1); p[2].y = clip_x(y2); - XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); + XDrawLines(fl_display, fl_window, gc, p, 3, 0); } void Fl_Xlib_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { @@ -205,18 +205,18 @@ void Fl_Xlib_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { p[0].x = clip_x(x); p[0].y = p[1].y = clip_x(y); p[1].x = p[2].x = clip_x(x1); p[2].y = p[3].y = clip_x(y2); p[3].x = clip_x(x3); - XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); + XDrawLines(fl_display, fl_window, gc, p, 4, 0); } void Fl_Xlib_Graphics_Driver::yxline(int x, int y, int y1) { - XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x), clip_x(y1)); + XDrawLine(fl_display, fl_window, gc, clip_x(x), clip_x(y), clip_x(x), clip_x(y1)); } void Fl_Xlib_Graphics_Driver::yxline(int x, int y, int y1, int x2) { XPoint p[3]; p[0].x = p[1].x = clip_x(x); p[0].y = clip_x(y); p[1].y = p[2].y = clip_x(y1); p[2].x = clip_x(x2); - XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); + XDrawLines(fl_display, fl_window, gc, p, 3, 0); } void Fl_Xlib_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { @@ -224,7 +224,7 @@ void Fl_Xlib_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { p[0].x = p[1].x = clip_x(x); p[0].y = clip_x(y); p[1].y = p[2].y = clip_x(y1); p[2].x = p[3].x = clip_x(x2); p[3].y = clip_x(y3); - XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); + XDrawLines(fl_display, fl_window, gc, p, 4, 0); } void Fl_Xlib_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { @@ -233,7 +233,7 @@ void Fl_Xlib_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; p[3].x = x; p[3].y = y; - XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); + XDrawLines(fl_display, fl_window, gc, p, 4, 0); } void Fl_Xlib_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { @@ -243,7 +243,7 @@ void Fl_Xlib_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, p[2].x = x2; p[2].y = y2; p[3].x = x3; p[3].y = y3; p[4].x = x; p[4].y = y; - XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0); + XDrawLines(fl_display, fl_window, gc, p, 5, 0); } void Fl_Xlib_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { @@ -252,8 +252,8 @@ void Fl_Xlib_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; p[3].x = x; p[3].y = y; - XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0); - XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); + XFillPolygon(fl_display, fl_window, gc, p, 3, Convex, 0); + XDrawLines(fl_display, fl_window, gc, p, 4, 0); } void Fl_Xlib_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { @@ -263,8 +263,8 @@ void Fl_Xlib_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int p[2].x = x2; p[2].y = y2; p[3].x = x3; p[3].y = y3; p[4].x = x; p[4].y = y; - XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0); - XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0); + XFillPolygon(fl_display, fl_window, gc, p, 4, Convex, 0); + XDrawLines(fl_display, fl_window, gc, p, 5, 0); } // --- clipping @@ -285,7 +285,7 @@ void Fl_Xlib_Graphics_Driver::push_clip(int x, int y, int w, int h) { } if (rstackptr < region_stack_max) rstack[++rstackptr] = r; else Fl::warning("Fl_Xlib_Graphics_Driver::push_clip: clip stack overflow!\n"); - fl_restore_clip(); + restore_clip(); } int Fl_Xlib_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ @@ -325,7 +325,7 @@ int Fl_Xlib_Graphics_Driver::not_clipped(int x, int y, int w, int h) { void Fl_Xlib_Graphics_Driver::push_no_clip() { if (rstackptr < region_stack_max) rstack[++rstackptr] = 0; else Fl::warning("fl_push_no_cFl_Xlib_Graphics_Driver::push_no_cliplip: clip stack overflow!\n"); - fl_restore_clip(); + restore_clip(); } // pop back to previous clip: @@ -334,14 +334,14 @@ void Fl_Xlib_Graphics_Driver::pop_clip() { Fl_Region oldr = rstack[rstackptr--]; if (oldr) XDestroyRegion(oldr); } else Fl::warning("Fl_Xlib_Graphics_Driver::pop_clip: clip stack underflow!\n"); - fl_restore_clip(); + restore_clip(); } void Fl_Xlib_Graphics_Driver::restore_clip() { fl_clip_state_number++; Fl_Region r = rstack[rstackptr]; - if (r) XSetRegion(fl_display, fl_gc, r); - else XSetClipMask(fl_display, fl_gc, 0); + if (r) XSetRegion(fl_display, gc, r); + else XSetClipMask(fl_display, gc, 0); } #endif // FL_CFG_GFX_XLIB_RECT_CXX diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx index 4c559ad8c..b7d927873 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx @@ -41,7 +41,7 @@ void Fl_Xlib_Graphics_Driver::vertex(double x,double y) { } void Fl_Xlib_Graphics_Driver::end_points() { - if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0); + if (n>1) XDrawPoints(fl_display, fl_window, gc, p, n, 0); } void Fl_Xlib_Graphics_Driver::end_line() { @@ -49,7 +49,7 @@ void Fl_Xlib_Graphics_Driver::end_line() { end_points(); return; } - if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0); + if (n>1) XDrawLines(fl_display, fl_window, gc, p, n, 0); } void Fl_Xlib_Graphics_Driver::end_loop() { @@ -64,7 +64,7 @@ void Fl_Xlib_Graphics_Driver::end_polygon() { end_line(); return; } - if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0); + if (n>2) XFillPolygon(fl_display, fl_window, gc, p, n, Convex, 0); } void Fl_Xlib_Graphics_Driver::begin_complex_polygon() { @@ -88,7 +88,7 @@ void Fl_Xlib_Graphics_Driver::end_complex_polygon() { end_line(); return; } - if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0); + if (n>2) XFillPolygon(fl_display, fl_window, gc, p, n, 0, 0); } // shortcut the closed circles so they use XDrawArc: @@ -106,7 +106,7 @@ void Fl_Xlib_Graphics_Driver::circle(double x, double y,double r) { int h = (int)rint(yt+ry)-lly; (what == POLYGON ? XFillArc : XDrawArc) - (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64); + (fl_display, fl_window, gc, llx, lly, w, h, 0, 360*64); } #endif // FL_CFG_GFX_XLIB_VERTEX_CXX diff --git a/src/fl_overlay.cxx b/src/fl_overlay.cxx index 41ac3b4a5..2f4547607 100644 --- a/src/fl_overlay.cxx +++ b/src/fl_overlay.cxx @@ -3,7 +3,7 @@ // // Overlay support for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -40,14 +40,15 @@ static int bgx, bgy, bgw, bgh; static void draw_current_rect() { #ifdef USE_XOR # if defined(USE_X11) - XSetFunction(fl_display, fl_gc, GXxor); - XSetForeground(fl_display, fl_gc, 0xffffffff); - XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph); - XSetFunction(fl_display, fl_gc, GXcopy); + GC gc = (GC)fl_graphics_driver->get_gc(); + XSetFunction(fl_display, gc, GXxor); + XSetForeground(fl_display, gc, 0xffffffff); + XDrawRectangle(fl_display, fl_window, gc, px, py, pw, ph); + XSetFunction(fl_display, gc, GXcopy); # elif defined(WIN32) - int old = SetROP2(fl_gc, R2_NOT); + int old = SetROP2(fl_graphics_driver->get_gc(), R2_NOT); fl_rect(px, py, pw, ph); - SetROP2(fl_gc, old); + SetROP2(fl_graphics_driver->get_gc(), old); # elif defined(__APPLE_QUARTZ__) // PORTME: Fl_Window_Driver - platform overlay // warning: Quartz does not support xor drawing // Use the Fl_Overlay_Window instead. diff --git a/src/fl_read_image_mac.cxx b/src/fl_read_image_mac.cxx index a6324e5c1..fb1a6cf24 100644 --- a/src/fl_read_image_mac.cxx +++ b/src/fl_read_image_mac.cxx @@ -3,7 +3,7 @@ // // WIN32 image reading routines for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -32,7 +32,7 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate uchar *base; int rowBytes, delta; if(fl_window == NULL) { // reading from an offscreen buffer - CGContextRef src = (CGContextRef)fl_gc; // get bitmap context + CGContextRef src = (CGContextRef)Fl_Surface_Device::surface()->driver()->get_gc(); // get bitmap context base = (uchar *)CGBitmapContextGetData(src); // get data if(!base) return NULL; int sw = CGBitmapContextGetWidth(src); diff --git a/src/fl_read_image_win32.cxx b/src/fl_read_image_win32.cxx index 28f83017a..738d43f49 100644 --- a/src/fl_read_image_win32.cxx +++ b/src/fl_read_image_win32.cxx @@ -3,7 +3,7 @@ // // WIN32 image reading routines for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2014 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -77,13 +77,13 @@ read_win_rectangle(uchar *p, // I - Pixel buffer or NULL to allocate bi.bmiHeader.biClrImportant = 0; // copy bitmap from original DC (Window, Fl_Offscreen, ...) - - HDC hdc = CreateCompatibleDC(fl_gc); - HBITMAP hbm = CreateCompatibleBitmap(fl_gc,w,h); + HDC gc = (HDC)fl_graphics_driver->get_gc(); + HDC hdc = CreateCompatibleDC(gc); + HBITMAP hbm = CreateCompatibleBitmap(gc,w,h); int save_dc = SaveDC(hdc); // save context for cleanup SelectObject(hdc,hbm); // select bitmap - BitBlt(hdc,0,0,w,h,fl_gc,X,Y,SRCCOPY); // copy image section to DDB + BitBlt(hdc,0,0,w,h,gc,X,Y,SRCCOPY); // copy image section to DDB // copy RGB image data to the allocated DIB diff --git a/src/fl_scroll_area.cxx b/src/fl_scroll_area.cxx index 4637dc561..e79d1453c 100644 --- a/src/fl_scroll_area.cxx +++ b/src/fl_scroll_area.cxx @@ -3,7 +3,7 @@ // // Scrolling routines for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2010 by Bill Spitzak and others. +// Copyright 1998-2016 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -79,7 +79,7 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, } #if defined(USE_X11) - XCopyArea(fl_display, fl_window, fl_window, fl_gc, + XCopyArea(fl_display, fl_window, fl_window, (GC)fl_graphics_driver->get_gc(), src_x, src_y, src_w, src_h, dest_x, dest_y); // we have to sync the display and get the GraphicsExpose events! (sigh) for (;;) { @@ -117,14 +117,15 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, // multi-screen solutions, it will not solve issues scrolling // from a different resolution screen onto another. // Note 3: this has been tested with image maps, too. + HDC gc = (HDC)fl_graphics_driver->get_gc(); if (fl_GetRandomRgn) { // get the DC region minus all overlapping windows HRGN sys_rgn = CreateRectRgn(0, 0, 0, 0); - fl_GetRandomRgn(fl_gc, sys_rgn, 4); + fl_GetRandomRgn(gc, sys_rgn, 4); // now get the source scrolling rectangle HRGN src_rgn = CreateRectRgn(src_x, src_y, src_x+src_w, src_y+src_h); POINT offset = { 0, 0 }; - if (GetDCOrgEx(fl_gc, &offset)) { + if (GetDCOrgEx(gc, &offset)) { OffsetRgn(src_rgn, offset.x, offset.y); } // see if all source pixels are available in the system region @@ -142,7 +143,7 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy, } // Great, we can do an accelerated scroll instead of re-rendering - BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY); + BitBlt(gc, dest_x, dest_y, src_w, src_h, gc, src_x, src_y,SRCCOPY); #elif defined(__APPLE_QUARTZ__) // PORTME: Fl_Graphics_Driver - platform scrolling CGImageRef img = Fl_X::CGImage_from_window_rect(Fl_Window::current(), src_x, src_y, src_w, src_h); diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx index 48c7d732f..51f92fd66 100644 --- a/src/gl_draw.cxx +++ b/src/gl_draw.cxx @@ -101,10 +101,10 @@ void gl_font(int fontid, int size) { // this is unused because USE_OksiD_style_GL_font_selection == 1 int base = fl_fontsize->metr.tmFirstChar; int count = fl_fontsize->metr.tmLastChar-base+1; - HFONT oldFid = (HFONT)SelectObject(fl_gc, fl_fontsize->fid); + HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->get_gc(), fl_fontsize->fid); fl_fontsize->listbase = glGenLists(256); - wglUseFontBitmaps(fl_gc, base, count, fl_fontsize->listbase+base); - SelectObject(fl_gc, oldFid); + wglUseFontBitmaps((HDC)fl_graphics_driver->get_gc(), base, count, fl_fontsize->listbase+base); + SelectObject((HDC)fl_graphics_driver->get_gc(), oldFid); # endif #endif // USE_OksiD_style_GL_font_selection @@ -132,9 +132,9 @@ static void get_list(int r) { # endif #elif defined(WIN32) unsigned int ii = r * 0x400; - HFONT oldFid = (HFONT)SelectObject(fl_gc, gl_fontsize->fid); - wglUseFontBitmapsW(fl_gc, ii, ii + 0x03ff, gl_fontsize->listbase+ii); - SelectObject(fl_gc, oldFid); + HFONT oldFid = (HFONT)SelectObject((HDC)fl_graphics_driver->get_gc(), gl_fontsize->fid); + wglUseFontBitmapsW((HDC)fl_graphics_driver->get_gc(), ii, ii + 0x03ff, gl_fontsize->listbase+ii); + SelectObject((HDC)fl_graphics_driver->get_gc(), oldFid); #else # error unsupported platform #endif @@ -350,6 +350,7 @@ static int has_texture_rectangle = 0; // true means GL_EXT_texture_rectangle is #include <FL/glu.h> // for gluUnProject() and gluCheckExtension() #include <FL/glut.H> // for glutStrokeString() and glutStrokeLength() +#include <src/drivers/Quartz/Fl_Quartz_Graphics_Driver.h> // manages a fifo pile of pre-computed string textures class gl_texture_fifo { @@ -490,25 +491,26 @@ int gl_texture_fifo::compute_texture(const char* str, int n) CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); void *base = NULL; if (fl_mac_os_version < 100600) base = calloc(4*fifo[current].width, h); - CGContextRef save_gc = fl_gc; - fl_gc = CGBitmapContextCreate(base, fifo[current].width, h, 8, fifo[current].width*4, lut, + void* save_gc = fl_graphics_driver->get_gc(); + CGContextRef gc = CGBitmapContextCreate(base, fifo[current].width, h, 8, fifo[current].width*4, lut, (CGBitmapInfo)(kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + fl_graphics_driver->set_gc(gc); CGColorSpaceRelease(lut); GLfloat colors[4]; glGetFloatv(GL_CURRENT_COLOR, colors); fl_color((uchar)(colors[0]*255), (uchar)(colors[1]*255), (uchar)(colors[2]*255)); - CGContextTranslateCTM(fl_gc, 0, h - gl_scale*fl_descent()); - CGContextScaleCTM(fl_gc, gl_scale, gl_scale); + CGContextTranslateCTM(gc, 0, h - gl_scale*fl_descent()); + CGContextScaleCTM(gc, gl_scale, gl_scale); fl_draw(str, n, 0, 0); //put this bitmap in a texture glPushAttrib(GL_TEXTURE_BIT); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, fifo[current].texName); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ROW_LENGTH, fifo[current].width); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, fifo[current].width, h, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, CGBitmapContextGetData(fl_gc)); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, fifo[current].width, h, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, CGBitmapContextGetData(gc)); glPopAttrib(); - CGContextRelease(fl_gc); - fl_gc = save_gc; + CGContextRelease(gc); + fl_graphics_driver->set_gc(save_gc); if (base) free(base); } else { fifo[current].ratio = float(fifo[current].width)/glutStrokeLength(GLUT_STROKE_ROMAN, (uchar*)fifo[current].utf8); |
