| | [ Return to Bugs & Features | Roadmap 1.3 | SVN ⇄ GIT ]
STR #2257
| Application: | FLTK Library |
| Status: | 1 - Closed w/Resolution |
| Priority: | 3 - Moderate, e.g. unable to compile the software |
| Scope: | 2 - Specific to an operating system |
| Subsystem: | Core Library |
| Summary: | fl_read_image and fl_begin_offscreen not working on fltk-1.3 OSX |
| Version: | 1.3-current |
| Created By: | ianmacarthur |
| Assigned To: | manolo |
| Fix Version: | 1.3-current (SVN: v7650) |
| Update Notification: | |
Trouble Report Files:
Trouble Report Comments:
| |
| #1 | ianmacarthur 03:02 Sep 20, 2009 |
| I have a fairly complicated piece of code that makes extensive use of fl_offscreen to compose a complex scene, the fl_read_image to store that to file.
This builds and works fine with fltk-1.1, but I recently had to rebuild with fltk-1.3 and the fl_read_image no longer works correctly.
The fl_offscreen appears to be operating fine still.
This is either a fltk-1.3 regression, or it may be caused by our Quartz implementation (my fltk-1.1 build is QD based, but fltk-1.3 quite rightly has to use Quartz.)
Attached is a simple offscreen grab demo I wrote, along with the png helper utilities I use. If you compile this twice, once with fltk-1.1, once with fltk-1.3, you can see the effect.
From the attached png samples, it very much looks as if the offscreen is not made current for the fl_read_image to read from... This does sound like some sort of Quartz weirdness. I have not investigated in any detail, though. -- Ian | |
| |
| #2 | matt 02:01 Apr 05, 2010 |
| Manolo? Ist this still the case? | |
| |
| #3 | ianmacarthur 13:22 Apr 06, 2010 |
| Yes - using my test harness, this still fails with svn current on OSX.
AFAIK other hosts are OK, so this does seem to be some OSX specific regression.
Note that the actual offscreen drawing actually works fine (I use it a fair bit and it seems fine) it is just when I try to read it back and store it into the PNG that it fails and we get the wrong image. | |
| |
| #4 | ianmacarthur 06:17 Jun 16, 2010 |
| Alex Croy posted this to the fltk.dev list - I'm appending it here so we don't lose it...
--------------
the problem is that the current implementation of fl_read_image seems to make a screenshot of the current view (?) instead of accessing the offscreen bitmap. I think I found a solution for this with the routine below.
However, there is an additional problem: fl_begin_offscreen and fl_end_offscreen currently do not reset (or clear) the clipping region, which doesn't matter if your make a screenshot. The respective code is actually commented out in Fl_Double_Window. IMHO the calls to fl_push_no_clip and fl_pop_clip should be the last and first calls in l_begin_offscreen and fl_end_offscreen, respectively.
Hope that helps somehow ...
- Alex
-------------------- Here comes the "new" fl_read_image routine:
uchar * // O - Pixel buffer or NULL if failed fl_read_image_crutch( uchar *p, // I - Pixel buffer or NULL to allocate int x, // I - Left position int y, // I - Top position int w, // I - Width of area to read int h, // I - Height of area to read int alpha) { // I - Alpha value for image (0 for none)
if(fl_window == (void *)0) { // sufficient condition for having an // active offscreen buffer??
CGContextRef src = (CGContextRef)fl_gc; // get bitmap context
uchar *base = (uchar *)CGBitmapContextGetData(src); // get data
if(!base) return NULL;
int sw = CGBitmapContextGetWidth(src); int sh = CGBitmapContextGetHeight(src); // CGImageAlphaInfo bmpalpha = CGBitmapContextGetAlphaInfo(src); int rowBytes = CGBitmapContextGetBytesPerRow(src); int delta = CGBitmapContextGetBitsPerPixel(src)/8;
if( (sw - x > w) || (sh - y > h) ) return NULL;
// Allocate the image data array as needed... int d = alpha ? 4 : 3;
printf("%i %i %i %i %i\n", sw, sh, rowBytes, delta, d); // DEBUG
if (!p) p = new uchar[w * h * d]; // Initialize the default colors/alpha in the whole image... memset(p, alpha, w * h * d);
// Copy the image from the off-screen buffer to the memory buffer. int idx, idy; // Current X & Y in image uchar *pdst, *psrc; for (idy = 0, pdst = p; idy < h; idy ++) { for (idx = 0, psrc = base + (idy + y) * rowBytes + x; idx < w; idx ++, psrc += delta, pdst += d) { pdst[0] = psrc[0]; // R pdst[1] = psrc[1]; // G pdst[2] = psrc[2]; // B } } return p; } else { // no active offscreen, use "old code" return fl_read_image(p, x, y, w, h, alpha); } } | |
| |
| #5 | manolo 09:33 Jun 18, 2010 |
| Fixed in Subversion repository. | |
| |
| #6 | manolo 09:51 Jun 18, 2010 |
| Alex's patch has been uploaded (in essence) and found to correct this bug.
About the clipping issue: - fl_push_noclip() and fl_pop_clip() calls have always been commented out in 1.3, for some reason I am not sure about. - in 1.1, they are commented out in the Quartz version of fl_begin_offscreen/fl_end_offscreen, but are active in their Quickdraw version, thus the code doesn't seem completely coherent. - the attached program that displays the bug writes to the offscreen buffer by these statements: fl_begin_offscreen(offscr); // draw the widget hierarchy of this group into the offscreen Fl_Group::draw(); fl_end_offscreen(); and, as already reported, even with Alex's change, the resulting offscreen buffer is clipped of some buttons. But this is not a result of the offscreen buffer, but of Fl_Group::draw() which does not draw what is outside its window. I think this behavior is logical, and believe the test program should be re-written: fl_begin_offscreen(offscr); // draw the widget hierarchy of this group into the offscreen fl_push_no_clip(); Fl_Group::draw(); fl_pop_clip(); fl_end_offscreen(); because it's the drawing function caller's responsibility to control the current clipping state when he/she draws. | |
[ Return to Bugs & Features ]
|
| |