using Pilz.Drawing; using System.Drawing.Drawing2D; namespace Pilz.UI.WinForms.PaintingControl; /// /// Contains static methods that are used for the standart PaintingObject Types. /// public class DefaultDrawMethodes { public static void DrawText(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; var b = new SolidBrush(obj.TextColor); var p = new PointF(); var rect = new Rectangle((int)Math.Round(e.X), (int)Math.Round(e.Y), (int)Math.Round(obj.Width), (int)Math.Round(obj.Height)); var f = StringFormat.GenericDefault; f.Alignment = obj.HorizontalTextAlignment; f.LineAlignment = obj.VerticalTextAlignment; float zoomFactor; if (obj.Parent is null) zoomFactor = 1.0f; else { zoomFactor = obj.Parent.ZoomFactor.Width; } e.Graphics.DrawString(obj.Text, new Font(obj.TextFont.FontFamily, obj.TextFont.Size * zoomFactor, obj.TextFont.Style), b, rect, f); } private static object _DrawPicture_newSyncObj = new(); public static void DrawPicture(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; Image objImg; Size objImgSize; RectangleF result; Bitmap image; SizeF zoomf; var hasNoParent = e.PaintingObject.Parent is null; object syncObj; if (hasNoParent) { zoomf = new SizeF(1f, 1f); syncObj = _DrawPicture_newSyncObj; } else { zoomf = e.PaintingObject.Parent.ZoomFactor; syncObj = e.PaintingObject.Parent; } lock (syncObj) { if (obj?.Image is null) return; objImg = obj.Image; objImgSize = objImg.Size; } image = (Bitmap)obj.BufferedImage; result = CalculateImageResolution(obj, objImgSize, zoomf); if (obj.ImageProperties.Rotate == 90 || obj.ImageProperties.Rotate == 270) result = CalculateImageResolution(obj, new SizeF(objImgSize.Height, objImgSize.Width), zoomf); if (image is null) { var needRescaleImageBecauseRot = false; image = DrawToNewImage((Bitmap)objImg, result.Size); switch (obj.ImageProperties.Rotate) { case 90: { image.RotateFlip(RotateFlipType.Rotate90FlipNone); needRescaleImageBecauseRot = true; break; } case 180: { image.RotateFlip(RotateFlipType.Rotate180FlipNone); break; } case 270: { image.RotateFlip(RotateFlipType.Rotate270FlipNone); needRescaleImageBecauseRot = true; break; } } if (obj.ImageProperties.FlipX) image.RotateFlip(RotateFlipType.RotateNoneFlipX); if (obj.ImageProperties.FlipY) image.RotateFlip(RotateFlipType.RotateNoneFlipY); if (needRescaleImageBecauseRot) { result = CalculateImageResolution(obj, new SizeF(objImgSize.Height, objImgSize.Width), zoomf); image = DrawToNewImage(image, result.Size); } obj.BufferedImage = image; } if (image is not null) { lock (syncObj) e.Graphics.DrawImageUnscaled(image, new Rectangle(new Point((int)Math.Round(obj.Location.X + result.Location.X - e.Offset.X), (int)Math.Round(obj.Location.Y + result.Location.Y - e.Offset.Y)), result.Size.ToSize())); } } private static Bitmap DrawToNewImage(Bitmap image, SizeF newSize) { var bmp = new Bitmap((int)Math.Round(newSize.Width < 0f ? newSize.Width * -1 : newSize.Width), (int)Math.Round(newSize.Height < 0f ? newSize.Height * -1 : newSize.Height)); var gimage = 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; } public static void DrawLine(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; var p2 = new Pen(obj.OutlineColor, obj.OutlineThicknes) { DashStyle = obj.OutlineDashStyle }; if (obj.LineEndCap is not null) { var args = obj.LineEndCap.Configure(); p2.StartCap = args.LineCap; p2.CustomStartCap = args.CustomLineCap; } if (obj.LineStartCap is not null) { var args = obj.LineStartCap.Configure(); p2.EndCap = args.LineCap; p2.CustomEndCap = args.CustomLineCap; } p2.Alignment = PenAlignment.Center; var no = new PointF(e.X, e.Y); e.Graphics.DrawLine(p2, no, no + obj.Size); } private static RectangleF CalculateImageResolution(PaintingObject obj, SizeF imageSize, SizeF zoom) { var result = new RectangleF(); var objrect = new RectangleF(obj.Location, obj.Size); var size = new SizeF(imageSize.Width * zoom.Width, imageSize.Height * zoom.Height); var clientRectangle = objrect; var val = clientRectangle.Width / size.Width; clientRectangle = objrect; var num = Math.Min(val, clientRectangle.Height / size.Height); result.Width = (int)Math.Round(Math.Truncate((double)(size.Width * num))); result.Height = (int)Math.Round(Math.Truncate((double)(size.Height * num))); clientRectangle = objrect; result.X = (long)Math.Round(clientRectangle.Width - result.Width) / 2L; clientRectangle = objrect; result.Y = (long)Math.Round(clientRectangle.Height - result.Height) / 2L; return result; } public static void DrawTriangle(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; var p1 = new Point((int)Math.Round(obj.Size.Width / 2f + e.X), (int)Math.Round(e.Y)); var p2 = new Point((int)Math.Round(e.X), (int)Math.Round(e.Y + obj.Size.Height)); var p3 = new Point((int)Math.Round(e.X + obj.Size.Width), (int)Math.Round(e.Y + obj.Size.Height)); if (obj.EnableFill) { var b = new SolidBrush(obj.FillColor); e.Graphics.FillPolygon(b, new[] { p1, p2, p3 }); } if (obj.EnableOutline) { var lw = obj.OutlineThicknes; var p = new Pen(obj.OutlineColor, obj.OutlineThicknes) { DashStyle = obj.OutlineDashStyle, Alignment = PenAlignment.Inset }; e.Graphics.DrawPolygon(p, new[] { p1, p2, p3 }); } } public static void DrawRectangle(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; var hol = obj.OutlineThicknes / 2f; if (obj.EnableFill) { var b = new SolidBrush(obj.FillColor); var rect = obj.EnableOutline ? new Rectangle((int)Math.Round(e.X + hol), (int)Math.Round(e.Y + hol), (int)Math.Round(obj.Size.Width - hol * 2f), (int)Math.Round(obj.Size.Height - hol * 2f)) : new Rectangle((int)Math.Round(e.X), (int)Math.Round(e.Y), (int)Math.Round(obj.Size.Width), (int)Math.Round(obj.Size.Height)); e.Graphics.FillRectangle(b, rect); } if (obj.EnableOutline) { var p = new Pen(obj.OutlineColor, obj.OutlineThicknes) { DashStyle = obj.OutlineDashStyle, Alignment = PenAlignment.Inset }; var rect = new Rectangle((int)Math.Round(e.X), (int)Math.Round(e.Y), (int)Math.Round(obj.Size.Width), (int)Math.Round(obj.Size.Height)); e.Graphics.DrawRectangle(p, rect); } } public static void DrawEllipse(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; if (obj.EnableFill) { var b = new SolidBrush(obj.FillColor); var rect = new Rectangle((int)Math.Round(e.X), (int)Math.Round(e.Y), (int)Math.Round(obj.Size.Width), (int)Math.Round(obj.Size.Height)); e.Graphics.FillEllipse(b, rect); } if (obj.EnableOutline) { var p = new Pen(obj.OutlineColor, obj.OutlineThicknes) { DashStyle = obj.OutlineDashStyle, Alignment = PenAlignment.Inset }; var rect = new Rectangle((int)Math.Round(e.X), (int)Math.Round(e.Y), (int)Math.Round(obj.Size.Width), (int)Math.Round(obj.Size.Height)); e.Graphics.DrawEllipse(p, rect); } } public static void DrawSelection(PaintingObjectPaintEventArgs e) { var obj = e.PaintingObject; var lw = 2.5f; var hlw = lw / 2f; var hlwphol = hlw; // + hol var hlwpholm2 = hlwphol * 2f; var p = new Pen(Color.CornflowerBlue, lw) { DashStyle = obj.SelectionDashStyle, Alignment = PenAlignment.Outset }; var rect = new Rectangle((int)Math.Round(e.X - hlwphol), (int)Math.Round(e.Y - hlwphol), (int)Math.Round(obj.Size.Width + hlwpholm2), (int)Math.Round(obj.Size.Height + hlwpholm2)); e.Graphics.DrawRectangle(p, rect); } public static void DrawGrid(PaintEventArgs e, PaintingControl pc, PointF offset) { var p = new Pen(pc.GridColor, 0.5f); var curX = (int)Math.Round(pc.GridChunkSize.Width * pc.ZoomFactor.Width - offset.X); while (curX < pc.Width) { e.Graphics.DrawLine(p, curX, -offset.Y, curX, pc.Height); curX = (int)Math.Round(curX + pc.GridChunkSize.Width * pc.ZoomFactor.Width); } var curY = (int)Math.Round(pc.GridChunkSize.Height * pc.ZoomFactor.Height - offset.Y); while (curY < pc.Height) { e.Graphics.DrawLine(p, -offset.X, curY, pc.Width, curY); curY = (int)Math.Round(curY + pc.GridChunkSize.Height * pc.ZoomFactor.Height); } } public static void DrawAreaSelection(PaintEventArgs e, PaintingControl pc, PointF startMousePos, PointF lastMousePos) { var rectToDraw = HelpfulDrawingFunctions.GetRectangle(startMousePos, lastMousePos); var p = new Pen(pc.AreaSelectionColor) { DashStyle = startMousePos.X >= lastMousePos.X ? DashStyle.DashDot : DashStyle.Solid, Width = 3f }; e.Graphics.DrawRectangle(p, rectToDraw.X, rectToDraw.Y, rectToDraw.Width, rectToDraw.Height); } }