Reputation: 31
GDI+ DrawLines function has a clipping bug that can be reproduced by running the following c# code. When running the code, two line paths appear, that should be identical, because both of them are inside the clipping region. But when the clipping region is set, one of the line segment is not drawn.
protected override void OnPaint(PaintEventArgs e)
{
PointF[] points = new PointF[] { new PointF(73.36f, 196),
new PointF(75.44f, 32),
new PointF(77.52f, 32),
new PointF(79.6f, 196),
new PointF(85.84f, 196) };
Rectangle b = new Rectangle(70, 32, 20, 164);
e.Graphics.SetClip(b);
e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
e.Graphics.TranslateTransform(80, 0);
e.Graphics.ResetClip();
e.Graphics.DrawLines(Pens.Red, points);
}
Setting the antials mode on the graphics object resolves this. But that is not a real solution.
Does anybody know of a workaround?
Upvotes: 2
Views: 1917
Reputation: 47873
What appears to be the matter with the code?
OK, the question should be... what should the code do that it doesn't already.
When I run the code, I see 2 red 'spikes' am I not meant to?
You appear to draw the first spike within the clipped rectangle region verified by adding the the following after the declaration of the Rectangle :
e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );
Then you perform a translation, reset the clip so at this point I assume the clientRectangle is being used as the appropriate clip region and then attempt to redraw the translated spike. Where's the bug?!?
Upvotes: 0
Reputation: 47873
It appears that this is a known bug...
The following code appears to function as you requested:
protected override void OnPaint(PaintEventArgs e)
{
PointF[] points = new PointF[] { new PointF(73.36f, 196),
new PointF(75.44f, 32),
new PointF(77.52f, 32),
new PointF(79.6f, 196),
new PointF(85.84f, 196) };
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
Rectangle b = new Rectangle(70, 32, 20, 165);
e.Graphics.SetClip(b);
e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
e.Graphics.TranslateTransform(80, 0);
e.Graphics.ResetClip();
e.Graphics.DrawLines(Pens.Red, points);
}
Note: I have AntiAlias'ed the line and extended your clipping region by 1
it appears that the following work arounds might help (although not tested):
The following is a list of articles that might / or then again might not help:
http://www.tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0368.html
OR...
the following is also possible:
protected override void OnPaint ( PaintEventArgs e )
{
PointF[] points = new PointF[] { new PointF(73.36f, 196),
new PointF(75.44f, 32),
new PointF(77.52f, 32),
new PointF(79.6f, 196),
new PointF(85.84f, 196) };
Rectangle b = new Rectangle( 70, 32, 20, 164 );
Region reg = new Region( b );
e.Graphics.SetClip( reg, System.Drawing.Drawing2D.CombineMode.Union);
e.Graphics.DrawLines( Pens.Red, points ); // clipped incorrectly
e.Graphics.TranslateTransform( 80, 0 );
e.Graphics.ResetClip();
e.Graphics.DrawLines( Pens.Red, points );
}
This effecivly clips using a region combined/unioned (I think) with the ClientRectangle of the canvas/Control. As the region is difned from the rectangle, the results should be what is expected. This code can be proven to work by adding
e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );
after the setClip() call. This clearly shows the black rectangle only appearing in the clipped region.
This could be a valid workaround if Anti-Aliasing the line is not an option.
Hope this helps
Upvotes: 3
Reputation: 31
The bug is that both line segments should be drawn identical but they are not because the spike that is drawn within the clipping region is completely within the clipping region and should not be clipped in any way but it is. This is a very annoying but that results in any software that uses drawlines heavily + clipping to look unprofessional because of gaps that can appear in the polygons.
Upvotes: 0