Zero Width Pen Draws through clipped region...
- From: Geoff <Geoff@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 8 May 2007 08:31:04 -0700
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.
Place a panel on a Form and attach to the paint event. In the paint event
create a rectangle whose right edge is outside the client area of the panel
BUT whose left, top, and bottom edges are inside the client area.
Exclude the rectangle from the graphics clip region.
I fill large rectangle with a color so that I can see that my clip region is
correct and it does clip on the fill.
Draw a line down the panel. A line that intersects the top and bottom edge
of the rectangle that was excluded from the clip region.
The line has to be vertical, like this:
graphics.DrawLine(pen, 10, 0, 10, 100);
I call this drawing a line down the form, from a small Y value to a larger Y
value.
If you draw the line up then it is clipped properly.
The line draws right through the clipped area.
IF you make the clip rectangle fit completely inside the client area of the
panel the clipping works correctly.
IF you use a pen that is more than one pixel the clipping works correctly.
IF you draw UP the clipping works correctly.
Is there any attribute of the Graphics object, Pen, Brush, or anything I can
set to make this work?
Things that make the clipping work that are not options:
- I can't draw up all of the time, and besides that would work for lines but
not for a rectangle. (The problem exists drawing rectangles as well)
- I can't clip the area to the client rectangle before hand.
- I can't call GDI directly, even though I wrote a test for Polyline and the
clipping works correctly.
(When I say I can't, read, it would be significant to rewrite all of the
code to make the changes. For instance, I cache graphics paths to increase
redraw performance and I would loose all of that)
I attached the code. Notice that if you change the width of the panel the
clipping behavior changes.
Here is the 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;
Rectangle rectA = new Rectangle( 100, 50, 400, 100 ); //this
rectangle's right side is outside the client
Rectangle rectB = new Rectangle( 100, 175, 300, 100 );
Region r = new Region( );
r.MakeInfinite( );
r.Exclude( rectA );
r.Exclude( rectB );
Region oldClip = graphics.Clip;
graphics.SetClip( r,
System.Drawing.Drawing2D.CombineMode.Intersect );
//fill some large rectangle to see the clipping region at work.
graphics.FillRectangle( Brushes.LightCoral, 0, 0, 10000, 10000 );
Pen blackPen = new Pen( Brushes.Black, 1.0f );
Pen yellowPen = new Pen( Brushes.Yellow, 1.0f );
int x = 0;
for( int i = 0; i < 500; i++ )
{
//draw a line down...
graphics.DrawLine( blackPen, x - 10, 0, x - 10, 225 );
//draw a line up...
graphics.DrawLine( yellowPen, x, 300, x, 25 );
x += 20;
}
//even rectangles don't clip when drawing "down"
//graphics.DrawRectangle( blackPen, 150, 10, 10, 300 );
blackPen.Dispose( );
yellowPen.Dispose( );
graphics.Clip = oldClip;
}
private void panel1_SizeChanged( object sender, EventArgs e )
{
panel1.Invalidate( true );
}
}
}
<DESIGNER>
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.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( (
( System.Windows.Forms.AnchorStyles.Top |
System.Windows.Forms.AnchorStyles.Bottom )
| System.Windows.Forms.AnchorStyles.Left )
| System.Windows.Forms.AnchorStyles.Right ) ) );
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( 500, 300 );
this.panel1.TabIndex = 0;
this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(
this.panel1_Paint );
this.panel1.SizeChanged += new System.EventHandler(
this.panel1_SizeChanged );
//
// 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;
}
}
.
- Follow-Ups:
- Prev by Date: Re: GraphicsPath size?
- Next by Date: Re: problem with resizing 32bppArgb images
- Previous by thread: Re: GraphicsPath size?
- Next by thread: RE: Zero Width Pen Draws through clipped region...
- Index(es):
Relevant Pages
|