Greg Ercolano wrote:

>       Below is an interesting variation that just draws a black
>       rectangle with a 2 pixel white border, but every second
>       it alternates drawing the border:
> 
>               1) using fl_line_style(FL_SOLID,2) + fl_rect()
> 
>               2) using fl_line_style(FL_SOLID,0) + two fl_rect()s,
>                  one single pixel rect inside the other.

Yes, really interesting, nice demo.

>       Theoretically, both should look the same (though I guess it depends
>       which side of the dimensions the extra pixel thickness should go for
>       a two pixel thick line), but on all platforms you can see there's
>       flashing going on.

No, they shouldn't, because...

According to the docs, fl_rect() "Draws a 1-pixel border inside the 
given bounding box." Emphasis on "1-pixel" and "inside".

As I read this, Jane's original code is wrong, and the correct fix is to 
draw two fl_rect()'s, as she did already :-) .

However FLTK (maybe?) has a bug as well, because setting fl_line_style() 
_changes_ the behavior of fl_rect() WRT line width.

Although it is documented "If you change this it is your responsibility 
to set it back to the default using fl_line_style(0)", it is not 
completely clear (for me) if this means that you must _reset_ the line 
style before calling fl_rect(). If this is true, then everything else is 
undefined behavior, and FLTK is right. ;-)

>       On linux, with the line style set to 2, it looks like only the
>       right and bottom edges are drawn with two pixel thickness,
>       and the top and left edges are drawn with one.
> 
>       On windows, there's a pretty horrible thing going on at
>       the lower right corner, apparently dropping pixels.

So far I could only test on Windows. My additional observation: Changing 
the line style like below can fix the "dropping pixels" effect.

OTOH, with the default line settings (fl_line_style(0)), there is this 
missing pixel in the lower right corner, and this might be a real bug.

BUT: Without _any_ fl_line_style() call, there is a correct bottom right 
corner (no missing pixel). Now I'm really confused - fl_line_style(0) 
seems to be different from setting no line style at all :-(

>       So it seems like the only way to get pixel accurate
>       results is to leave the line style alone, and draw two
>       separate rectangles.

Right :-)

>       Here's the program described above:
> 
> #include <FL/Fl.H>
> #include <FL/Fl_Double_Window.H>
> #include <FL/fl_draw.H>
> #include <FL/Fl_Box.H>

Add this:

// #define LINE_STYLE FL_SOLID|FL_CAP_FLAT
// #define LINE_STYLE FL_SOLID|FL_CAP_ROUND
// #define LINE_STYLE FL_SOLID|FL_CAP_SQUARE
#define LINE_STYLE FL_SOLID

and experiment with different values, as shown below:

> class Foo: public Fl_Box {
>     int count;
>     void draw() {
>         fl_color(FL_BLACK);
>         fl_rectf(x(),y(),w(),h());
>         fl_color(FL_WHITE);
>         if ( count & 1 ) {
>             // use 2 pixel thick lines
>             fl_line_style(FL_SOLID, 1);

             fl_line_style(LINE_STYLE, 2); // (2 pixel test)

>             fl_rect(x(),y(),w(),h());
>             fl_line_style(FL_SOLID, 0);         // docs say we must leave it 
> at zero
>         } else {
>             // use 1 pixel thick lines, but draw two rects, one inside the 
> other
>             fl_line_style(FL_SOLID, 0);

             // fl_line_style(LINE_STYLE,0); // (also try this)
             fl_line_style(0); // (default line style)

>             fl_rect(x(),y(),w(),h());
>             fl_rect(x()+1,y()+1,w()-2,h()-2);
>         }
           fl_line_style(0);  // *always* reset line style

[rest of code snipped for brevity]

Albrecht
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to