PC Review


Reply
Thread Tools Rate Thread

Bug: DrawRectangle...*or* Rectangle

 
 
James F. Bellinger
Guest
Posts: n/a
 
      25th Aug 2003
DrawRectangle draws from Left to Right, it appears.
However, Rectangle seems to think the rectangle does
not include the pixel referred to in its Right property..
the range includes Left and every pixel up to but not
including Right.

You can see this strange inconsistency (though at which
of the two it should be changed, I'm not sure ... I'd say
DrawRectangle, and then Rectangle needs to have clearer
documentation (largely because going:

for (int i = r.Top; i < r.Bottom; i ++)

Seems the way one would normally do things. You can see it
by doing a DrawRectangle, constructing a Rectangle using
the override that accepts a Size parameter. The right and bottom
edges of the rectangle will be one pixel off. :-)

Have a nice day
Jim Bellinger


 
Reply With Quote
 
 
 
 
100
Guest
Posts: n/a
 
      25th Aug 2003
Hi James,
I've found this inconsisitency only with pens with width of 1. If you create
a pen with width more the 1 (2 let say) and set pen's alignment to
PenAlignment.Inset the rectangle will be exactly Rectangle.Width pixels wide
and Rectangle.Height pixels high.
In the book "Programming MS Windows with c#" Charles Petzold gives some
unclear explanation why when the pen's width is set to 1 the rectangle is 1
pixel higher and 1 pixel wider, which makes me think that MS finds this
reasonable. Anyways, I remember the way he explained to us the off-by-1
error in GDI in his book about Win32 and I feel that in his new book about
..NET he just tries the get off the subject as quick as it possible.

In GDI the drawing functions draw objects from the first point, up to the
last point but not including the last point. This decision was made to make
drawing connected lines with LineTo easier. If the last point was drawn this
would cause some points to be drawn twice, which in some ROPs could be
unallowable.

In GDI+ there are no ROPs so the lines can be drawn including the last
point. And it is as is. The same doesn't go for rectangles though. Let say
we want to draw a grid which lines are 1 pixel wide (I dare to say most of
the grids use lines 1 pixel wide ).
It could be done in several ways. And one of them is to use DrawRectangle or
DrawRectangles methods do draw the grid cells.
One posible drawing of grid 2x2 is:

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
Pen pen = new Pen(Color.Red,1);

Rectangle[] r = new Rectangle[4]{new Rectangle(10, 10, 10, 10), new
Rectangle(20, 10, 10, 10), new Rectangle(10, 20, 10, 10), new Rectangle(20,
20, 10, 10)};
e.Graphics.DrawRectangles(pen, r);
}

The numbers used for the rectangles are pretty obvious and the the grid
looks exactly how it has to look. If it wasn't that off-by-1 the grid will
be surrounded with 1-pixel-wide line and the internal lines will be 2 pixels
wide or we would have used some others *not so obvious* numbers.

According to what MS did in Win32's GDI I believe this is the main reason
for this strange inconsisitency.

B\rgds
100

"James F. Bellinger" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> DrawRectangle draws from Left to Right, it appears.
> However, Rectangle seems to think the rectangle does
> not include the pixel referred to in its Right property..
> the range includes Left and every pixel up to but not
> including Right.
>
> You can see this strange inconsistency (though at which
> of the two it should be changed, I'm not sure ... I'd say
> DrawRectangle, and then Rectangle needs to have clearer
> documentation (largely because going:
>
> for (int i = r.Top; i < r.Bottom; i ++)
>
> Seems the way one would normally do things. You can see it
> by doing a DrawRectangle, constructing a Rectangle using
> the override that accepts a Size parameter. The right and bottom
> edges of the rectangle will be one pixel off. :-)
>
> Have a nice day
> Jim Bellinger
>
>



 
Reply With Quote
 
James F. Bellinger
Guest
Posts: n/a
 
      26th Aug 2003

"100" <(E-Mail Removed)> wrote in message
news:%(E-Mail Removed)...
> Hi James,
> I've found this inconsisitency only with pens with width of 1. If you

create
> a pen with width more the 1 (2 let say) and set pen's alignment to
> PenAlignment.Inset the rectangle will be exactly Rectangle.Width pixels

wide
> and Rectangle.Height pixels high.
> In the book "Programming MS Windows with c#" Charles Petzold gives some
> unclear explanation why when the pen's width is set to 1 the rectangle is

1
> pixel higher and 1 pixel wider, which makes me think that MS finds this
> reasonable. Anyways, I remember the way he explained to us the off-by-1
> error in GDI in his book about Win32 and I feel that in his new book about
> .NET he just tries the get off the subject as quick as it possible.
>
> In GDI the drawing functions draw objects from the first point, up to the
> last point but not including the last point. This decision was made to

make
> drawing connected lines with LineTo easier. If the last point was drawn

this
> would cause some points to be drawn twice, which in some ROPs could be
> unallowable.


It does make sense for lines... though I can't think of any real-life
use for an XOR pen. :-)

