RE: GDI+ Clip Region allows 0.0f width pen to draw through

Tech-Archive recommends: Fix windows errors by optimizing your registry



Remember when resizing the form only change the WIDTH of the form to see the
bug.

Replace the paint method with this even simpler version to show the bug. It
just draws a rectangle that overlaps the clip. Notice how the left edge of
the rect gets clipped and the right edge goes right through the clip region.

private void panel1_Paint( object sender, PaintEventArgs e )
{

Graphics graphics = e.Graphics;

Rectangle rectA = new Rectangle( 100, 100, 200, 100 );
Region r = new Region( rectA );

Region oldClip = graphics.Clip;

graphics.SetClip( rectA,
System.Drawing.Drawing2D.CombineMode.Exclude );

int x = 0;

graphics.FillRectangle( Brushes.LightCoral, 0, 0, 10000, 10000 );

Pen pen = new Pen( Brushes.Black, 1.0f );

//for( int i = 0; i < 500; i++ )
//{
// graphics.DrawLine( pen, x, 300, x, 0 );
// graphics.DrawLine( pen, x - 10, 0, x - 10, 150 );
// x += 20;
//}

graphics.DrawRectangle( pen, 150, 50, 10, 200 );

pen.Dispose( );
}

"Geoff" wrote:

Just to make this more outrageous if you draw the vertical lines from the
bottom of the form to the top they clip just fine. In otherwords if you draw
from a large Y value to a small value.

I took the previous code I posted and made the panel anchor to all four
sides of the form so that I could resize the form and see how the drawing was
affected. I also added an Invalidate in the resize of the panel so that it
would redraw everything everytime.

Here is the new code:

<FORM>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ClipBug
{
public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent( );
}

private void panel1_Paint( object sender, PaintEventArgs e )
{
//Graphics graphics = e.Graphics;
//graphics.PageUnit = GraphicsUnit.Inch;

//RectangleF rectA = new RectangleF( 3.5f, 0.5f, 2.0f, 1.0f );
//RectangleF rectB = new RectangleF( 3.5f, 2.0f, .5f, .5f );
//RectangleF rectC = new RectangleF( -1.0f, 0.5f, 2.0f, 1.0f );

////graphics.FillRectangle( Brushes.Beige, rect );
//Region r = new Region( );
//r.MakeInfinite( );
//r.Exclude( rectA );
//r.Exclude( rectB );
//r.Exclude( rectC );

//Region oldClip = graphics.Clip;

//graphics.SetClip( r,
System.Drawing.Drawing2D.CombineMode.Intersect );

//float x = 0.0f;

//graphics.FillRectangle( Brushes.LightCoral, 0.0f, 0.0f,
1000.0f, 1000.0f );

//Pen pen = new Pen( Brushes.Black, 0.00f );

//for( int i = 0; i < 10000; i++ )
//{
// graphics.DrawLine( pen, x, 0.0f, x, 100.0f );
// x += 0.1f;
//}

//pen.Dispose( );


Graphics graphics = e.Graphics;

Rectangle rectA = new Rectangle( 100, 100, 200, 100 );
Region r = new Region( rectA );

Region oldClip = graphics.Clip;

graphics.SetClip( rectA,
System.Drawing.Drawing2D.CombineMode.Exclude );

int x = 0;

graphics.FillRectangle( Brushes.LightCoral, 0, 0, 10000, 10000 );

Pen pen = new Pen( Brushes.Black, 1.0f );

for( int i = 0; i < 500; i++ )
{
graphics.DrawLine( pen, x, 300, x, 0 );
graphics.DrawLine( pen, x - 10, 0, x - 10, 300 );
x += 20;
}

pen.Dispose( );
}

private void panel1_SizeChanged( object sender, EventArgs e )
{
panel1.Invalidate( true );
}
}
}





"Geoff" wrote:

Here is my setup:
Windows Vista Ultimate
Visual Studio 2005
Intel Core 2 CPU 6600 @ 2.40 GHz
RAM: 2045 MB
.NET 2.0

The problem is:
Using a zero width pen I can draw into areas that are not part of the clip
region.

