using PaintDotNet.Annotation.Enum; using PaintDotNet.Base.SettingModel; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.Windows.Forms; namespace PaintDotNet.Annotation.Label { using PointList = List; /// /// 标注->曲线->曲线 /// public class DrawCurve : DrawObject { private PointList pointArray; private static Cursor handleCursor = new Cursor(PdnResources.GetResourceStream("Cursors.AnnotationPolyHandle.cur")); /// /// Graphic objects for hit test /// private GraphicsPath areaPath = null; private Pen areaPen = null; private Region areaRegion = null; /// /// 标注样式信息model /// private LabelStyleModel.CurveModel labelCurveModelStyleModel; public LabelStyleModel.CurveModel LabelCurveModelStyleModel { set { this.labelCurveModelStyleModel = value; } } public DrawCurve() : base() { this.objectType = DrawClass.Label; this.drawToolType = DrawToolType.DrawCurve; pointArray = new PointList(); Initialize(); } public DrawCurve(ISurfaceBox surfaceBox, int x1, int y1) : base() { this.objectType = DrawClass.Label; this.drawToolType = DrawToolType.DrawCurve; labelCurveModelStyleModel = surfaceBox.GetLabelStyleModel().curveModel; pointArray = new PointList(); startPoint.X = x1; startPoint.Y = y1; pointArray.Add(new PointF(x1, y1)); Initialize(); } public DrawCurve(ISurfaceBox surfaceBox, List points, ParentStyleModel parentStyleModel, Object content) : base() { this.objectType = DrawClass.Label; this.drawToolType = DrawToolType.DrawCurve; this.ISurfaceBox = surfaceBox; labelCurveModelStyleModel = (LabelStyleModel.CurveModel)parentStyleModel; pointArray = points; startPoint = points[points.Count - 2]; endPoint = points[points.Count - 1]; } /// /// Clone this instance /// public override DrawObject Clone() { DrawCurve drawPolygon = new DrawCurve(ISurfaceBox, 0, 0); drawPolygon.objectType = DrawClass.Label; drawPolygon.drawToolType = DrawToolType.DrawCurve; drawPolygon.ISurfaceBox = this.ISurfaceBox; drawPolygon.pointArray.Clear(); foreach (PointF p in this.pointArray) { drawPolygon.pointArray.Add(p); } drawPolygon.startPoint = this.startPoint; drawPolygon.endPoint = this.endPoint; drawPolygon.labelCurveModelStyleModel = this.labelCurveModelStyleModel; FillDrawObjectFields(drawPolygon); return drawPolygon; } public override DrawObject Clone(ISurfaceBox surfaceBox) { DrawCurve drawPolygon = new DrawCurve(surfaceBox, 0, 0); drawPolygon.objectType = DrawClass.Label; drawPolygon.drawToolType = DrawToolType.DrawCurve; drawPolygon.ISurfaceBox = surfaceBox; drawPolygon.pointArray.Clear(); foreach (PointF p in this.pointArray) { drawPolygon.pointArray.Add(p); } drawPolygon.startPoint = this.startPoint; drawPolygon.endPoint = this.endPoint; drawPolygon.labelCurveModelStyleModel = this.labelCurveModelStyleModel; FillDrawObjectFields(drawPolygon); return drawPolygon; } public override void Draw(Graphics g) { if (HandleCount >= 3) { g.SmoothingMode = SmoothingMode.AntiAlias; Color color = Color.FromArgb(labelCurveModelStyleModel.lineColor); int lineWidth = labelCurveModelStyleModel.lineWidth; Pen pen = new Pen(color, lineWidth); pen.DashStyle = (DashStyle)this.labelCurveModelStyleModel.lineStyle; g.DrawCurve(pen, pointArray.ToArray()); //.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); pen.Dispose(); } } public void AddPoint(PointF point) { pointArray.Add(point); } public override int HandleCount { get { return pointArray.Count; } } /// /// Get handle pointscroll by 1-based number /// /// /// public override PointF GetHandle(int handleNumber) { if (handleNumber < 1) handleNumber = 1; if (handleNumber > pointArray.Count) handleNumber = pointArray.Count; return pointArray[handleNumber - 1]; } public override Cursor GetHandleCursor(int handleNumber) { return handleCursor; } public override void MoveHandleTo(Point point, int handleNumber) { if (handleNumber < 1) handleNumber = 1; if (handleNumber > pointArray.Count) handleNumber = pointArray.Count; pointArray[handleNumber - 1] = point; Invalidate(); } public override void Move(int deltaX, int deltaY) { int n = pointArray.Count; for (int i = 0; i < n; i++) { PointF point = new PointF(pointArray[i].X + ISurfaceBox.UnscaleScalar(deltaX), pointArray[i].Y + ISurfaceBox.UnscaleScalar(deltaY)); pointArray[i] = point; } Invalidate(); } /// /// 用于创建一个路径或者是闭合的范围 /// 用于响应点击选中 /// 需要咨询用户是仅点击线还是矩形选择 /// protected virtual void CreateObjects() { if (AreaPath != null) return; AreaPath = new GraphicsPath(); AreaPath.AddRectangle(GetBoundingBox()); AreaPath.CloseFigure(); AreaRegion = new Region(AreaPath); } /// /// Invalidate object. /// When object is invalidated, path used for hit test /// is released and should be created again. /// protected void Invalidate() { if (AreaPath != null) { AreaPath.Dispose(); AreaPath = null; } if (AreaPen != null) { AreaPen.Dispose(); AreaPen = null; } if (AreaRegion != null) { AreaRegion.Dispose(); AreaRegion = null; } } protected GraphicsPath AreaPath { get { return areaPath; } set { areaPath = value; } } protected Pen AreaPen { get { return areaPen; } set { areaPen = value; } } protected Region AreaRegion { get { return areaRegion; } set { areaRegion = value; } } /// /// Draw tracker for selected object /// /// public override void DrawTracker(Graphics g) { if (!Selected) return; SolidBrush brush = new SolidBrush(Color.FromArgb(MarkpointAreaColor)); Pen pen = new Pen(Color.FromArgb(MarkpointLineColor), MarkpointLineWidth); for (int i = 1; i <= HandleCount; i++) { switch (MarkpointStyle) { case 0: g.FillRectangle(brush, GetHandleRectangle(i)); g.DrawRectangle(pen, GetHandleRectangle(i)); break; case 1: g.FillEllipse(brush, GetHandleRectangle(i)); g.DrawEllipse(pen, GetHandleRectangle(i)); break; case 2: g.FillPolygon(brush, GetHandlePoint(i)); g.DrawPolygon(pen, GetHandlePoint(i)); break; } } brush.Dispose(); pen.Dispose(); RectangleF r = GetBoundingBox(); g.DrawRectangle(new Pen(Color.White), r.X, r.Y, r.Width, r.Height); } /// /// Hit test. /// Return value: -1 - no hit /// 0 - hit anywhere /// > 1 - handle number /// /// /// public override int HitTest(Point point) { if (Selected) { for (int i = 1; i <= HandleCount; i++) { if (GetHandleRectangle(i).Contains(point)) return i; } } if (PointInObject(point)) return 0; return -1; } protected override bool PointInObject(Point point) { CreateObjects(); return AreaRegion.IsVisible(point); } public override bool IntersectsWith(Rectangle rectangle) { CreateObjects(); return AreaRegion.IsVisible(rectangle); } public override RectangleF GetBoundingBox() { RectangleF rectangle; int minx = 0, maxx = 0, miny = 0, maxy = 0; for (int i = 0; i < pointArray.Count; i++) { if (i == 0) { minx = maxx = (int)pointArray[i].X; miny = maxy = (int)pointArray[i].Y; } else { if (pointArray[i].X > maxx) maxx = (int)pointArray[i].X; if (pointArray[i].X < minx) minx = (int)pointArray[i].X; if (pointArray[i].Y > maxy) maxy = (int)pointArray[i].Y; if (pointArray[i].Y < miny) miny = (int)pointArray[i].Y; } } rectangle = new RectangleF(minx, miny, maxx - minx, maxy - miny); return rectangle; } internal void setNextPoint(PointF p) { AddPoint(p); startPoint = endPoint; endPoint = p; } internal void setEndPoint(PointF p) { endPoint = p; } public override List GetPoints() { return pointArray; } public override ParentStyleModel GetStyle() { return labelCurveModelStyleModel; } } }