Files
Pilz/Pilz.UI/PaintingControl/DefaultDrawMethodes.vb
2024-06-05 19:15:32 +02:00

250 lines
10 KiB
VB.net

Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
Imports Pilz.Drawing
''' <summary>
''' Contains static methods that are used for the standart PaintingObject Types.
''' </summary>
Public Class DefaultDrawMethodes
Public Shared Sub DrawText(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim b As New SolidBrush(obj.TextColor)
Dim p As New PointF
Dim rect As New Rectangle(e.X, e.Y, obj.Width, obj.Height)
Dim f As StringFormat = StringFormat.GenericDefault
f.Alignment = obj.HorizontalTextAlignment
f.LineAlignment = obj.VerticalTextAlignment
Dim zoomFactor As Single
If obj.Parent Is Nothing Then
zoomFactor = 1.0!
Else
zoomFactor = obj.Parent.ZoomFactor.Width
End If
e.Graphics.DrawString(obj.Text, New Font(obj.TextFont.FontFamily, obj.TextFont.Size * zoomFactor, obj.TextFont.Style), b, rect, f)
End Sub
Public Shared Sub DrawPicture(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim objImg As Image
Dim objImgSize As Size
Dim result As RectangleF
Dim image As Bitmap
Dim zoomf As SizeF
Dim hasNoParent As Boolean = e.PaintingObject.Parent Is Nothing
Dim syncObj As Object
If hasNoParent Then
zoomf = New SizeF(1, 1)
Static newSyncObj As New Object
syncObj = newSyncObj
Else
zoomf = e.PaintingObject.Parent.ZoomFactor
syncObj = e.PaintingObject.Parent
End If
SyncLock syncObj
If obj?.Image Is Nothing Then Return
objImg = obj.Image
objImgSize = objImg.Size
End SyncLock
image = obj.BufferedImage
result = CalculateImageResolution(obj, objImgSize, zoomf)
If obj.ImageProperties.Rotate = 90 OrElse obj.ImageProperties.Rotate = 270 Then
result = CalculateImageResolution(obj, New SizeF(objImgSize.Height, objImgSize.Width), zoomf)
End If
If image Is Nothing Then
Dim needRescaleImageBecauseRot As Boolean = False
image = DrawToNewImage(objImg, result.Size)
Select Case obj.ImageProperties.Rotate
Case 90
image.RotateFlip(RotateFlipType.Rotate90FlipNone)
needRescaleImageBecauseRot = True
Case 180
image.RotateFlip(RotateFlipType.Rotate180FlipNone)
Case 270
image.RotateFlip(RotateFlipType.Rotate270FlipNone)
needRescaleImageBecauseRot = True
End Select
If obj.ImageProperties.FlipX Then
image.RotateFlip(RotateFlipType.RotateNoneFlipX)
End If
If obj.ImageProperties.FlipY Then
image.RotateFlip(RotateFlipType.RotateNoneFlipY)
End If
If needRescaleImageBecauseRot Then
result = CalculateImageResolution(obj, New SizeF(objImgSize.Height, objImgSize.Width), zoomf)
image = DrawToNewImage(image, result.Size)
End If
obj.BufferedImage = image
End If
If image IsNot Nothing Then
SyncLock syncObj
e.Graphics.DrawImageUnscaled(image, New Rectangle(New Point(obj.Location.X + result.Location.X - e.Offset.X, obj.Location.Y + result.Location.Y - e.Offset.Y), result.Size.ToSize))
End SyncLock
End If
End Sub
Private Shared Function DrawToNewImage(image As Bitmap, newSize As SizeF) As Bitmap
Dim bmp As New Bitmap(CInt(If(newSize.Width < 0, newSize.Width * -1, newSize.Width)),
CInt(If(newSize.Height < 0, newSize.Height * -1, newSize.Height)))
Dim gimage As Graphics = Graphics.FromImage(bmp)
gimage.SmoothingMode = SmoothingMode.HighQuality
gimage.PixelOffsetMode = PixelOffsetMode.HighQuality
gimage.PageUnit = GraphicsUnit.Pixel
gimage.InterpolationMode = InterpolationMode.HighQualityBicubic
gimage.DrawImage(image, New RectangleF(PointF.Empty, newSize))
gimage.Dispose()
Return bmp
End Function
Public Shared Sub DrawLine(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim p2 As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {
.DashStyle = obj.OutlineDashStyle
}
If obj.LineEndCap IsNot Nothing Then
Dim args As LineCapConfigurationArgs = obj.LineEndCap.Configure
p2.StartCap = args.LineCap
p2.CustomStartCap = args.CustomLineCap
End If
If obj.LineStartCap IsNot Nothing Then
Dim args As LineCapConfigurationArgs = obj.LineStartCap.Configure
p2.EndCap = args.LineCap
p2.CustomEndCap = args.CustomLineCap
End If
p2.Alignment = PenAlignment.Center
Dim no As PointF = New PointF(e.X, e.Y)
e.Graphics.DrawLine(p2, no, no + obj.Size)
End Sub
Private Shared Function CalculateImageResolution(obj As PaintingObject, imageSize As SizeF, zoom As SizeF) As RectangleF
Dim result As New RectangleF
Dim objrect As New RectangleF(obj.Location, obj.Size)
Dim size As SizeF = New SizeF(imageSize.Width * zoom.Width, imageSize.Height * zoom.Height)
Dim clientRectangle As RectangleF = objrect
Dim val As Single = clientRectangle.Width / size.Width
clientRectangle = objrect
Dim num As Single = Math.Min(val, clientRectangle.Height / size.Height)
result.Width = CInt(Math.Truncate(size.Width * num))
result.Height = CInt(Math.Truncate(size.Height * num))
clientRectangle = objrect
result.X = (clientRectangle.Width - result.Width) \ 2
clientRectangle = objrect
result.Y = (clientRectangle.Height - result.Height) \ 2
Return result
End Function
Public Shared Sub DrawTriangle(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim p1 As New Point(obj.Size.Width / 2 + e.X, e.Y)
Dim p2 As New Point(e.X, e.Y + obj.Size.Height)
Dim p3 As New Point(e.X + obj.Size.Width, e.Y + obj.Size.Height)
If obj.EnableFill Then
Dim b As New SolidBrush(obj.FillColor)
e.Graphics.FillPolygon(b, {p1, p2, p3})
End If
If obj.EnableOutline Then
Dim lw As Single = obj.OutlineThicknes
Dim p As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {.DashStyle = obj.OutlineDashStyle, .Alignment = PenAlignment.Inset}
e.Graphics.DrawPolygon(p, {p1, p2, p3})
End If
End Sub
Public Shared Sub DrawRectangle(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim hol As Single = obj.OutlineThicknes / 2
If obj.EnableFill Then
Dim b As New SolidBrush(obj.FillColor)
Dim rect As Rectangle = If(obj.EnableOutline,
New Rectangle(e.X + hol, e.Y + hol, obj.Size.Width - hol * 2, obj.Size.Height - hol * 2),
New Rectangle(e.X, e.Y, obj.Size.Width, obj.Size.Height))
e.Graphics.FillRectangle(b, rect)
End If
If obj.EnableOutline Then
Dim p As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {.DashStyle = obj.OutlineDashStyle, .Alignment = PenAlignment.Inset}
Dim rect As New Rectangle(e.X, e.Y, obj.Size.Width, obj.Size.Height)
e.Graphics.DrawRectangle(p, rect)
End If
End Sub
Public Shared Sub DrawEllipse(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
If obj.EnableFill Then
Dim b As New SolidBrush(obj.FillColor)
Dim rect As Rectangle = New Rectangle(e.X, e.Y, obj.Size.Width, obj.Size.Height)
e.Graphics.FillEllipse(b, rect)
End If
If obj.EnableOutline Then
Dim p As New Pen(obj.OutlineColor, obj.OutlineThicknes) With {.DashStyle = obj.OutlineDashStyle, .Alignment = PenAlignment.Inset}
Dim rect As New Rectangle(e.X, e.Y, obj.Size.Width, obj.Size.Height)
e.Graphics.DrawEllipse(p, rect)
End If
End Sub
Public Shared Sub DrawSelection(e As PaintingObjectPaintEventArgs)
Dim obj As PaintingObject = e.PaintingObject
Dim lw As Single = 2.5!
Dim hlw As Single = lw / 2
Dim hlwphol As Single = hlw '+ hol
Dim hlwpholm2 As Single = hlwphol * 2
Dim p As New Pen(Color.CornflowerBlue, lw) With {.DashStyle = obj.SelectionDashStyle, .Alignment = PenAlignment.Outset}
Dim rect As New Rectangle(e.X - hlwphol, e.Y - hlwphol, obj.Size.Width + hlwpholm2, obj.Size.Height + hlwpholm2)
e.Graphics.DrawRectangle(p, rect)
End Sub
Public Shared Sub DrawGrid(e As PaintEventArgs, pc As PaintingControl, offset As PointF)
Dim p As New Pen(pc.GridColor, 0.5)
Dim curX As Integer = pc.GridChunkSize.Width * pc.ZoomFactor.Width - offset.X
Do While curX < pc.Width
e.Graphics.DrawLine(p, curX, -offset.Y, curX, pc.Height)
curX += (pc.GridChunkSize.Width * pc.ZoomFactor.Width)
Loop
Dim curY As Integer = pc.GridChunkSize.Height * pc.ZoomFactor.Height - offset.Y
Do While curY < pc.Height
e.Graphics.DrawLine(p, -offset.X, curY, pc.Width, curY)
curY += (pc.GridChunkSize.Height * pc.ZoomFactor.Height)
Loop
End Sub
Public Shared Sub DrawAreaSelection(e As PaintEventArgs, pc As PaintingControl, startMousePos As PointF, lastMousePos As PointF)
Dim rectToDraw As RectangleF = HelpfulDrawingFunctions.GetRectangle(startMousePos, lastMousePos)
Dim p As New Pen(pc.AreaSelectionColor)
p.DashStyle = If(startMousePos.X >= lastMousePos.X, DashStyle.DashDot, DashStyle.Solid)
p.Width = 3
e.Graphics.DrawRectangle(p, rectToDraw.X, rectToDraw.Y, rectToDraw.Width, rectToDraw.Height)
End Sub
End Class