using PaintDotNet.Annotation.Enum; using PaintDotNet.Base.SettingModel; using PaintDotNet.Base.CommTool; using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Windows.Forms; namespace PaintDotNet.Annotation.Measure { using PointList = List; /// /// 测量->长度测量->直线 /// public class MeasureLine : MeasureDrawObject { /// /// Graphic objects for hit test /// private GraphicsPath areaPath = null; /// /// Pen /// private Pen areaPen = null; /// /// Region /// private Region areaRegion = null; /// /// 直线长度 /// //private double length = 0.0; /// /// 样式信息 /// private MeasureStyleModel.MeasureLine measureLine; public PointList pointArray; /// /// 文本矩形定义 /// private RectangleF rectangleF1 = new RectangleF(); private RectangleF rectangleF2 = new RectangleF(); private RectangleF rectangleF3 = new RectangleF(); private RectangleF rectangleF4 = new RectangleF(); private RectangleF rectangleF5 = new RectangleF(); private RectangleF rectangleF6 = new RectangleF(); private RectangleF rectangleF7 = new RectangleF(); private RectangleF rectangleF8 = new RectangleF(); private RectangleF rectangleF9 = new RectangleF(); /// /// 文本上用于拖动的点 /// private Point pointL = new Point(); /// /// 绘制限制(第一次绘制时) /// public bool pointChange = true; /// /// 绘制限制(更改属性时) /// private bool SavePointChange; /// /// 绘制限制(从配置文件加载) /// public bool configurationFile = false; /// /// 区分移动文本 /// private int moveKb; /// /// 绘制属性 /// private string[] drawingPropertiesList; /// /// 绘制属性(克隆) /// private string[] drawingPropertiesListClone; /// /// 属性绘制点 /// private PointF rotationPoint; /// /// 旋转角度 /// private double angle; /// /// 是否移动了鼠标 /// public bool moved = false; /// /// 限制绘制(绘制中) /// public bool mouseUpPointChange = false; public MeasureLine(ISurfaceBox surfaceBox, PointF x, PointF y) : base(surfaceBox) { this.objectType = DrawClass.Measure; this.drawToolType = DrawToolType.MeasureLine; this.measurementUnit = (MeasurementUnit)System.Enum.Parse(typeof(MeasurementUnit), surfaceBox.GetPxPerUnit()[0]); this.unitString = surfaceBox.GetPxPerUnit()[1]; this.unit = surfaceBox.GetPxPerUnit()[2]; startPoint = x; endPoint = y; measureLine = this.ISurfaceBox.GetMeasureStyleModel().measureLine; } /// /// 测量属性 /// /// public override Dictionary GetData() { if (data.ContainsKey(MeasureAttributes.MeasureMethod)) data[MeasureAttributes.MeasureMethod] = PdnResources.GetString("Menu.MeasureAction.LengthMeasurement.Text"); else data.Add(MeasureAttributes.MeasureMethod, PdnResources.GetString("Menu.MeasureAction.LengthMeasurement.Text")); if (data.ContainsKey(MeasureAttributes.MeasureUnitCN)) data[MeasureAttributes.MeasureUnitCN] = this.unitString; else data.Add(MeasureAttributes.MeasureUnitCN, this.unitString); if (data.ContainsKey(MeasureAttributes.MeasureUnitEN)) data[MeasureAttributes.MeasureUnitEN] = this.unit; else data.Add(MeasureAttributes.MeasureUnitEN, this.unit); if (data.ContainsKey(MeasureAttributes.PixelStartX)) data[MeasureAttributes.PixelStartX] = startPoint.X; else data.Add(MeasureAttributes.PixelStartX, startPoint.X); if (data.ContainsKey(MeasureAttributes.PixelStartY)) data[MeasureAttributes.PixelStartY] = startPoint.Y; else data.Add(MeasureAttributes.PixelStartY, startPoint.Y); if (data.ContainsKey(MeasureAttributes.PhysicalStartX)) data[MeasureAttributes.PhysicalStartX] = Math.Round(startPoint.X * unitLength, decimalPlaces); else data.Add(MeasureAttributes.PhysicalStartX, Math.Round(startPoint.X * unitLength, decimalPlaces)); if (data.ContainsKey(MeasureAttributes.PhysicalStartY)) data[MeasureAttributes.PhysicalStartY] = Math.Round(startPoint.Y * unitLength, decimalPlaces); else data.Add(MeasureAttributes.PhysicalStartY, Math.Round(startPoint.Y * unitLength, decimalPlaces)); if (data.ContainsKey(MeasureAttributes.PixelLength)) data[MeasureAttributes.PixelLength] = Math.Round(length, decimalPlaces); else data.Add(MeasureAttributes.PixelLength, Math.Round(length, decimalPlaces)); string s = Math.Round(length * unitLength, decimalPlaces).ToString(); if (s.IndexOf(".") == -1) { for (int i = 0; i < decimalPlaces; i++) { if (i == 0) s += "."; s += "0"; } } else { int a = s.Length - s.IndexOf(".") - 1; if (a < decimalPlaces) { for (int i = 0; i < decimalPlaces - a; i++) { s += "0"; } } } if (data.ContainsKey(MeasureAttributes.PhysicalLength)) data[MeasureAttributes.PhysicalLength] = s; else data.Add(MeasureAttributes.PhysicalLength, s); return data; } public MeasureLine(ISurfaceBox surfaceBox, List points, ParentStyleModel parentStyleModel, Object content) : base() { this.objectType = DrawClass.Measure; this.drawToolType = DrawToolType.MeasureLine; this.ISurfaceBox = surfaceBox; measureLine = (MeasureStyleModel.MeasureLine)parentStyleModel; this.startPoint = points[0]; this.endPoint = points[1]; this.measurementUnit = (MeasurementUnit)System.Enum.Parse(typeof(MeasurementUnit), surfaceBox.GetPxPerUnit()[0]); this.unitString = surfaceBox.GetPxPerUnit()[1]; this.unit = surfaceBox.GetPxPerUnit()[2]; this.moved = true; this.configurationFile = true; } /// /// Clone this instance /// public override DrawObject Clone() { MeasureLine drawLine = new MeasureLine(ISurfaceBox, this.startPoint, this.endPoint); if (drawingPropertiesList != null) drawLine.drawingPropertiesListClone = drawingPropertiesList; drawLine.moved = true; FillDrawObjectFields(drawLine); return drawLine; } public override DrawObject Clone(ISurfaceBox surfaceBox) { MeasureLine drawLine = new MeasureLine(surfaceBox, this.GetPoints(), this.measureLine, null); if (drawingPropertiesList != null) drawLine.drawingPropertiesListClone = drawingPropertiesList; drawLine.moved = true; FillDrawObjectFields(drawLine); return drawLine; } public override void Draw(Graphics g) { if (this.moved) { measureLine = this.ISurfaceBox.GetMeasureStyleModel().measureLine; drawingProperties.TryGetValue(this.drawToolType, out drawingPropertiesList); if (drawingPropertiesList == null) { drawingPropertiesList = drawingPropertiesListClone; this.configurationFile = true; } pointChangeObject.TryGetValue(this.drawToolType, out SavePointChange); Font textfont = new Font(measureLine.font, measureLine.fontSize); Brush textbrush = new SolidBrush(Color.FromArgb(measureLine.textColor)); Pen linePen = new Pen(Color.FromArgb(measureLine.lineColor), measureLine.lineWidth); linePen.DashStyle = (DashStyle)measureLine.lineStyle; if (this.Selected) { if (measureLine.chooseStyle != null) { textfont = new Font(measureLine.chooseStyle.font, measureLine.chooseStyle.fontSize); textbrush = new SolidBrush(Color.FromArgb(measureLine.chooseStyle.textColor)); linePen = new Pen(Color.FromArgb(measureLine.chooseStyle.lineColor), measureLine.chooseStyle.lineWidth); linePen.DashStyle = (DashStyle)measureLine.chooseStyle.lineStyle; } } g.SmoothingMode = SmoothingMode.AntiAlias; Matrix mtxSave = g.Transform; Matrix matrix = g.Transform; //计算需要旋转的角度 angle = BasicCalculationHelper.Angle(startPoint, endPoint, new PointF(startPoint.X, endPoint.Y)); // 直线长度 length = BasicCalculationHelper.GetDistance(startPoint, endPoint, 10); // 直线中点 PointF pointF = new PointF((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2); // 求线上面三个点 int offsetValuePoint = measureLine.fontSize + measureLine.fontSize / 2; int offsetValue1Point = measureLine.lineWidth * 2 / 3; int offsetPoint = offsetValue1Point; if (!this.Selected) { this.pointChange = true; rectangleF1 = new RectangleF(); rectangleF2 = new RectangleF(); rectangleF3 = new RectangleF(); rectangleF4 = new RectangleF(); rectangleF5 = new RectangleF(); rectangleF6 = new RectangleF(); rectangleF7 = new RectangleF(); rectangleF8 = new RectangleF(); rectangleF9 = new RectangleF(); } if (drawingPropertiesList != null) { // 像素长度 if (drawingPropertiesList.Contains(MeasureAttributes.PixelLength.ToString())) { offsetPoint += offsetValuePoint; } // 物理长度 if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalLength.ToString())) { offsetPoint += offsetValuePoint; } // 测量方式 if (drawingPropertiesList.Contains(MeasureAttributes.MeasureMethod.ToString())) { offsetPoint += offsetValuePoint; } // 测量单位(中文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitCN.ToString())) { offsetPoint += offsetValuePoint; } // 测量单位(英文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitEN.ToString())) { offsetPoint += offsetValuePoint; } // 像素起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartX.ToString())) { offsetPoint += offsetValuePoint; } // 像素起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartY.ToString())) { offsetPoint += offsetValuePoint; } // 物理起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartX.ToString())) { offsetPoint += offsetValuePoint; } // 物理起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartY.ToString())) { offsetPoint += offsetValuePoint; } } PointF pointF1; PointF pointF2; if (angle < 90) pointF1 = BasicCalculationHelper.GetAnglePoint(new Point((int)startPoint.X + offsetPoint + offsetValue1Point, (int)startPoint.Y), startPoint, angle - 90); else pointF1 = BasicCalculationHelper.GetAnglePoint(new Point((int)startPoint.X + offsetPoint + offsetValue1Point, (int)startPoint.Y), startPoint, angle + 90); if (angle < 90) pointF2 = BasicCalculationHelper.GetAnglePoint(new Point((int)endPoint.X + offsetPoint + offsetValue1Point, (int)endPoint.Y), endPoint, angle - 90); else pointF2 = BasicCalculationHelper.GetAnglePoint(new Point((int)endPoint.X + offsetPoint + offsetValue1Point, (int)endPoint.Y), endPoint, angle + 90); PointF pointF3 = new PointF((pointF1.X + pointF2.X) / 2, (pointF1.Y + pointF2.Y) / 2); if (measureLine.linePosition == 0) this.rotationPoint = pointF1; else if (measureLine.linePosition == 1) this.rotationPoint = pointF3; else if (measureLine.linePosition == 2) this.rotationPoint = pointF2; else if (measureLine.linePosition == 3) this.rotationPoint = startPoint; else if (measureLine.linePosition == 4) this.rotationPoint = new PointF((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2); else if (measureLine.linePosition == 5) this.rotationPoint = endPoint; // 画布旋转 string frontStr = string.Empty; if (this.measureLine.showSuffix) { frontStr = this.measureLine.suffixName; } if (this.measureLine.showSerial) { #region [获取序号] List newGraphicsList = new List(); int n = ISurfaceBox.GraphicsList.Count; int num = 0; for (int i = n - 1; i >= 0; i--) { newGraphicsList.Add(ISurfaceBox.GraphicsList[i].Clone()); } var newGraphics = newGraphicsList.Where(m => m.ID.Equals(this.ID)).FirstOrDefault(); if (newGraphics != null) { num = newGraphicsList.IndexOf(newGraphics) + 1; } #endregion frontStr = $"[{ num }]{frontStr}"; } if (this.measureLine.showAlias) { frontStr = this.measureLine.aliasName + frontStr; } if (measureLine.followLine) { if (angle < 90) { matrix.RotateAt((float)angle, new PointF(this.rotationPoint.X, this.rotationPoint.Y)); g.Transform = matrix; } else { angle = BasicCalculationHelper.Angle(endPoint, startPoint, new PointF(endPoint.X, startPoint.Y)); matrix.RotateAt((float)angle, new PointF(this.rotationPoint.X, this.rotationPoint.Y)); g.Transform = matrix; } } SizeF sizeF = new SizeF(); // 是否绘制 if (this.pointChange || this.SavePointChange || this.mouseUpPointChange || this.mouseUpAttribute) { // 属性文本的间隔定义 int offsetValue = measureLine.fontSize + measureLine.fontSize / 2; int offsetValue1 = measureLine.lineWidth * 2 / 3; int offset = offsetValue1; this.pointL = new Point((int)this.rotationPoint.X, (int)this.rotationPoint.Y); if (drawingPropertiesList != null) { // 像素长度 if (drawingPropertiesList.Contains(MeasureAttributes.PixelLength.ToString())) { sizeF = g.MeasureString(frontStr + "" + Math.Round(length, decimalPlaces) + "px", textfont); if (measureLine.followLine) { rectangleF8.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF8.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 物理长度 if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalLength.ToString())) { string s = Math.Round(length * unitLength, decimalPlaces).ToString(); if (s.IndexOf(".") == -1) { for (int i = 0; i < decimalPlaces; i++) { if (i == 0) s += "."; s += "0"; } } else { int a = s.Length - s.IndexOf(".") - 1; if (a < decimalPlaces) { for (int i = 0; i < decimalPlaces - a; i++) { s += "0"; } } } sizeF = g.MeasureString(frontStr + s + this.unit, textfont); if (measureLine.followLine) { rectangleF9.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF9.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 测量方式 if (drawingPropertiesList.Contains(MeasureAttributes.MeasureMethod.ToString())) { sizeF = g.MeasureString(frontStr + PdnResources.GetString("Menu.MeasureAction.LengthMeasurement.Text"), textfont); if (measureLine.followLine) { rectangleF1.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF1.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 测量单位(中文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitCN.ToString())) { sizeF = g.MeasureString(frontStr + this.unitString, textfont); if (measureLine.followLine) { rectangleF2.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF2.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 测量单位(英文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitEN.ToString())) { sizeF = g.MeasureString(frontStr + this.unit, textfont); if (measureLine.followLine) { rectangleF3.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF3.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 像素起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartX.ToString())) { sizeF = g.MeasureString(frontStr + startPoint.X, textfont); if (measureLine.followLine) { rectangleF4.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF4.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 像素起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartY.ToString())) { sizeF = g.MeasureString(frontStr + startPoint.Y, textfont); if (measureLine.followLine) { rectangleF5.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF5.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 物理起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartX.ToString())) { sizeF = g.MeasureString(frontStr + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont); if (measureLine.followLine) { rectangleF6.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF6.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } // 物理起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartY.ToString())) { sizeF = g.MeasureString(frontStr + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont); if (measureLine.followLine) { rectangleF7.Location = new Point((int)this.rotationPoint.X + offsetValue1 - (int)sizeF.Width / 2, (int)this.rotationPoint.Y + offset); } else { rectangleF7.Location = getLevelPoint(this.startPoint, this.endPoint, this.rotationPoint, sizeF, measureLine.linePosition, offset, angle); } offset += offsetValue; } } } if (drawingPropertiesList != null) { // 测量方式 if (drawingPropertiesList.Contains(MeasureAttributes.MeasureMethod.ToString())) { sizeF = g.MeasureString(frontStr + PdnResources.GetString("Menu.MeasureAction.LengthMeasurement.Text"), textfont); rectangleF1.Width = sizeF.Width; rectangleF1.Height = sizeF.Height; g.DrawString(frontStr + PdnResources.GetString("Menu.MeasureAction.LengthMeasurement.Text"), textfont, textbrush, rectangleF1); } else { rectangleF1 = new RectangleF(); } // 测量单位(中文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitCN.ToString())) { sizeF = g.MeasureString(frontStr + this.unitString, textfont); rectangleF2.Width = sizeF.Width; rectangleF2.Height = sizeF.Height; g.DrawString(frontStr + this.unitString, textfont, textbrush, rectangleF2); } else { rectangleF2 = new RectangleF(); } // 测量单位(英文) if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitEN.ToString())) { sizeF = g.MeasureString(frontStr + this.unit, textfont); rectangleF3.Width = sizeF.Width; rectangleF3.Height = sizeF.Height; g.DrawString(frontStr + this.unit, textfont, textbrush, rectangleF3); } else { rectangleF3 = new RectangleF(); } // 像素起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartX.ToString())) { sizeF = g.MeasureString(frontStr + startPoint.X, textfont); rectangleF4.Width = sizeF.Width; rectangleF4.Height = sizeF.Height; g.DrawString(frontStr + startPoint.X, textfont, textbrush, rectangleF4); } else { rectangleF4 = new RectangleF(); } // 像素起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartY.ToString())) { sizeF = g.MeasureString(frontStr + startPoint.Y, textfont); rectangleF5.Width = sizeF.Width; rectangleF5.Height = sizeF.Height; g.DrawString(frontStr + startPoint.Y, textfont, textbrush, rectangleF5); } else { rectangleF5 = new RectangleF(); } // 物理起始点X if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartX.ToString())) { sizeF = g.MeasureString(frontStr + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont); rectangleF6.Width = sizeF.Width; rectangleF6.Height = sizeF.Height; g.DrawString(frontStr + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont, textbrush, rectangleF6); } else { rectangleF6 = new RectangleF(); } // 物理起始点Y if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartY.ToString())) { sizeF = g.MeasureString(frontStr + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont); rectangleF7.Width = sizeF.Width; rectangleF7.Height = sizeF.Height; g.DrawString(frontStr + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont, textbrush, rectangleF7); } else { rectangleF7 = new RectangleF(); } // 像素长度 if (drawingPropertiesList.Contains(MeasureAttributes.PixelLength.ToString())) { sizeF = g.MeasureString(frontStr + Math.Round(length, decimalPlaces) + "px", textfont); rectangleF8.Width = sizeF.Width; rectangleF8.Height = sizeF.Height; g.DrawString(frontStr + Math.Round(length, decimalPlaces) + "px", textfont, textbrush, rectangleF8); } else { rectangleF8 = new RectangleF(); } // 物理长度 if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalLength.ToString())) { string s = Math.Round(length * unitLength, decimalPlaces).ToString(); if (s.IndexOf(".") == -1) { for (int i = 0; i < decimalPlaces; i++) { if (i == 0) s += "."; s += "0"; } } else { int a = s.Length - s.IndexOf(".") - 1; if (a < decimalPlaces) { for (int i = 0; i < decimalPlaces - a; i++) { s += "0"; } } } sizeF = g.MeasureString(frontStr + s + this.unit, textfont); rectangleF9.Width = sizeF.Width; rectangleF9.Height = sizeF.Height; g.DrawString(frontStr + s + this.unit, textfont, textbrush, rectangleF9); } else { rectangleF9 = new RectangleF(); } } //还原为原始旋转矩阵 g.Transform = mtxSave; PointF point = BasicCalculationHelper.GetAnglePoint(new PointF(startPoint.X, startPoint.Y + measureLine.vLineLength), startPoint, angle); PointF point1 = BasicCalculationHelper.GetAnglePoint(new PointF(startPoint.X, startPoint.Y - measureLine.vLineLength), startPoint, angle); PointF point2 = BasicCalculationHelper.GetAnglePoint(new PointF(endPoint.X, endPoint.Y + measureLine.vLineLength), endPoint, angle); PointF point3 = BasicCalculationHelper.GetAnglePoint(new PointF(endPoint.X, endPoint.Y - measureLine.vLineLength), endPoint, angle); if (this.Selected) { if (measureLine.chooseStyle != null) { point = BasicCalculationHelper.GetAnglePoint(new PointF(startPoint.X, startPoint.Y + measureLine.chooseStyle.vLineLength), startPoint, angle); point1 = BasicCalculationHelper.GetAnglePoint(new PointF(startPoint.X, startPoint.Y - measureLine.chooseStyle.vLineLength), startPoint, angle); point2 = BasicCalculationHelper.GetAnglePoint(new PointF(endPoint.X, endPoint.Y + measureLine.chooseStyle.vLineLength), endPoint, angle); point3 = BasicCalculationHelper.GetAnglePoint(new PointF(endPoint.X, endPoint.Y - measureLine.chooseStyle.vLineLength), endPoint, angle); } } g.DrawLine(linePen, point.X, point.Y, point1.X, point1.Y); g.DrawLine(linePen, point2.X, point2.Y, point3.X, point3.Y); g.DrawLine(linePen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); matrix.Dispose(); this.pointArray = new PointList(); this.pointArray.Add(this.startPoint); this.pointArray.Add(this.endPoint); linePen.Dispose(); if (this.configurationFile) this.pointChange = false; this.mouseUpAttribute = false; pointChangeObject.Remove(this.drawToolType); } } /// /// 停止绘制时 /// /// public override void MouseUp(bool up) { mouseUpPointChange = up; } public override int HandleCount { get { return 3; } } /// /// Get handle pointscroll by 1-based number /// /// /// public override PointF GetHandle(int handleNumber) { if (handleNumber == 1) return startPoint; else if (handleNumber == 2) return endPoint; else return pointL; } /// /// 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 (GetRectanglePosition(this.rectangleF1, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 1; return 3; } else if (GetRectanglePosition(this.rectangleF2, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 2; return 3; } else if (GetRectanglePosition(this.rectangleF3, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 3; return 3; } else if (GetRectanglePosition(this.rectangleF4, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 4; return 3; } else if (GetRectanglePosition(this.rectangleF5, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 5; return 3; } else if (GetRectanglePosition(this.rectangleF6, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 6; return 3; } else if (GetRectanglePosition(this.rectangleF7, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 7; return 3; } else if (GetRectanglePosition(this.rectangleF8, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 8; return 3; } else if (GetRectanglePosition(this.rectangleF9, point, this.rotationPoint, angle)) { this.pointL = SetOffsetAfterRotation(point, this.rotationPoint, angle); moveKb = 9; return 3; } } 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 Cursor GetHandleCursor(int handleNumber) { switch (handleNumber) { case 1: case 2: case 3: return handleCursor;// Cursors.SizeAll; default: return Cursors.Default; } } public override void MoveHandleTo(Point point, int handleNumber) { if (handleNumber == 1) { if (this.pointArray != null && this.pointArray.Count > 0) { this.mouseUpPointChange = true; this.rectangleF1.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF2.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF3.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF4.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF5.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF6.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF7.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF8.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); this.rectangleF9.Offset(point.X - this.pointArray[0].X, point.Y - this.pointArray[0].Y); startPoint = point; } } else if (handleNumber == 2) { this.mouseUpPointChange = true; endPoint = point; } else { point = SetOffsetAfterRotation(point, this.rotationPoint, angle); if (this.moveKb == 1) this.rectangleF1.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 2) this.rectangleF2.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 3) this.rectangleF3.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 4) this.rectangleF4.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 5) this.rectangleF5.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 6) this.rectangleF6.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 7) this.rectangleF7.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 8) this.rectangleF8.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); else if (this.moveKb == 9) this.rectangleF9.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y); this.pointL = point; } Invalidate(); } public override void Move(int deltaX, int deltaY) { int x = ISurfaceBox.UnscaleScalar(deltaX); int y = ISurfaceBox.UnscaleScalar(deltaY); startPoint.X += x; startPoint.Y += y; endPoint.X += x; endPoint.Y += y; pointL.X += x; pointL.Y += y; this.rectangleF1.Offset(x, y); this.rectangleF2.Offset(x, y); this.rectangleF3.Offset(x, y); this.rectangleF4.Offset(x, y); this.rectangleF5.Offset(x, y); this.rectangleF6.Offset(x, y); this.rectangleF7.Offset(x, y); this.rectangleF8.Offset(x, y); this.rectangleF9.Offset(x, y); Invalidate(); } /// /// 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; } } /// /// Create graphic objects used from hit test. /// protected virtual void CreateObjects() { if (AreaPath != null) return; // Create path which contains wide line // for easy mouse selection AreaPath = new GraphicsPath(); AreaPen = new Pen(Color.Black, 7); AreaPath.AddLine(startPoint.X - 1, startPoint.Y - 1, endPoint.X + 1, endPoint.Y + 1); AreaPath.Widen(AreaPen); // Create region from the path AreaRegion = new Region(AreaPath); } 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; } } public override RectangleF GetBoundingBox() { RectangleF rectangle = GetNotmalizedRectangle(startPoint, endPoint); return rectangle; } public static RectangleF GetNotmalizedRectangle(PointF a, PointF b) { RectangleF rect = new RectangleF(); if (a.X < b.X) { rect.X = a.X; rect.Width = b.X - a.X; } else { rect.X = b.X; rect.Width = a.X - b.X; } if (a.Y < b.Y) { rect.Y = a.Y; rect.Height = b.Y - a.Y; } else { rect.Y = b.Y; rect.Height = a.Y - b.Y; } return rect; } /// /// 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++) { if (i == 3) { brush = new SolidBrush(Color.Transparent); pen = new Pen(Color.Transparent); } 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(); } public override List GetPoints() { return pointArray; } public override ParentStyleModel GetStyle() { return measureLine; } /// /// 获取水平文字时的起始坐标 /// /// private PointF getLevelPoint(PointF lineStartPoint, PointF lineEndPoint, PointF lineRotationPoint, SizeF sizeF, int type, int offset, double angle) { var startPoint = new PointF(); switch (type) { case 0: if (angle < 0) { startPoint = new PointF(lineStartPoint.X - sizeF.Width - 10, lineStartPoint.Y - sizeF.Height - offset); } else if (angle < 90) { startPoint = new PointF(lineStartPoint.X, lineStartPoint.Y - sizeF.Height - offset); } else if (angle < 180) { startPoint = new PointF(lineStartPoint.X - sizeF.Width - 10, lineStartPoint.Y - sizeF.Height - offset); } else if (angle <= 270) { startPoint = new PointF(lineStartPoint.X, lineStartPoint.Y - sizeF.Height - offset); } break; case 1: if (angle == 0) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width - 10, lineRotationPoint.Y + offset); } else if (angle < -5) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width - 10, lineRotationPoint.Y + offset); } else if (angle < 5) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width / 2, lineRotationPoint.Y + offset); } else if (angle < 90) { startPoint = new PointF(lineRotationPoint.X - 10, lineRotationPoint.Y + offset); } else if (angle < 175) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width + 10, lineRotationPoint.Y + offset); } else if (angle < 185) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width / 2, lineRotationPoint.Y + offset); } else if (angle <= 270) { startPoint = new PointF(lineRotationPoint.X, lineRotationPoint.Y + offset); } break; case 2: if (angle < 0) { startPoint = new PointF(lineEndPoint.X, lineEndPoint.Y - sizeF.Height - offset); } else if (angle < 90) { startPoint = new PointF(lineEndPoint.X, lineEndPoint.Y); } else if (angle < 180) { startPoint = new PointF(lineEndPoint.X - sizeF.Width - 10, lineEndPoint.Y - sizeF.Height - offset); } else if (angle <= 270) { startPoint = new PointF(lineEndPoint.X, lineEndPoint.Y - sizeF.Height - offset); } break; case 3: if (angle < 0) { startPoint = new PointF(lineStartPoint.X, lineStartPoint.Y + offset); } else if (angle < 90) { startPoint = new PointF(lineStartPoint.X - sizeF.Width - 10, lineStartPoint.Y + offset); } else if (angle < 180) { startPoint = new PointF(lineStartPoint.X, lineStartPoint.Y + offset); } else if (angle <= 270) { startPoint = new PointF(lineStartPoint.X - sizeF.Width - 10, lineStartPoint.Y + offset); } break; case 4: if (angle == 0) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width - 10, lineRotationPoint.Y + offset); } if (angle < -5) { startPoint = new PointF(lineRotationPoint.X, lineRotationPoint.Y + offset); } else if (angle < 5) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width / 2, lineRotationPoint.Y + offset); } else if (angle < 90) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width - 10, lineRotationPoint.Y + offset); } else if (angle < 180) { startPoint = new PointF(lineRotationPoint.X + 10, lineRotationPoint.Y + offset); } else if (angle <= 270) { startPoint = new PointF(lineRotationPoint.X - sizeF.Width - 10, lineRotationPoint.Y + offset); } break; case 5: if (angle < 0) { startPoint = new PointF(lineEndPoint.X, lineEndPoint.Y + offset); } else if (angle < 90) { startPoint = new PointF(lineEndPoint.X, lineEndPoint.Y + offset); } else if (angle < 175) { startPoint = new PointF(lineEndPoint.X - sizeF.Width - 10, lineEndPoint.Y + offset); } else if (angle < 185) { startPoint = new PointF(lineEndPoint.X - sizeF.Width / 2, lineEndPoint.Y + offset); } else if (angle <= 270) { startPoint = new PointF(lineEndPoint.X - sizeF.Width - 10, lineEndPoint.Y + offset); } break; } return startPoint; } } }