On 22.04.2017 00:48 Greg Ercolano wrote:
> On 04/21/17 13:50, Will B wrote:
>> As requested, I have made a compilable example which outputs the warning to the terminal:
>
> Great, much thanks.
>
> I can confirm on Linux/X11:
>
> On 1.3.x svn current, it prints the "fl_pop_clip: clip stack underflow!"
> warnings once per second, and draws a green rectangle in a gray window.
>
> On 1.4.x svn current, there's no warning, but only draws a gray window.
> (No green rectangle)
In the original code version Fl_Image_Surface::image() is called while
the current drawing context is set to the screen driver. This failed to
read the image from the the image surface surfImg in FLTK 1.4 whereas it
obviously (kinda) "works" in FLTK 1.3 with the 'clip stack underflow'
warning.
IMO Fl_Image_Surface::image() _must_ work always independent of the
current drawing context, and the fix was pretty straightforward in FLTK
1.4 (svn r12221):
Fl_RGB_Image* Fl_Xlib_Image_Surface_Driver::image()
{
+ push_current(this);
unsigned char *data = fl_read_image(NULL, 0, 0, width, height, 0);
+ pop_current();
...
@Manolo: please feel free to change this fix if you can find a better
way to do it. I thought of calling read_win_rectangle(..) directly but
couldn't find a way to set up the correct driver context. I'm also
afraid that the same issue might be on other platforms, but I didn't
test any other platforms yet.
> However, if I adjust the code as per Chris's suggestion:
>
> On 1.3.x svn current, no warnings, and draws the green rectangle.
> On 1.4.x svn current, no warnings, and draws the green rectangle.
This is a workaround that works for FLTK 1.3 and is no longer necessary
for FLTK 1.4 since r12221.
Thanks to Chris for the hint, BTW.
> So sounds like Chris's suggestion on re-ordering is the way to go,
> as this works consistently on both versions of FLTK.
Since this is no longer necessary and was certainly not intended I
wouldn't want to recommend it.
> I assume this is the intended use case we should document.
> Awaiting info from the devs familiar with the image surface abstraction,
> as I am not.
As I wrote above, Fl_Image_Surface::image() must work no matter what the
current drawing context is. My modified code shows another situation
where surface creation and the draw() method that extracts the image are
separated. This version works well in FLTK 1.4 (r12221).
Unfortunately this will not work in FLTK 1.3 and since we can't change
the docs I don't know what to do (other than fix it and issue 1.3.5).
Here's the modified example code:
-- snip --
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Image_Surface.H>
Fl_Image_Surface* surfImg = 0;
// Create image surface and draw a green rectangle onto it
void create_image (void)
{
// create image surface
surfImg = new Fl_Image_Surface(1024, 740);
//// tell fltk to draw onto the image surface from now on
surfImg->set_current();
fl_rectf(0, 0, 1024, 740, 100, 255, 100);
//// tell fltk to draw onto the screen from now on
Fl_Display_Device::display_device()->set_current();
}
// read the image surface and draw it on the screen (window)
void draw (void*)
{
//// create rgb image from image surface image
Fl_RGB_Image* imgI = surfImg->image();
//// set appropriate scale quality
imgI->RGB_scaling(FL_RGB_SCALING_BILINEAR);
//// scale down imgI image to imgC
Fl_Image* imgC = imgI->copy(400, 300);
//// draw scaled image onto screen
imgC->draw(400, 300);
delete imgI;
delete imgC;
Fl::repeat_timeout(1.0, draw);
}
/* main program */
int main(int argc, char **argv)
{
Fl_Window *window = new Fl_Window(1024, 740);
window->end();
window->show(argc, argv);
Fl::add_timeout(1.0, draw);
create_image(); // notice: create image surface here
return Fl::run();
}
-- snip --