mirror of
https://github.com/fltk/fltk.git
synced 2026-05-24 08:16:04 +08:00
Replace internal fl_create_offscreen() calls by new Fl_Image_Surface
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
class Fl_X;
|
||||
class Fl_Image;
|
||||
class Fl_RGB_Image;
|
||||
class Fl_Image_Surface;
|
||||
|
||||
/**
|
||||
\brief A base class for platform specific window handling code.
|
||||
@@ -64,7 +65,7 @@ public:
|
||||
static fl_uintptr_t xid(const Fl_Window *win);
|
||||
static Fl_Window *find(fl_uintptr_t xid);
|
||||
int wait_for_expose_value;
|
||||
Fl_Offscreen other_xid; // offscreen bitmap (overlay and double-buffered windows)
|
||||
Fl_Image_Surface *other_xid; // offscreen bitmap (overlay and double-buffered windows)
|
||||
int screen_num();
|
||||
void screen_num(int n) { screen_num_ = n; }
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "Fl_Window_Driver.H"
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/Fl_Overlay_Window.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl.H>
|
||||
@@ -120,7 +121,7 @@ void Fl_Window_Driver::draw_end() {
|
||||
}
|
||||
|
||||
void Fl_Window_Driver::destroy_double_buffer() {
|
||||
fl_delete_offscreen(other_xid);
|
||||
delete other_xid;
|
||||
other_xid = 0;
|
||||
}
|
||||
|
||||
|
||||
+14
-13
@@ -27,6 +27,7 @@ extern "C" {
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Tooltip.H>
|
||||
#include <FL/Fl_Printer.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl_Rect.H>
|
||||
#include <FL/fl_string_functions.h>
|
||||
@@ -3969,9 +3970,9 @@ static NSImage *imageFromText(const char *text, int *pwidth, int *pheight)
|
||||
}
|
||||
height = nl * fl_height() + 3;
|
||||
width += 6;
|
||||
Fl_Offscreen off = fl_create_offscreen(width, height);
|
||||
fl_begin_offscreen(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
Fl_Image_Surface *off = new Fl_Image_Surface(width, height, 1);
|
||||
Fl_Surface_Device::push_current(off);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off->offscreen(), 0,0,0,0);
|
||||
fl_rectf(0,0,width,height);
|
||||
fl_color(FL_BLACK);
|
||||
p = text;
|
||||
@@ -3988,9 +3989,9 @@ static NSImage *imageFromText(const char *text, int *pwidth, int *pheight)
|
||||
y += fl_height();
|
||||
p = q + 1;
|
||||
}
|
||||
fl_end_offscreen();
|
||||
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off );
|
||||
fl_delete_offscreen( off );
|
||||
Fl_Surface_Device::pop_current();
|
||||
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off->offscreen() );
|
||||
delete off;
|
||||
*pwidth = width;
|
||||
*pheight = height;
|
||||
return image;
|
||||
@@ -4006,8 +4007,8 @@ static NSImage *defaultDragImage(int *pwidth, int *pheight)
|
||||
else {
|
||||
width = 16; height = 16;
|
||||
}
|
||||
Fl_Offscreen off = fl_create_offscreen(width, height);
|
||||
fl_begin_offscreen(off);
|
||||
Fl_Image_Surface *off = new Fl_Image_Surface(width, height, 1);
|
||||
Fl_Surface_Device::push_current(off);
|
||||
if (fl_mac_os_version >= version_threshold) {
|
||||
fl_font(FL_HELVETICA, 20);
|
||||
fl_color(FL_BLACK);
|
||||
@@ -4016,15 +4017,15 @@ static NSImage *defaultDragImage(int *pwidth, int *pheight)
|
||||
fl_draw(str, l, 1, 16);
|
||||
}
|
||||
else { // draw two squares
|
||||
CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
|
||||
CGContextSetRGBFillColor( (CGContextRef)off->offscreen(), 0,0,0,0);
|
||||
fl_rectf(0,0,width,height);
|
||||
CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6);
|
||||
CGContextSetRGBStrokeColor( (CGContextRef)off->offscreen(), 0,0,0,0.6);
|
||||
fl_rect(0,0,width,height);
|
||||
fl_rect(2,2,width-4,height-4);
|
||||
}
|
||||
fl_end_offscreen();
|
||||
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off );
|
||||
fl_delete_offscreen( off );
|
||||
Fl_Surface_Device::pop_current();
|
||||
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off->offscreen() );
|
||||
delete off;
|
||||
*pwidth = width;
|
||||
*pheight = height;
|
||||
return image;
|
||||
|
||||
@@ -54,20 +54,18 @@ void Fl_Cocoa_Window_Driver::flush_overlay()
|
||||
if (!oWindow->shown()) return;
|
||||
pWindow->make_current(); // make sure fl_gc is non-zero
|
||||
if (!other_xid) {
|
||||
other_xid = fl_create_offscreen(oWindow->w(), oWindow->h());
|
||||
other_xid = new Fl_Image_Surface(oWindow->w(), oWindow->h(), 1);
|
||||
oWindow->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
if (oWindow->damage() & ~FL_DAMAGE_EXPOSE) {
|
||||
Fl_X *myi = Fl_X::flx(pWindow);
|
||||
fl_clip_region(myi->region); myi->region = 0;
|
||||
fl_begin_offscreen(other_xid);
|
||||
Fl_Surface_Device::push_current(other_xid);
|
||||
draw();
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
if (erase_overlay) fl_clip_region(0);
|
||||
if (other_xid) {
|
||||
fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid, 0, 0);
|
||||
}
|
||||
fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid->offscreen(), 0, 0);
|
||||
if (overlay() == oWindow) oWindow->draw_overlay();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include "Fl_PostScript_Graphics_Driver.H"
|
||||
#include <FL/Fl_PostScript.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/Fl_Native_File_Chooser.H>
|
||||
#include "../../Fl_System_Driver.H"
|
||||
#include <FL/fl_string_functions.h>
|
||||
@@ -1128,8 +1129,8 @@ void Fl_PostScript_Graphics_Driver::transformed_draw_extra(const char* str, int
|
||||
// create an offscreen image of the string
|
||||
Fl_Color text_color = Fl_Graphics_Driver::color();
|
||||
Fl_Color bg_color = fl_contrast(FL_WHITE, text_color);
|
||||
Fl_Offscreen off = fl_create_offscreen(w_scaled, (int)(h+3*scale) );
|
||||
fl_begin_offscreen(off);
|
||||
Fl_Image_Surface *off = new Fl_Image_Surface(w_scaled, (int)(h+3*scale), 1);
|
||||
Fl_Surface_Device::push_current(off);
|
||||
fl_color(bg_color);
|
||||
// color offscreen background with a shade contrasting with the text color
|
||||
fl_rectf(0, 0, w_scaled, (int)(h+3*scale) );
|
||||
@@ -1147,9 +1148,9 @@ void Fl_PostScript_Graphics_Driver::transformed_draw_extra(const char* str, int
|
||||
else fl_draw(str, n, 0, (int)(h * 0.8) );
|
||||
// read (most of) the offscreen image
|
||||
uchar *img = fl_read_image(NULL, 0, 1, w2, h, 0);
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
font(fontnum, old_size);
|
||||
fl_delete_offscreen(off);
|
||||
delete off;
|
||||
// compute the mask of what is not the background
|
||||
uchar *img_mask = calc_mask(img, w2, h, bg_color);
|
||||
delete[] img;
|
||||
|
||||
@@ -111,17 +111,8 @@ void Fl_Quartz_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Of
|
||||
CGDataProviderRelease(src_bytes);
|
||||
CGColorSpaceRelease(lut);
|
||||
}
|
||||
float s = scale();
|
||||
Fl_Surface_Device *current = Fl_Surface_Device::surface();
|
||||
// test whether osrc was created by fl_create_offscreen()
|
||||
fl_begin_offscreen(osrc); // does nothing if osrc was not created by fl_create_offscreen()
|
||||
if (current != Fl_Surface_Device::surface()) { // osrc was created by fl_create_offscreen()
|
||||
Fl_Image_Surface *imgs = (Fl_Image_Surface*)Fl_Surface_Device::surface();
|
||||
int pw, ph;
|
||||
imgs->printable_rect(&pw, &ph);
|
||||
s = sw / float(pw);
|
||||
fl_end_offscreen();
|
||||
}
|
||||
CGAffineTransform at = CGContextGetCTM(src);
|
||||
float s = at.a;
|
||||
draw_CGImage(img, x, y, w, h, srcx, srcy, sw/s, sh/s);
|
||||
CGImageRelease(img);
|
||||
}
|
||||
|
||||
@@ -176,19 +176,19 @@ void Fl_Wayland_Window_Driver::flush_overlay()
|
||||
pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
|
||||
pWindow->make_current();
|
||||
if (!other_xid) {
|
||||
other_xid = fl_create_offscreen(oWindow->w(), oWindow->h());
|
||||
other_xid = new Fl_Image_Surface(oWindow->w(), oWindow->h(), 1);
|
||||
oWindow->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
if (oWindow->damage() & ~FL_DAMAGE_EXPOSE) {
|
||||
Fl_X *myi = Fl_X::flx(pWindow);
|
||||
fl_clip_region(myi->region); myi->region = 0;
|
||||
fl_begin_offscreen(other_xid);
|
||||
Fl_Surface_Device::push_current(other_xid);
|
||||
draw();
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
if (erase_overlay) fl_clip_region(0);
|
||||
if (other_xid) {
|
||||
fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid, 0, 0);
|
||||
fl_copy_offscreen(0, 0, oWindow->w(), oWindow->h(), other_xid->offscreen(), 0, 0);
|
||||
}
|
||||
if (overlay() == oWindow) oWindow->draw_overlay();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <FL/Fl_Image.H>
|
||||
#include <FL/Fl_Bitmap.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/Fl_Overlay_Window.H>
|
||||
#include <FL/platform.H>
|
||||
#include "Fl_WinAPI_Window_Driver.H"
|
||||
@@ -290,16 +291,16 @@ void Fl_WinAPI_Window_Driver::flush_double()
|
||||
if (!i) return; // window not yet created
|
||||
|
||||
if (!other_xid) {
|
||||
other_xid = fl_create_offscreen(w(), h());
|
||||
other_xid = new Fl_Image_Surface(w(), h(), 1);
|
||||
pWindow->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
|
||||
fl_clip_region(i->region); i->region = 0;
|
||||
#if 0 /* Short form that transiently changes the current Fl_Surface_Device */
|
||||
fl_begin_offscreen(other_xid);
|
||||
Fl_Surface_Device::push_current(other_xid);
|
||||
fl_graphics_driver->clip_region( 0 );
|
||||
draw();
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
#else
|
||||
/* Alternative form that avoids changing the current Fl_Surface_Device.
|
||||
The code run in the window draw() method can call Fl_Surface_Device::surface()
|
||||
@@ -307,7 +308,7 @@ void Fl_WinAPI_Window_Driver::flush_double()
|
||||
for an Fl_Double_Window.
|
||||
*/
|
||||
HDC sgc = fl_gc;
|
||||
fl_gc = fl_makeDC((HBITMAP)other_xid);
|
||||
fl_gc = fl_makeDC((HBITMAP)other_xid->offscreen());
|
||||
int savedc = SaveDC(fl_gc);
|
||||
fl_graphics_driver->gc(fl_gc);
|
||||
fl_graphics_driver->restore_clip(); // duplicate clip region into new gc
|
||||
@@ -322,7 +323,7 @@ void Fl_WinAPI_Window_Driver::flush_double()
|
||||
}
|
||||
int X = 0, Y = 0, W = 0, H = 0;
|
||||
fl_clip_box(0, 0, w(), h(), X, Y, W, H);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid, X, Y);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid->offscreen(), X, Y);
|
||||
}
|
||||
|
||||
|
||||
@@ -339,20 +340,20 @@ void Fl_WinAPI_Window_Driver::flush_overlay()
|
||||
pWindow->clear_damage((uchar)(pWindow->damage()&~FL_DAMAGE_OVERLAY));
|
||||
|
||||
if (!other_xid) {
|
||||
other_xid = fl_create_offscreen(w(), h());
|
||||
other_xid = new Fl_Image_Surface(w(), h(), 1);
|
||||
pWindow->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
|
||||
fl_clip_region(i->region); i->region = 0;
|
||||
fl_begin_offscreen(other_xid);
|
||||
Fl_Surface_Device::push_current(other_xid);
|
||||
fl_graphics_driver->clip_region(0);
|
||||
draw();
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
|
||||
if (eraseoverlay) fl_clip_region(0);
|
||||
int X, Y, W, H; fl_clip_box(0, 0, w(), h(), X, Y, W, H);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid, X, Y);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid->offscreen(), X, Y);
|
||||
|
||||
if (overlay() == oWindow) oWindow->draw_overlay();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#endif // FLTK_USE_CAIRO
|
||||
|
||||
#include <FL/Fl_Tooltip.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/fl_ask.H>
|
||||
#include <FL/Fl.H>
|
||||
@@ -158,11 +159,11 @@ void Fl_X11_Window_Driver::flush_double(int erase_overlay)
|
||||
pWindow->make_current(); // make sure fl_gc is non-zero
|
||||
Fl_X *i = Fl_X::flx(pWindow);
|
||||
if (!other_xid) {
|
||||
other_xid = fl_create_offscreen(w(), h());
|
||||
other_xid = new Fl_Image_Surface(w(), h(), 1);
|
||||
#if FLTK_USE_CAIRO
|
||||
fl_begin_offscreen(other_xid);
|
||||
Fl_Surface_Device::push_current(other_xid);
|
||||
cairo_ = ((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->cr();
|
||||
fl_end_offscreen();
|
||||
Fl_Surface_Device::pop_current();
|
||||
#endif
|
||||
pWindow->clear_damage(FL_DAMAGE_ALL);
|
||||
}
|
||||
@@ -171,7 +172,7 @@ void Fl_X11_Window_Driver::flush_double(int erase_overlay)
|
||||
#endif
|
||||
if (pWindow->damage() & ~FL_DAMAGE_EXPOSE) {
|
||||
fl_clip_region(i->region); i->region = 0;
|
||||
fl_window = other_xid;
|
||||
fl_window = other_xid->offscreen();
|
||||
# if defined(FLTK_HAVE_CAIROEXT)
|
||||
if (Fl::cairo_autolink_context()) Fl::cairo_make_current(pWindow);
|
||||
# endif
|
||||
@@ -181,7 +182,7 @@ void Fl_X11_Window_Driver::flush_double(int erase_overlay)
|
||||
if (erase_overlay) fl_clip_region(0);
|
||||
int X = 0, Y = 0, W = 0, H = 0;
|
||||
fl_clip_box(0, 0, w(), h(), X, Y, W, H);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid, X, Y);
|
||||
if (other_xid) fl_copy_offscreen(X, Y, W, H, other_xid->offscreen(), X, Y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
# include <cairo/cairo.h>
|
||||
#endif // FLTK_USE_CAIRO
|
||||
|
||||
class Fl_Image_Surface;
|
||||
|
||||
class Fl_Xlib_Copy_Surface_Driver : public Fl_Copy_Surface_Driver {
|
||||
friend class Fl_Copy_Surface_Driver;
|
||||
void end_current() FL_OVERRIDE;
|
||||
protected:
|
||||
Fl_Offscreen xid;
|
||||
Fl_Image_Surface *xid;
|
||||
Window oldwindow;
|
||||
Fl_Xlib_Copy_Surface_Driver(int w, int h);
|
||||
~Fl_Xlib_Copy_Surface_Driver();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Fl_Xlib_Copy_Surface_Driver.H"
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/platform.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include "../X11/Fl_X11_Screen_Driver.H"
|
||||
#if FLTK_USE_CAIRO
|
||||
@@ -39,9 +40,9 @@ Fl_Xlib_Copy_Surface_Driver::Fl_Xlib_Copy_Surface_Driver(int w, int h) : Fl_Copy
|
||||
float s = Fl_Graphics_Driver::default_driver().scale();
|
||||
driver()->scale(s);
|
||||
oldwindow = fl_window;
|
||||
xid = fl_create_offscreen(w,h);
|
||||
xid = new Fl_Image_Surface(w, h, 1);
|
||||
#if FLTK_USE_CAIRO
|
||||
cairo_surface_t *surf = cairo_xlib_surface_create(fl_display, xid, fl_visual->visual, w * s, h * s);
|
||||
cairo_surface_t *surf = cairo_xlib_surface_create(fl_display, xid->offscreen(), fl_visual->visual, w * s, h * s);
|
||||
cairo_ = cairo_create(surf);
|
||||
cairo_surface_destroy(surf);
|
||||
cairo_scale(cairo_, 1/s, 1/s);
|
||||
@@ -49,7 +50,7 @@ Fl_Xlib_Copy_Surface_Driver::Fl_Xlib_Copy_Surface_Driver(int w, int h) : Fl_Copy
|
||||
((Fl_X11_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_);
|
||||
#endif
|
||||
driver()->push_no_clip();
|
||||
fl_window = xid;
|
||||
fl_window = xid->offscreen();
|
||||
driver()->color(FL_WHITE);
|
||||
driver()->rectf(0, 0, w, h);
|
||||
fl_window = oldwindow;
|
||||
@@ -59,13 +60,13 @@ Fl_Xlib_Copy_Surface_Driver::Fl_Xlib_Copy_Surface_Driver(int w, int h) : Fl_Copy
|
||||
Fl_Xlib_Copy_Surface_Driver::~Fl_Xlib_Copy_Surface_Driver() {
|
||||
driver()->pop_clip();
|
||||
Window old_win = fl_window;
|
||||
fl_window = xid;
|
||||
fl_window = xid->offscreen();
|
||||
Fl_RGB_Image *rgb = Fl::screen_driver()->read_win_rectangle(0, 0, width, height, 0);
|
||||
fl_window = old_win;
|
||||
if (is_current()) end_current();
|
||||
Fl_X11_Screen_Driver::copy_image(rgb->array, rgb->w(), rgb->h(), 1);
|
||||
delete rgb;
|
||||
fl_delete_offscreen(xid);
|
||||
delete xid;
|
||||
#if FLTK_USE_CAIRO
|
||||
cairo_destroy(cairo_);
|
||||
#endif
|
||||
@@ -76,7 +77,7 @@ Fl_Xlib_Copy_Surface_Driver::~Fl_Xlib_Copy_Surface_Driver() {
|
||||
void Fl_Xlib_Copy_Surface_Driver::set_current() {
|
||||
Fl_Surface_Device::set_current();
|
||||
oldwindow = fl_window;
|
||||
fl_window = xid;
|
||||
fl_window = xid->offscreen();
|
||||
#if FLTK_USE_CAIRO
|
||||
((Fl_X11_Cairo_Graphics_Driver*)driver())->set_cairo(cairo_);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user