Right and Bottom Cut Off When Creating New Region From GraphicsPath

  • Thread starter Thread starter Don
  • Start date Start date
D

Don

When creating a new region for a control via a GraphicsPath object, it
appears the entire rightmost column of pixels and bottom most row of pixels
are not included in the region.

I will try to clarify with some ASCII art. Imagine a GraphicsPath
describing a 4x4 pixel square with rounded corners (X = pixel, _ = blank)

_ X X _
X X X X
X X X X
_ X X _

Creating a region from this GraphicsPath object will yield a region shaped
like this:

_ X X
X X X
X X X


Can anyone tell me what's going on with this? How can this be fixed?


- Don
 
Try placing the following control class on a form in a new project:


--- CODE START ---


Imports System.Drawing.Drawing2D

Public Class ShapedPanel
Inherits System.Windows.Forms.Panel


Public Sub New()
MyBase.New()

ChangeControlRegion()

End Sub

Private Sub ChangeControlRegion()

Dim regionPath As GraphicsPath = GetControlShapePath()
Dim newRegion As System.Drawing.Region = New
System.Drawing.Region(regionPath)

Me.Region = newRegion

End Sub

Private Function GetControlShapePath() As GraphicsPath

Dim points(7) As Point
Dim types(7) As Byte
Dim result As GraphicsPath
Dim h As Integer = Me.Height
Dim w As Integer = Me.Width
Dim i As Integer

points(0) = New Point(1, 0)
points(1) = New Point(w - 1, 0)
points(2) = New Point(w, 1)
points(3) = New Point(w, h - 1)
points(4) = New Point(w - 1, h)
points(5) = New Point(1, h)
points(6) = New Point(0, h - 1)
points(7) = New Point(0, 1)

For i = 0 To 7
types(i) = CByte(PathPointType.Line)
Next i

result = New GraphicsPath(points, types)

Return result


End Function

End Class


--- CODE END ---


This panel should be drawn with a single pixel out of each of the four
corners. However, only the upper left corner pixel will be missing. Tests
I have done lead me to believe that the rightmost column and bottommost row
of pixels are not included in the region for some reason.

- Don
 
Maybe add this method to the class instead of calling ChangeControlRegion
from the class constructor:

Protected Overrides Sub OnResize(ByVal eventargs As System.EventArgs)
MyBase.OnResize(eventargs)
ChangeControlRegion()
End Sub

- Don

Don said:
Try placing the following control class on a form in a new project:


--- CODE START ---


Imports System.Drawing.Drawing2D

Public Class ShapedPanel
Inherits System.Windows.Forms.Panel


Public Sub New()
MyBase.New()

ChangeControlRegion()

End Sub

Private Sub ChangeControlRegion()

Dim regionPath As GraphicsPath = GetControlShapePath()
Dim newRegion As System.Drawing.Region = New
System.Drawing.Region(regionPath)

Me.Region = newRegion

End Sub

Private Function GetControlShapePath() As GraphicsPath

Dim points(7) As Point
Dim types(7) As Byte
Dim result As GraphicsPath
Dim h As Integer = Me.Height
Dim w As Integer = Me.Width
Dim i As Integer

points(0) = New Point(1, 0)
points(1) = New Point(w - 1, 0)
points(2) = New Point(w, 1)
points(3) = New Point(w, h - 1)
points(4) = New Point(w - 1, h)
points(5) = New Point(1, h)
points(6) = New Point(0, h - 1)
points(7) = New Point(0, 1)

For i = 0 To 7
types(i) = CByte(PathPointType.Line)
Next i

result = New GraphicsPath(points, types)

Return result


End Function

End Class


--- CODE END ---


This panel should be drawn with a single pixel out of each of the four
corners. However, only the upper left corner pixel will be missing.
Tests I have done lead me to believe that the rightmost column and
bottommost row of pixels are not included in the region for some reason.

- Don
 
I'm definitely seeing a result that I didn't expect. Even though I've made a
few changes from your original code.

I'll investigate this further and If I can pin down an real bug I'll
escalate it to the GDI+ team at MS. As to a workaround I would suggest in
the short-term adding a fudge-factor to make it look the way you want it to.

Thanks.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





Don said:
Maybe add this method to the class instead of calling ChangeControlRegion
from the class constructor:

Protected Overrides Sub OnResize(ByVal eventargs As System.EventArgs)
MyBase.OnResize(eventargs)
ChangeControlRegion()
End Sub

- Don
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top