> Could you, please, post a simple code example that displays > the problem ? This would be very helpful. > Also, specify whether you are on snow leopard or not, because > there are small peculiarities of snow leopard on this topic.
Sure, code is at the bottom. This is all on 10.5.8. Now, when compiled on 1.1.9, this shows a rect with a one pixel red line, a rect with a two pixel red line, and the third rect is not drawn at all. It prints: clip rect: 10 10 x 1 20 clip rect: 10 50 x 2 20 So that all makes sense. When compiled on fltk-1.3.x-r7008, the first rect has no red line (so a clip of width 1 is mistaken as a complete clip), the second has two pixels (so that's correct), and the third rect isn't clipped, and shows up (so a clip of width 0 does nothing). And it prints: clip rect: 0 0 x 0 0 clip rect: 10 50 x 1 19 So it looks like for some reason OS X clip functions are clipping one pixel *wider* than the given rect, so fltk subtracts 1 to compensate. Except OS X doesn't add 1 to 0, so when you pass 1, fltk makes it zero and OS X goes ahead and clips it all... even though CGRectIsEmpty is false for this zero width rect. Then if you pass 0, it becomes -1, which is finally considered "empty", and so MacRectRegionIntersect ignores it entirely. And... fltk doesn't add 1 back on when it returns it from fl_clip_box, so using this to add a new clip successively shaves off pixels. As far as the solution, I haven't looked into that much yet, I don't really know anything about OS X graphics programming. Obviously the best thing would be to figure out what's up with this +1 behaviour and turn it off. The docs for CGContextClipToRects [1] says only that "The locations and dimensions of the rectangles are specified in the user space coordinate system." I don't know what user space coordinate systems are on OS X, but maybe there's something wrong there. Otherwise, we can add specific hacks for ==0, ==1, and >1, but I wouldn't have a lot of trust that it will continue to work without understanding the underlying cause. BTW, fl_rect.cxx:fl_push_clip is a real mess of #ifdefs. In fact the whole file is like that. Isn't the idea to separate platform specific files? If I made a patch that separated it out, at the cost of some code duplication, would it be accepted? And this stuff about __APPLE_QUARTZ__ and __APPLE_COCOA__ overlapping is confusing, shouldn't they be exclusive? Also, on a similar subject, wouldn't it be better to conditionally compile Fl_cocoa.mm and fl_color_mac.cxx etc. from the build system rather than using #include? It's confusing. Also also while I'm in a cleanup mood... how about someday removing reference output params like fl_clip_box? Ref args should be const, output args should be pointers. Adding a new function and deprecating the old one is ok too, as long as we eventually get rid of deprecated stuff (fl_clip() is still around...). [1] http://developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextClipToRects #include <stdio.h> #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Box.H> #include <FL/fl_draw.H> struct Rect { Rect(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {} int x, y, w, h; }; static void print_clip() { Rect r(0, 0, 0, 0); fl_clip_box(0, 0, 9999, 9999, r.x, r.y, r.w, r.h); printf("clip rect: %d %d x %d %d\n", r.x, r.y, r.w, r.h); } class Box : public Fl_Box { public: Box(int x, int y, int w, int h) : Fl_Box(x, y, w, h) { box(FL_THIN_DOWN_BOX); color(FL_WHITE); } void draw() { Fl_Box::draw(); fl_push_clip(0, 0, w(), h()); fl_color(FL_BLACK); fl_rectf(10, 10, 50, 20); fl_push_clip(10, 10, 1, 20); print_clip(); fl_color(FL_RED); fl_rectf(0, 0, 30, 100); fl_pop_clip(); fl_color(FL_BLACK); fl_rectf(10, 50, 50, 20); fl_push_clip(10, 50, 2, 20); print_clip(); fl_color(FL_RED); fl_rectf(0, 50, 30, 100); fl_pop_clip(); fl_push_clip(10, 100, 0, 20); fl_rectf(10, 100, 50, 20); fl_pop_clip(); fl_pop_clip(); } }; int main(int argc, char **argv) { Fl_Double_Window win(100, 100, 200, 200); Box box(0, 0, 200, 200); win.show(argc, argv); Fl::run(); return 0; } _______________________________________________ fltk-dev mailing list [email protected] http://lists.easysw.com/mailman/listinfo/fltk-dev