> In GDI+ there are no ROPs so the lines can be drawn including the last
> point. And it is as is. The same doesn't go for rectangles though. Let say
> we want to draw a grid which lines are 1 pixel wide (I dare to say most of
> the grids use lines 1 pixel wide ).
> It could be done in several ways. And one of them is to use DrawRectangle

or
> DrawRectangles methods do draw the grid cells.
> One posible drawing of grid 2x2 is:
>
> protected override void OnPaint(PaintEventArgs e)
> {
> base.OnPaint (e);
> Pen pen = new Pen(Color.Red,1);
>
> Rectangle[] r = new Rectangle[4]{new Rectangle(10, 10, 10, 10), new
> Rectangle(20, 10, 10, 10), new Rectangle(10, 20, 10, 10), new

Rectangle(20,
> 20, 10, 10)};
> e.Graphics.DrawRectangles(pen, r);
> }
>
> The numbers used for the rectangles are pretty obvious and the the grid
> looks exactly how it has to look. If it wasn't that off-by-1 the grid will
> be surrounded with 1-pixel-wide line and the internal lines will be 2

pixels
> wide or we would have used some others *not so obvious* numbers.


Regardless of whether the numbers are obvious or not, it's patently absurd
that you've just told it the rectangles are 10x10 and it is painting them
11x11. :-)
The pixels should be two wide in that example, because you've asked it to
make a bunch of boxes that are 10x10, 10 pixels apart from each other.
Ugh. *does not compute*.

There's no reason for them to keep this, except that Windows Forms (and
System.Drawing by extension) is a cheesy hack over Win32's forms, albeit one
nice in some areas like the designer support (though it's hard to forgive
the fact
that some controls work like .Net ones and some don't -- just today I
encountered
the fact that ClientSize does not work for ListViews... joy...).

At best, I would think it could at least not lie in the Width and Height
parameters.
When I give it a Size parameter saying it needs to be 10 wide and 10 tall,
it should
do that. :-) But I know, it won't. :-)

> According to what MS did in Win32's GDI I believe this is the main reason
> for this strange inconsisitency.
>
> B\rgds
> 100


Thanks
Jim Bellinger


 
Reply With Quote
 
100
Guest
Posts: n/a
 
      26th Aug 2003
Hi James,
> > protected override void OnPaint(PaintEventArgs e)
> > {
> > base.OnPaint (e);
> > Pen pen = new Pen(Color.Red,1);
> >
> > Rectangle[] r = new Rectangle[4]{new Rectangle(10, 10, 10, 10), new
> > Rectangle(20, 10, 10, 10), new Rectangle(10, 20, 10, 10), new

> Rectangle(20,
> > 20, 10, 10)};
> > e.Graphics.DrawRectangles(pen, r);
> > }
> >
> > The numbers used for the rectangles are pretty obvious and the the grid
> > looks exactly how it has to look. If it wasn't that off-by-1 the grid

will
> > be surrounded with 1-pixel-wide line and the internal lines will be 2

> pixels
> > wide or we would have used some others *not so obvious* numbers.

>
> Regardless of whether the numbers are obvious or not, it's patently absurd
> that you've just told it the rectangles are 10x10 and it is painting them
> 11x11. :-)
> The pixels should be two wide in that example, because you've asked it to
> make a bunch of boxes that are 10x10, 10 pixels apart from each other.
> Ugh. *does not compute*.


Hmm, it depends on what you are going to use the grid for. If I use the grid
just to rule a page I would cound the pixels for the first line up to the
next line no including the last one otherwise I have to count the last line
twise when I start counting the pixels in the next column. Which doesn't
make a lot of sense to me. Unfortunately we cannot draw lines between the
pixels.
In this case all cells in the grid are 10 pixels wide and 10 pixels high.

You say the System.Drawing is a hack over the GDI. it is true, but in this
case I dare to say it is different. In Win32's GDI the off-by-1 error works
in the oposite direction. It drawns one pixel less as the oposite to the
GDI+ where the off-by-1 error is one pixel more.

I can recall a lot of post in the Win32 news groups programmers complaining
of off-by-1 error in GDI. I strongly believe that there would be as many
complaints if we didn't (don't) have this off-by-1. So what I want to say is
that some times it might work for you some times it might not it depends on
the logic of the program.

I think this is not a bug. They just have to explain more clear that the pen
alignment works diferently for pens 1 pixel wide.

B\rgds
100


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
DrawRectangle positioning Jon Slaughter Microsoft C# .NET 2 26th Oct 2006 03:24 PM
Forcing CreateGraphics.DrawRectangle to Draw rectangle on top =?Utf-8?B?SmVmZiBXYXNraWV3aWN6?= Microsoft VB .NET 1 18th Oct 2006 01:05 PM
Erasing rectangle drawn with DrawRectangle =?Utf-8?B?RGFu?= Microsoft VB .NET 2 22nd Dec 2005 08:10 PM
Help for DRAWRECTANGLE Cristian Microsoft VB .NET 5 13th Dec 2005 04:56 PM
using g.DrawRectangle(pen,rect) to draw a rectangle on an object Colin McGuire Microsoft VB .NET 3 31st Dec 2003 05:03 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 12:47 PM.