Create a simple Windows Forms application.
On the form place a panel.
Attach a method to the Paint event.
Inside the draw create two rectangles.
The first rectangle does not fit in the panel in this very specific manner:
the rectangle's right edge is outside the panel and the left edge is inside
the panel. In other words create a rectangle that is a wider than the panel.
The second rectangle does not intersect the first rectangle and is
completely inside the panel.
Create a region and make it infinite. Exclude rectangle one and rectangle
two from the region.
Set the clip of the graphics instance (found in the event args) to the
region just created using a combine mode of Intersect.

Now fill a rectangle that is bigger than the panel with some color to see if
the two rectangles are excluded from the fill, which they are.

Create a pen that has a zero width.

In a loop draw vertical lines across the panel. Notice how the lines draw
through rectangle one but not rectangle two.

If you change the pen size the lines will not draw through rectangle one or
rectangle two.

Any suggestions on how to still use a zero width pen and not draw inside the
rectangle one?

Is there a specific group for GDI+ to which I should post this problem?

Geoffrey Slinker

--- here is the code---

<DESIGNER CODE>
namespace ClipBug
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if( disposing && ( components != null ) )
{
components.Dispose( );
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent( )
{
this.panel1 = new System.Windows.Forms.Panel( );
this.SuspendLayout( );
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.BorderStyle =
System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Location = new System.Drawing.Point( 52, 44 );
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size( 491, 326 );
this.panel1.TabIndex = 0;
this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(
this.panel1_Paint );
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size( 625, 440 );
this.Controls.Add( this.panel1 );
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout( false );

}

#endregion

private System.Windows.Forms.Panel panel1;
}
}



<FORM CODE>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ClipBug
{
public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent( );
}

private void panel1_Paint( object sender, PaintEventArgs e )
{
Graphics graphics = e.Graphics;
graphics.PageUnit = GraphicsUnit.Inch;

RectangleF rectA = new RectangleF( 3.5f, 0.5f, 2.0f, 1.0f );
RectangleF rectB = new RectangleF( 3.5f, 2.0f, .5f, .5f );

//graphics.FillRectangle( Brushes.Beige, rect );
Region r = new Region( );
r.MakeInfinite( );
r.Exclude( rectA );
r.Exclude( rectB );

Region oldClip = graphics.Clip;

graphics.SetClip( r,
System.Drawing.Drawing2D.CombineMode.Intersect );

float x = 0.0f;

graphics.FillRectangle( Brushes.LightCoral, 0.0f, 0.0f, 1000.0f,
1000.0f );

Pen pen = new Pen( Brushes.Black, 0.0f );

for( int i = 0; i < 10000; i++ )
{
graphics.DrawLine( pen, x, 0.0f, x, 100.0f );
x += 0.1f;
}

pen.Dispose( );
}
}
}


<DISIGNER>
namespace ClipBug
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if( disposing && ( components != null ) )
{
components.Dispose( );
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

/// <summary>
.



Relevant Pages

  • RE: GDI+ Clip Region allows 0.0f width pen to draw through
    ... Just to make this more outrageous if you draw the vertical lines from the ... I took the previous code I posted and made the panel anchor to all four ... private void panel1_SizeChanged ... In other words create a rectangle that is a wider than the panel. ...
    (microsoft.public.win32.programmer.gdi)
  • GDI+ Clip Region allows 0.0f width pen to draw through
    ... On the form place a panel. ... Inside the draw create two rectangles. ... In other words create a rectangle that is a wider than the panel. ... Create a pen that has a zero width. ...
    (microsoft.public.win32.programmer.gdi)
  • Problem with custom Panel class
    ... I'm extending the Panel control to allow selection of controls on the Panel ... selection rectangle is drawn behind the controls on the Panel. ... private void OnMouseDown ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Problem with custom Panel class
    ... I'm extending the Panel control to allow selection of controls on the Panel ... selection rectangle is drawn behind the controls on the Panel. ... private void OnMouseDown ...
    (microsoft.public.dotnet.framework.windowsforms.controls)
  • Re: FillRectangle over Windows Forms Components
    ... I really used the wrong panel. ... "Stoitcho Goutsev " wrote: ... flag on the component that you draw on. ... The rectangle is still under the Forms components. ...
    (microsoft.public.dotnet.framework.windowsforms)