Ian MacArthur wrote:
>
> > What do I make wrong?
>
> I'm not sure - can you post a minimal, compileable, example that shows
> the failing behaviour?
>
The 'minimal, compileable, example' is attached.
I have inserted some trace code into fl_rect.cxx and Fl_Image.cxx .
The example image is the APACHE 'feather-508x398.jpg'.
The image RECT(5,-29,508,398)
is said to be completely outside
the clip RECT(5,69,508,300)
NOTE:
-----
Let FORCE_EXPOSE mean 'overlay the fltk window completely with
another window and make the fltk window the top window again'.
1x1-case:
When an image of 1x1 is followed by an image of say 10x10,
the new image becomes visible only with FORCE_EXPOSE.
same-height-case:
When an image 30x100 is followed by an image of say 30x30,
the new image is shown above the previous image. One has
to wipe out the previous image with FORCE_EXPOSE.
Both cases are observed only with fltk-1.3, not with fltk-2.0 .
====================== fltk-1.3.x-r7339 ====================
fl_rect.cxx:590:Fl_Device::push_clip(172,41,410,21)
cur((nil)) new(0x809ea70)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809ea70)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809ea70
fl_rect.cxx:590:Fl_Device::push_clip(513,86,17,266) <== VBAR
cur((nil)) new(0x809eaa8)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809eaa8)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809eaa8
canvas->draw count(1)
IMG(508,398)
WIN(611,374)
CANVAS(5,69,525,300)
CLIP(5,69,508,300)
HBAR has(0) val(0)
VBAR has(17) val(0)
SCROLL(0,0)
fl_rect.cxx:590:Fl_Device::push_clip(5,69,508,300) <== CLIP_RECT
cur((nil)) new(0x809eaa8)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809eaa8)
Fl_Image.cxx:447:ENTER Fl_RGB_Image::draw
IN(5,69,508,398) C(0,0)
IMG(508,398)
fl_rect.cxx:692:Fl_Device::clip_box
Region 0x809eaa8
fl_rect.cxx:717:Fl_Device::clip_box
IN(5,69,508,398) is intersected:
OUT(5,69,508,300)
Fl_Image.cxx:451:Fl_RGB_Image::draw
CLIP(5,69,508,300)
Fl_Image.cxx:457:Fl_RGB_Image::draw
C(0,0) W(508)
Fl_Image.cxx:462:Fl_RGB_Image::draw
C(0,0) H(300)
fl_rect.cxx:644:Fl_Device::pop_clip (nil)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809eaa8
fl_rect.cxx:590:Fl_Device::push_clip(172,41,410,21)
cur(0x809eaa8) new(0x809f3f8)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809f410)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809f410
fl_rect.cxx:590:Fl_Device::push_clip(513,86,17,266) <== VBAR
cur(0x809eaa8) new(0x809f3f8)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809f428)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809f428
canvas->draw count(2)
IMG(508,398)
WIN(611,374)
CANVAS(5,69,525,300)
CLIP(5,69,508,300)
HBAR has(0) val(0)
VBAR has(17) val(0)
SCROLL(0,0)
fl_rect.cxx:590:Fl_Device::push_clip(5,69,508,300) <== CLIP_RECT
cur(0x809eaa8) new(0x809f428)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x809efc0)
Fl_Image.cxx:447:ENTER Fl_RGB_Image::draw
IN(5,69,508,398) C(0,0)
IMG(508,398)
fl_rect.cxx:692:Fl_Device::clip_box
Region 0x809efc0
fl_rect.cxx:717:Fl_Device::clip_box
IN(5,69,508,398) is intersected:
OUT(5,69,508,300)
Fl_Image.cxx:451:Fl_RGB_Image::draw
CLIP(5,69,508,300)
Fl_Image.cxx:457:Fl_RGB_Image::draw
C(0,0) W(508)
Fl_Image.cxx:462:Fl_RGB_Image::draw
C(0,0) H(300)
fl_rect.cxx:644:Fl_Device::pop_clip 0x809efc0
fl_rect.cxx:590:Fl_Device::push_clip(513,86,17,266) <== VBAR
cur(0x809f3f8) new(0x809eaa8)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x80a0780)
fl_rect.cxx:644:Fl_Device::pop_clip 0x80a0780
canvas->draw count(3)
IMG(508,398)
WIN(611,374)
CANVAS(5,69,525,300)
CLIP(5,69,508,300)
HBAR has(0) val(0)
VBAR has(17) val(98) <== FL_End
SCROLL(0,98)
fl_rect.cxx:590:Fl_Device::push_clip(5,69,508,300) <== CLIP_RECT
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cur(0x809f3f8) new(0x80a0780)
fl_rect.cxx:626:Fl_Device::push_clip TOP(0x80a07a8)
Fl_Image.cxx:447:ENTER Fl_RGB_Image::draw
IN(5,-29,508,398) C(0,0)
IMG(508,398)
fl_rect.cxx:692:Fl_Device::clip_box
Region 0x80a07a8
fl_rect.cxx:698:Fl_Device::clip_box
IN(5,-29,508,398) is completely outside
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fl_Image.cxx:451:Fl_RGB_Image::draw
CLIP(5,-29,0,0)
Fl_Image.cxx:457:Fl_RGB_Image::draw
C(0,0) W(0)
fl_rect.cxx:644:Fl_Device::pop_clip 0x80a07a8
--------------- the minimal example code ---------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/Enumerations.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Scrollbar.H>
#include <FL/x.H>
#define CLICK_STEP 16
#define CURSOR_STEP 16
#define PAGE_STEP 64
#define DEFAULT_BACKGROUND FL_LIGHT1
#define DEFAULT_CANVAS_BACKGROUND FL_DARK2
static Fl_Double_Window *main_win;
static int win_w, win_h;
/*============================*/
#define MAX_CLIP_W 700
#define MAX_CLIP_H 300
/*============================*/
#define BAR_SIZE 17
#define WIN_X 50
#define WIN_Y 50
#define CANVAS_MIN_W 5
#define CANVAS_MIN_H 5
#define BORDER_SIZE 5
#define BUTTON_W 80
#define BUTTON_H 25
#define NG_GROUP_W BUTTON_W*5 + 4
#define NG_GROUP_H BUTTON_H + 4
#define HEADER_H 69
#define HEADER_W NG_GROUP_W + 2 * (BUTTON_W + 10)
#define WINDOW_MIN_W HEADER_W + BORDER_SIZE + BORDER_SIZE
#define WINDOW_MIN_H HEADER_H + CANVAS_MIN_H + BORDER_SIZE
#ifdef DEBUG_DRAW
static int draw_count;
#endif
class Canvas: public Fl_Group
{
virtual void draw();
unsigned int iwidth, iheight;
Fl_Shared_Image *sim, *new_sim;
Fl_Scrollbar *vbar, *hbar;
int handle(int);
Fl_Color bgc;
int has_bgc, clip_w, clip_h, drag_x, drag_y;
unsigned char bgred, bggreen, bgblue;
public:
Canvas(int x,int y,int w,int h, const char *l);
Fl_Double_Window *win;
int vbar_min_y, vbar_max_y;
int hbar_min_x, hbar_max_x;
void draw_sim(const char *n);
void put_bgcolor(unsigned char r, unsigned char g, unsigned char b)
{
bgred = r; bggreen = g; bgblue = b; has_bgc = 1;
}
};
Canvas::Canvas(int view_x,int view_y,int view_w,int view_h,const char *l)
:Fl_Group(view_x, view_y, view_w, view_h, l)
{
//AUTO IN FLTK13: begin();
// color(DEFAULT_CANVAS_BACKGROUND);
box(FL_FLAT_BOX);
sim = new_sim = NULL;
iwidth = iheight = 0;
bgc = FL_RED; has_bgc = 0;
vbar = new Fl_Scrollbar(view_w - BAR_SIZE, 0, BAR_SIZE, view_h -
BAR_SIZE);
vbar->value(0, view_h, 0, CANVAS_MIN_H);
vbar->step(8.0);
vbar->align(FL_ALIGN_RIGHT);
vbar->type(FL_VERTICAL);
vbar->linesize(PAGE_STEP);
hbar = new Fl_Scrollbar(0, view_h - BAR_SIZE, view_w - BAR_SIZE,
BAR_SIZE);
hbar->value(0, view_w, 0, CANVAS_MIN_W);
hbar->step(8.0);
hbar->align(FL_ALIGN_BOTTOM);
hbar->type(FL_HORIZONTAL);
hbar->linesize(PAGE_STEP);
vbar_min_y = BAR_SIZE;
vbar_max_y = vbar->h() - BAR_SIZE;
hbar_min_x = BAR_SIZE;
hbar_max_x = hbar->w() - BAR_SIZE;
clip_w = clip_h = 0;
drag_x = drag_y = 0;
fl_register_images();
win = main_win;
end();
}
static Canvas *canvas;
int Canvas::handle(int event)
{
int ex, ey, scroll_x, scroll_y, ek, max, dx, dy, step;
if(!Fl::event_inside(x(), y(), w(), h() ) ) return 0;
if(!hbar->visible() && !vbar->visible()) return 1;
ex = Fl::event_x(); ey = Fl::event_y(); step = 0;
switch(event)
{
case FL_PUSH://event_key():LeftButton==1,MiddleButton==2,RightButton==3
/*==================*/
/* VBAR EVENT: */
if(vbar->visible()
&& ex >= vbar->x()
&& ex < vbar->x() + vbar->w()
&& ey >= vbar->y()
&& ey < vbar->y() + vbar->h())
{
scroll_y = vbar->value();
if(scroll_y > 0 && ey <= y() + scroll_y + vbar_min_y)
{
step = -CLICK_STEP;
}
else
if(ey >= y() + scroll_y + vbar->slider_size())
{
step = CLICK_STEP;
}
max = iheight - clip_h;
if(step > 0 && scroll_y >= max) return 1;
if(step == 0) return 1;
if(step < 0 && scroll_y == 0) return 1;
scroll_y += step;
if(step > 0 && scroll_y > max)
scroll_y = max;
else
if(scroll_y < 0) scroll_y = 0;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
/* HBAR EVENT: */
if(hbar->visible()
&& ex >= hbar->x()
&& ex < hbar->x() + hbar->w()
&& ey >= hbar->y()
&& ey < hbar->y() + hbar->h())
{
scroll_x = hbar->value();
if(scroll_x > 0 && ex <= hbar_min_x + scroll_x + x())
{
step = -CLICK_STEP;
}
else
if(ex >= scroll_x + hbar->slider_size() + x())
{
step = CLICK_STEP;
}
max = iwidth - clip_w;
if(step == 0) return 1;
if(step > 0 && scroll_x >= max) return 1;
if(step < 0 && scroll_x == 0) return 1;
scroll_x += step;
if(step > 0 && scroll_x > max)
scroll_x = max;
else
if(scroll_x < 0) scroll_x = 0;
hbar->value(scroll_x, clip_w, 0, iwidth);
return 1;
}
break;
case FL_MOUSEWHEEL:
/*==================*/
if(vbar->visible() && (dy = Fl::event_dy()))
{
max = iheight - clip_h;
scroll_y = vbar->value();
if(dy < 0 && scroll_y == 0) return 1;
if(dy > 0 && scroll_y == max) return 1;
scroll_y += dy * CURSOR_STEP;
if(scroll_y < 0) scroll_y = 0;
else
if(scroll_y > max) scroll_y = max;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
if(hbar->visible() && (dx = Fl::event_dx()))
{
max = iwidth - clip_w;
scroll_x = hbar->value();
if(dx < 0 && scroll_x == 0) return 1;
if(dx > 0 && scroll_x == max) return 1;
scroll_x += dx * CURSOR_STEP;
hbar->value(scroll_x, clip_w, 0, iwidth);
return 1;
}
return 1;
case FL_SHORTCUT:
/*==================*/
ek = Fl::event_key(); scroll_x = hbar->value(); scroll_y =
vbar->value();
if(vbar->visible())
{
if(ek == FL_Home)
{
if(scroll_y > 0)
vbar->value(0, clip_h, 0, iheight);
return 1;
}
if(ek == FL_End)
{
max = iheight - clip_h;
if(scroll_y < max)
vbar->value(max, clip_h, 0, iheight);
return 1;
}
if(ek == FL_Page_Up)
{
if(scroll_y == 0) return 1;
if((scroll_y = vbar->value() - vbar->linesize()) < 0) scroll_y = 0;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
if(ek == FL_Page_Down)
{
max = iheight - clip_h;
if(scroll_y == max) return 1;
if((scroll_y = vbar->value() + vbar->linesize()) > max) scroll_y = max;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
if(ek == FL_Up)
{
if(scroll_y == 0) return 1;
if((scroll_y = vbar->value() - CURSOR_STEP) < 0) scroll_y = 0;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
if(ek == FL_Down)
{
max = iheight - clip_h;
if(scroll_y == max) return 1;
if((scroll_y = vbar->value() + CURSOR_STEP) > max) scroll_y = max;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
} /* if(vbar->visible()) */
if(hbar->visible())
{
if(ek == FL_Left)
{
if(scroll_x == 0) return 1;
if((scroll_x = hbar->value() - CURSOR_STEP) < 0) scroll_x = 0;
hbar->value(scroll_x, clip_w, 0, iwidth);
return 1;
}
if(ek == FL_Right)
{
max = iwidth - clip_w;
if(scroll_x == max) return 1;
if((scroll_x = hbar->value() + CURSOR_STEP) > max) scroll_x = max;
hbar->value(scroll_x, clip_w, 0, iwidth);
return 1;
}
}
break;
case FL_DRAG:
/* VBAR EVENT: */
if(vbar->visible()
&& ex >= vbar->x()
&& ex < vbar->x() + vbar->w()
&& ey >= vbar->y()
&& ey < vbar->y() + vbar->h())
{
if(ey > drag_y)
step = 3;
else
if(ey < drag_y)
step = -3;
else
return 1;
drag_y = ey;
scroll_y = vbar->value();
max = iheight - clip_h;
if(step > 0 && scroll_y >= max) return 1;
if(step == 0) return 1;
if(step < 0 && scroll_y == 0) return 1;
scroll_y += step;
if(step > 0 && scroll_y > max)
scroll_y = max;
else
if(scroll_y < 0) scroll_y = 0;
vbar->value(scroll_y, clip_h, 0, iheight);
return 1;
}
/* HBAR EVENT: */
if(hbar->visible()
&& ex >= hbar->x()
&& ex < hbar->x() + hbar->w()
&& ey >= hbar->y()
&& ey < hbar->y() + hbar->h())
{
if(ex > drag_x)
step = 3;
else
if(ex < drag_x)
step = -3;
else
return 1;
drag_x = ex;
scroll_x = hbar->value();
max = iwidth - clip_w;
if(step > 0 && scroll_x >= max) return 1;
if(step == 0) return 1;
if(step < 0 && scroll_x == 0) return 1;
scroll_x += step;
if(step > 0 && scroll_x > max)
scroll_x = max;
else
if(scroll_x < 0) scroll_x = 0;
hbar->value(scroll_x, clip_w, 0, iwidth);
return 1;
}
default: break;
/*==================*/
}
return (Fl_Group::handle(event));
}/* Canvas::handle() */
void Canvas::draw()
{
int init = 0;
if(new_sim)
{
sim = new_sim; new_sim = NULL; init = 1;
iwidth = sim->w(); iheight = sim->h();
}
if(sim)
{
int clip_x, clip_y, win_w, win_h, has_vbar, has_hbar;
int sx, sy, sw, sh;
has_hbar = has_vbar = 0;
if((clip_w = iwidth) > MAX_CLIP_W) has_hbar = BAR_SIZE;
if((clip_h = iheight) > MAX_CLIP_H) has_vbar = BAR_SIZE;
if(has_hbar)
{
clip_w = win_w = MAX_CLIP_W;
}
else
if(clip_w > HEADER_W)
{
win_w = clip_w;
}
else win_w = HEADER_W;
win_w += BORDER_SIZE + BORDER_SIZE + has_vbar;
if(has_vbar)
{
clip_h = MAX_CLIP_H;
}
win_h = HEADER_H + has_hbar + clip_h + BORDER_SIZE;
clip_x = x(); clip_y = y();
sw = clip_w + has_vbar; sh = clip_h + has_hbar;
main_win->resize(WIN_X, WIN_Y, win_w, win_h);
resize(x(), y(), sw, sh);
if(has_vbar)
{
vbar->set_visible();
vbar->resize(clip_x + clip_w, clip_y,BAR_SIZE,clip_h);
draw_child(*vbar);
if(init)
{
drag_y = 0;
vbar->value(0, clip_h, 0, iheight);
}
sy = vbar->value();
}
else
{
vbar->hide(); vbar->clear_visible(); sy = 0;
}
if(has_hbar)
{
hbar->set_visible();
hbar->resize(clip_x, clip_y + clip_h,clip_w,BAR_SIZE);
draw_child(*hbar);
if(init)
{
drag_x = 0;
hbar->value(0, clip_w, 0, iwidth);
}
sx = hbar->value();
}
else
{
hbar->hide(); hbar->clear_visible(); sx = 0;
}
fl_push_clip(clip_x, clip_y, clip_w, clip_h);
if(sim)
{
sim->draw(clip_x - sx, clip_y - sy);
}
fl_pop_clip();
return;
}
fl_color(bgred, bggreen, bgblue);
fl_rectf(x(), y(), w(), h());
}/* Canvas::draw() */
void Canvas::draw_sim(const char *n)
{
new_sim = Fl_Shared_Image::get(n);
redraw();
}
int main(int argc, char *argv[])
{
const char *fname;
int x, y;
if(argc != 2) return 1;
Fl::visual(FL_RGB);
fname = argv[1];
win_w = WINDOW_MIN_W; win_h = WINDOW_MIN_H;
main_win = new Fl_Double_Window(WIN_X, WIN_Y, win_w, win_h);
main_win->color(DEFAULT_BACKGROUND);
//AUTO IN FLTK13: main_win->begin();
x = BORDER_SIZE; y = BORDER_SIZE;
canvas = new Canvas(x,y,CANVAS_MIN_W,CANVAS_MIN_H, NULL);
{
unsigned char rc, gc, bc;
Fl::get_color(DEFAULT_CANVAS_BACKGROUND, rc, gc, bc);
canvas->put_bgcolor(rc, gc, bc);
}
main_win->resizable(canvas);
main_win->end();
canvas->win = main_win;
main_win->show();
canvas->draw_sim(fname);
return Fl::run();
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk