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

Reply via email to