I seldom work with graphics, but I'm doing a project now which
requires me to draw precise shapes. I've discovered that, in order to
get crisp results, I have to "nudge" the coordinates. For instance,
instead of drawing a rectangle with
DrawRectangle(Pen1, X, Y, Width, Height)
I must use
DrawRectangle(Pen1, X + 0.001953, Y + 0.001953, Width, Height)
Is anyone familiar with this issue? I'm guessing it is a problem with
Windows (I'm using Windows XP Pro), but I'd like to learn more.
-TC
Sorry - fact of life.
Tom Dacon
Dacon Software Consulting
<existential...@gmail.com> wrote in message
news:efbcd39a-4afb-4ebf...@k16g2000hsf.googlegroups.com...
http://en.wikibooks.org/wiki/Visual_Basic_.NET/GDI%2B is a bluffer's guide,
but really you need to study GDI+ a bit to get it right.
If you can ensure that you dpi (dots per inch) is the same at every step,
you'll have a fighting chance. You need to turn off any "smoothing" etc that
your printer might perform.
--
David Streeter
Synchrotech Software
Sydney Australia
Use MM_TEXT mapping mode and work directly in pixels. To use any other
mapping mode will result in never knowing exactly where something will end
up pixel wise. Working with pixels you create your own coordinate system
as needed via math.
best regards,
Robert Dede
Gigasoft, Inc.
www.gigasoft.com
<existential...@gmail.com> wrote in message
news:efbcd39a-4afb-4ebf...@k16g2000hsf.googlegroups.com...
I wasn't very clear in my original post. What I meant to say is that
in pixel mode with no smoothing, I find that the graphics methods are
imprecise. Specifically, they seem to suffer from rounding errors when
Single arguments are used, and they seem to have inconsistent
definitions of "Width" and "Height". The result is shapes that don't
look as expected, and which must be "nudged" to fit properly into
place.
I wrote a simple form which illustrates what I'm talking about. I'd be
grateful if other people would try this form and let me know if the
problems I'm seeing affect only me, only XP systems, or all Windows
systems.
-TC
Imports System.Drawing
Imports System.Windows.Forms
Public Class GraphicsTestForm
Inherits Form
Private FlowLayoutPanel1 As FlowLayoutPanel
Private TextBox1 As TextBox
Private WithEvents ComboBox1 As ComboBox
Private TextBox2 As TextBox
Private WithEvents Panel1 As Panel
Public Sub New()
'TextBox1
TextBox1 = New TextBox
With TextBox1
.BorderStyle = BorderStyle.FixedSingle
.Multiline = True
.ReadOnly = True
.Size = New Size(400, 60)
.TabStop = False
.Text = "This form demonstrates the implementation of graphics
methods by drawing shapes inside a 100x100 white square with a 1-pixel
margin."
End With
'ComboBox1
ComboBox1 = New ComboBox
With ComboBox1
.Width = 400
.Items.AddRange(New String() {"DrawLine", "DrawRectangle 1",
"DrawRectangle 2", "FillRectangle 1", "FillRectangle 2",
"DrawEllipse", "FillEllipse"})
.MaxDropDownItems = 20
End With
'TextBox2
TextBox2 = New TextBox
With TextBox2
.BorderStyle = BorderStyle.FixedSingle
.Multiline = True
.ReadOnly = True
.Size = New Size(400, 60)
.TabStop = False
End With
'Panel1
Panel1 = New Panel
With Panel1
.BackColor = Color.White
.BorderStyle = BorderStyle.FixedSingle
.ClientSize = New Size(100, 100)
End With
'FlowLayoutPanel1
FlowLayoutPanel1 = New FlowLayoutPanel
With FlowLayoutPanel1
.Controls.Add(TextBox1)
.Controls.Add(ComboBox1)
.Controls.Add(TextBox2)
.Controls.Add(Panel1)
.Dock = DockStyle.Fill
.FlowDirection = FlowDirection.TopDown
End With
'Me
With Me
.Controls.Add(FlowLayoutPanel1)
.ClientSize = New Size(420, 300)
End With
End Sub
Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As
System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
Select Case ComboBox1.Text
Case "DrawLine"
e.Graphics.DrawLine(Pens.Red, 1, 1, 1, 98)
e.Graphics.DrawLine(Pens.Red, 1, 98, 98, 98)
e.Graphics.DrawLine(Pens.Red, 98, 98, 98, 1)
e.Graphics.DrawLine(Pens.Red, 98, 1, 1, 1)
Case "DrawRectangle 1"
e.Graphics.DrawRectangle(Pens.Red, 1, 1, 98, 98)
Case "DrawRectangle 2"
e.Graphics.DrawRectangle(Pens.Red, 0.501, 0.501, 98, 98)
Case "FillRectangle 1"
e.Graphics.FillRectangle(Brushes.Red, 1, 1, 98, 98)
Case "FillRectangle 2"
e.Graphics.FillRectangle(Brushes.Red, 1.1, 1.1, 98, 98)
Case "DrawEllipse"
e.Graphics.DrawEllipse(Pens.Red, 1, 1, 98, 98)
Case "FillEllipse"
e.Graphics.FillEllipse(Brushes.Red, 1, 1, 98, 98)
End Select
End Sub
Private Sub ComboBox1_TextChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles ComboBox1.TextChanged
Panel1.Invalidate()
Select Case ComboBox1.Text
Case "DrawLine"
TextBox2.Text = "DrawLine with integer arguments: This method
works as expected."
Case "DrawRectangle 1"
TextBox2.Text = "DrawRectangle(Pens.Red, 1, 1, 98, 98): This
method does not work as expected. The rectangle is too big."
Case "DrawRectangle 2"
TextBox2.Text = "DrawRectangle(Pens.Red, 0.501, 0.501, 98,
98): This method does not work as expected. The rectangle is
positioned improperly and is too big."
Case "FillRectangle 1"
TextBox2.Text = "FillRectangle(Brushes.Red, 1, 1, 98, 98):
This method works as expected."
Case "FillRectangle 2"
TextBox2.Text = "FillRectangle(Brushes.Red, 1.1, 1.1, 98, 98):
This method does not work as expected. The rectangle is positioned
improperly."
Case "DrawEllipse"
TextBox2.Text = "DrawEllipse(Pens.Red, 1, 1, 98, 98): This
method does not work as expected. The ellipse is too big and is not
centered properly."
Case "FillEllipse"
TextBox2.Text = "FillEllipse(Brushes.Red, 1, 1, 98, 98): This
method does not work as expected. The ellipse is too small and is not
centered properly."
End Select
End Sub
End Class
I am far from an assembly programmer, but for fun I thought I'd see how far
I could get looking at the IL disassembly (to see whether the different
DrawLine functions add or subtract 1 to yield the error).
There are several wrapper functions in different assemblies, but I hit a
brick wall when I got to gdiplus.dll - I can only assume this is a real (not
PE) executable, since it won't disassemble into ILAsm. None of the wrapper
functions convert from Single to Integer, so if there is a bug, it's probably
there.
--
David Streeter
Synchrotech Software
Sydney Australia