private static void RenderTwoStrokeNodes(StreamGeometryContext context, StrokeNode strokeNodePrevious, Rect strokeNodePreviousBounds, StrokeNode strokeNodeCurrent, Rect strokeNodeCurrentBounds, List <Point> pointBuffer1, List <Point> pointBuffer2, List <Point> pointBuffer3) { if (FuzzyContains(strokeNodePreviousBounds, strokeNodeCurrentBounds, 70.0) != RectCompareResult.NoItersection) { strokeNodePrevious.GetContourPoints(pointBuffer1); AddFigureToStreamGeometryContext(context, pointBuffer1, strokeNodePrevious.IsEllipse); Quad connectingQuad = strokeNodeCurrent.GetConnectingQuad(); if (!connectingQuad.IsEmpty) { pointBuffer3.Add(connectingQuad.A); pointBuffer3.Add(connectingQuad.B); pointBuffer3.Add(connectingQuad.C); pointBuffer3.Add(connectingQuad.D); AddFigureToStreamGeometryContext(context, pointBuffer3, isBezierFigure: false); } strokeNodeCurrent.GetContourPoints(pointBuffer2); AddFigureToStreamGeometryContext(context, pointBuffer2, strokeNodeCurrent.IsEllipse); } else { strokeNodeCurrent.GetPointsAtStartOfSegment(pointBuffer1, pointBuffer2); strokeNodeCurrent.GetPointsAtEndOfSegment(pointBuffer1, pointBuffer2); ReverseDCPointsRenderAndClear(context, pointBuffer1, pointBuffer2, pointBuffer3, strokeNodeCurrent.IsEllipse, clear: false); } }
internal bool HitTest(StrokeNode hitNode) { if (!IsValid || !hitNode.IsValid) { return(false); } IEnumerable <ContourSegment> contourSegments = hitNode.GetContourSegments(); return(_operations.HitTest(_lastNode, _thisNode, ConnectingQuad, contourSegments)); }
internal StrokeFIndices CutTest(StrokeNode hitNode) { if (!IsValid || !hitNode.IsValid) { return(StrokeFIndices.Empty); } IEnumerable <ContourSegment> contourSegments = hitNode.GetContourSegments(); StrokeFIndices strokeFIndices = _operations.CutTest(_lastNode, _thisNode, ConnectingQuad, contourSegments); if (_index != 0) { return(BindFIndices(strokeFIndices)); } return(strokeFIndices); }
internal static void CalcGeometryAndBoundsWithTransform(StrokeNodeIterator iterator, DrawingAttributes drawingAttributes, MatrixTypes stylusTipMatrixType, bool calculateBounds, out Geometry geometry, out Rect bounds) { StreamGeometry streamGeometry = new StreamGeometry(); streamGeometry.FillRule = FillRule.Nonzero; StreamGeometryContext streamGeometryContext = streamGeometry.Open(); geometry = streamGeometry; bounds = Rect.Empty; try { List <Point> list = new List <Point>(iterator.Count * 4); int num = iterator.Count * 2; int num2 = 0; for (int i = 0; i < num; i++) { list.Add(new Point(0.0, 0.0)); } List <Point> list2 = new List <Point>(); double lastAngle = 0.0; bool flag = false; Rect rect = new Rect(0.0, 0.0, 0.0, 0.0); for (int j = 0; j < iterator.Count; j++) { StrokeNode strokeNode = iterator[j]; Rect bounds2 = strokeNode.GetBounds(); if (calculateBounds) { bounds.Union(bounds2); } double num3 = Math.Abs(GetAngleDeltaFromLast(strokeNode.PreviousPosition, strokeNode.Position, ref lastAngle)); double num4 = 45.0; if (stylusTipMatrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) { num4 = 10.0; } else if (bounds2.Height > 40.0 || bounds2.Width > 40.0) { num4 = 20.0; } bool flag2 = num3 > num4 && num3 < 360.0 - num4; double val = rect.Height * rect.Width; double val2 = bounds2.Height * bounds2.Width; bool flag3 = false; if (Math.Min(val, val2) / Math.Max(val, val2) <= 0.7) { flag3 = true; } rect = bounds2; if ((j <= 1 || j >= iterator.Count - 2) | flag2 | flag3) { if (flag2 && !flag && j > 1 && j < iterator.Count - 1) { list2.Clear(); strokeNode.GetPreviousContourPoints(list2); AddFigureToStreamGeometryContext(streamGeometryContext, list2, strokeNode.IsEllipse); flag = true; } list2.Clear(); strokeNode.GetContourPoints(list2); AddFigureToStreamGeometryContext(streamGeometryContext, list2, strokeNode.IsEllipse); } if (!flag2) { flag = false; } Quad connectingQuad = strokeNode.GetConnectingQuad(); if (!connectingQuad.IsEmpty) { list[num2++] = connectingQuad.A; list[num2++] = connectingQuad.B; list.Add(connectingQuad.D); list.Add(connectingQuad.C); } if (strokeNode.IsLastNode && num2 > 0) { int num5 = iterator.Count * 2; int num6 = list.Count - 1; int num7 = num2; for (int k = num5; k <= num6; k++) { list[num7] = list[k]; num7++; } int num8 = num5 - num2; list.RemoveRange(num6 - num8 + 1, num8); int num9 = num2; int num10 = list.Count - 1; while (num9 < num10) { Point value = list[num9]; list[num9] = list[num10]; list[num10] = value; num9++; num10--; } AddFigureToStreamGeometryContext(streamGeometryContext, list, isBezierFigure: false); } } } finally { streamGeometryContext.Close(); geometry.Freeze(); } }
internal static void CalcGeometryAndBounds(StrokeNodeIterator iterator, DrawingAttributes drawingAttributes, bool calculateBounds, out Geometry geometry, out Rect bounds) { Matrix stylusTipTransform = drawingAttributes.StylusTipTransform; if (stylusTipTransform != Matrix.Identity) { CalcGeometryAndBoundsWithTransform(iterator, drawingAttributes, MatrixTypes.TRANSFORM_IS_TRANSLATION, calculateBounds, out geometry, out bounds); return; } StreamGeometry streamGeometry = new StreamGeometry(); streamGeometry.FillRule = FillRule.Nonzero; StreamGeometryContext streamGeometryContext = streamGeometry.Open(); geometry = streamGeometry; Rect rect = bounds = Rect.Empty; try { StrokeNode strokeNode = default(StrokeNode); StrokeNode strokeNodePrevious = default(StrokeNode); StrokeNode strokeNode2 = default(StrokeNode); StrokeNode strokeNode3 = default(StrokeNode); Rect rect2 = rect; Rect rect3 = rect; Rect rect4 = rect; double num = 95.0; double num2 = Math.Max(drawingAttributes.Height, drawingAttributes.Width); num += Math.Min(4.99999, num2 / 20.0 * 5.0); double lastAngle = double.MinValue; bool flag = true; bool isEllipse = drawingAttributes.StylusTip == StylusTip.Ellipse; bool ignorePressure = drawingAttributes.IgnorePressure; List <Point> list = new List <Point>(); List <Point> list2 = new List <Point>(); List <Point> list3 = new List <Point>(4); int count = iterator.Count; int num3 = 0; int previousIndex = -1; while (num3 < count) { if (!strokeNodePrevious.IsValid) { if (!strokeNode2.IsValid) { strokeNodePrevious = iterator[num3++, previousIndex++]; rect2 = strokeNodePrevious.GetBounds(); continue; } strokeNodePrevious = strokeNode2; rect2 = rect3; strokeNode2 = strokeNode; } if (!strokeNode2.IsValid) { if (!strokeNode3.IsValid) { strokeNode2 = iterator[num3++, previousIndex]; rect3 = strokeNode2.GetBounds(); switch (FuzzyContains(rect3, rect2, flag ? 99.99999 : num)) { case RectCompareResult.Rect1ContainsRect2: strokeNodePrevious = iterator[num3 - 1, strokeNodePrevious.Index - 1]; rect2 = Rect.Union(rect3, rect2); strokeNode2 = strokeNode; previousIndex = num3 - 1; break; case RectCompareResult.Rect2ContainsRect1: strokeNode2 = strokeNode; break; default: previousIndex = num3 - 1; break; } continue; } strokeNode2 = strokeNode3; rect3 = rect4; strokeNode3 = strokeNode; } if (!strokeNode3.IsValid) { strokeNode3 = iterator[num3++, previousIndex]; rect4 = strokeNode3.GetBounds(); RectCompareResult rectCompareResult = FuzzyContains(rect4, rect3, flag ? 99.99999 : num); RectCompareResult rectCompareResult2 = FuzzyContains(rect4, rect2, flag ? 99.99999 : num); if (flag && rectCompareResult == RectCompareResult.Rect1ContainsRect2 && rectCompareResult2 == RectCompareResult.Rect1ContainsRect2) { if (list.Count > 0) { strokeNode2.GetPointsAtEndOfSegment(list, list2); ReverseDCPointsRenderAndClear(streamGeometryContext, list, list2, list3, isEllipse, clear: true); } strokeNodePrevious = iterator[num3 - 1, strokeNodePrevious.Index - 1]; rect2 = strokeNodePrevious.GetBounds(); strokeNode2 = strokeNode; strokeNode3 = strokeNode; previousIndex = num3 - 1; continue; } switch (rectCompareResult) { case RectCompareResult.Rect1ContainsRect2: strokeNode3 = iterator[num3 - 1, strokeNode2.Index - 1]; if (!strokeNode3.GetConnectingQuad().IsEmpty) { strokeNode2 = strokeNode3; rect3 = Rect.Union(rect4, rect3); previousIndex = num3 - 1; } strokeNode3 = strokeNode; lastAngle = double.MinValue; continue; case RectCompareResult.Rect2ContainsRect1: strokeNode3 = strokeNode; continue; } previousIndex = num3 - 1; } bool flag2 = rect2.IntersectsWith(rect4); if (calculateBounds) { bounds.Union(rect3); } if (list.Count == 0) { if (calculateBounds) { bounds.Union(rect2); } if (flag && flag2) { strokeNodePrevious.GetContourPoints(list3); AddFigureToStreamGeometryContext(streamGeometryContext, list3, strokeNodePrevious.IsEllipse); list3.Clear(); } strokeNode2.GetPointsAtStartOfSegment(list, list2); flag = false; } if (lastAngle == double.MinValue) { lastAngle = GetAngleBetween(strokeNodePrevious.Position, strokeNode2.Position); } double angleDeltaFromLast = GetAngleDeltaFromLast(strokeNode2.Position, strokeNode3.Position, ref lastAngle); bool flag3 = Math.Abs(angleDeltaFromLast) > 90.0 && Math.Abs(angleDeltaFromLast) < 270.0; bool flag4 = flag2 && !ignorePressure && strokeNode3.PressureFactor != 1f && Math.Abs(angleDeltaFromLast) > 30.0 && Math.Abs(angleDeltaFromLast) < 330.0; double num4 = rect3.Height * rect3.Width; double num5 = rect4.Height * rect4.Width; bool flag5 = num4 != num5 || num4 != rect2.Height * rect2.Width; bool flag6 = false; if (flag2 && flag5 && Math.Min(num4, num5) / Math.Max(num4, num5) <= 0.9) { flag6 = true; } if (flag5 || angleDeltaFromLast != 0.0 || num3 >= count) { if ((flag2 && (flag4 | flag6)) | flag3) { strokeNode2.GetPointsAtEndOfSegment(list, list2); ReverseDCPointsRenderAndClear(streamGeometryContext, list, list2, list3, isEllipse, clear: true); if (flag6) { strokeNode2.GetContourPoints(list3); AddFigureToStreamGeometryContext(streamGeometryContext, list3, strokeNode2.IsEllipse); list3.Clear(); } } else { strokeNode3.GetPointsAtMiddleSegment(strokeNode2, angleDeltaFromLast, list, list2, out bool missingIntersection); if (missingIntersection) { strokeNode2.GetPointsAtEndOfSegment(list, list2); ReverseDCPointsRenderAndClear(streamGeometryContext, list, list2, list3, isEllipse, clear: true); } } } strokeNodePrevious = strokeNode; rect2 = rect; } if (strokeNodePrevious.IsValid) { if (strokeNode2.IsValid) { if (calculateBounds) { bounds.Union(rect2); bounds.Union(rect3); } if (list.Count > 0) { strokeNode2.GetPointsAtEndOfSegment(list, list2); ReverseDCPointsRenderAndClear(streamGeometryContext, list, list2, list3, isEllipse, clear: false); } else { RenderTwoStrokeNodes(streamGeometryContext, strokeNodePrevious, rect2, strokeNode2, rect3, list, list2, list3); } } else { if (calculateBounds) { bounds.Union(rect2); } strokeNodePrevious.GetContourPoints(list); AddFigureToStreamGeometryContext(streamGeometryContext, list, strokeNodePrevious.IsEllipse); } } else if (strokeNode2.IsValid && strokeNode3.IsValid) { if (calculateBounds) { bounds.Union(rect3); bounds.Union(rect4); } if (list.Count > 0) { strokeNode3.GetPointsAtEndOfSegment(list, list2); ReverseDCPointsRenderAndClear(streamGeometryContext, list, list2, list3, isEllipse, clear: false); if (FuzzyContains(rect4, rect3, 70.0) != RectCompareResult.NoItersection) { strokeNode3.GetContourPoints(list3); AddFigureToStreamGeometryContext(streamGeometryContext, list3, strokeNode3.IsEllipse); } } else { RenderTwoStrokeNodes(streamGeometryContext, strokeNode2, rect3, strokeNode3, rect4, list, list2, list3); } } } finally { streamGeometryContext.Close(); geometry.Freeze(); } }
internal void GetPointsAtMiddleSegment(StrokeNode previous, double angleBetweenNodes, List <Point> abPoints, List <Point> dcPoints, out bool missingIntersection) { missingIntersection = false; if (!IsValid || !previous.IsValid) { return; } Quad connectingQuad = previous.ConnectingQuad; if (connectingQuad.IsEmpty) { return; } Quad connectingQuad2 = ConnectingQuad; if (connectingQuad2.IsEmpty) { return; } if (IsEllipse) { Rect nodeBounds = _operations.GetNodeBounds(previous._lastNode); Rect nodeBounds2 = _operations.GetNodeBounds(_lastNode); Rect nodeBounds3 = _operations.GetNodeBounds(_thisNode); if (angleBetweenNodes == 0.0 || (connectingQuad.B == connectingQuad2.A && connectingQuad.C == connectingQuad2.D)) { abPoints.Add(connectingQuad.B); dcPoints.Add(connectingQuad.C); return; } if (angleBetweenNodes > 0.0) { if (connectingQuad.B == connectingQuad2.A) { abPoints.Add(connectingQuad.B); } else { Point intersection = GetIntersection(connectingQuad.A, connectingQuad.B, connectingQuad2.A, connectingQuad2.B); Rect rect = Rect.Union(nodeBounds, nodeBounds2); rect.Inflate(1.0, 1.0); if (!rect.Contains(intersection)) { missingIntersection = true; return; } abPoints.Add(intersection); } if (connectingQuad.C == connectingQuad2.D) { dcPoints.Add(connectingQuad.C); return; } dcPoints.Add(connectingQuad.C); dcPoints.Add(new Point(nodeBounds2.Width, nodeBounds2.Height)); dcPoints.Add(StrokeRenderer.ArcToMarker); dcPoints.Add(connectingQuad2.D); return; } if (connectingQuad.C == connectingQuad2.D) { dcPoints.Add(connectingQuad.C); } else { Point intersection2 = GetIntersection(connectingQuad.D, connectingQuad.C, connectingQuad2.D, connectingQuad2.C); Rect rect2 = Rect.Union(nodeBounds, nodeBounds2); rect2.Inflate(1.0, 1.0); if (!rect2.Contains(intersection2)) { missingIntersection = true; return; } dcPoints.Add(intersection2); } if (connectingQuad.B == connectingQuad2.A) { abPoints.Add(connectingQuad.B); return; } abPoints.Add(connectingQuad.B); abPoints.Add(StrokeRenderer.ArcToMarker); abPoints.Add(new Point(nodeBounds2.Width, nodeBounds2.Height)); abPoints.Add(connectingQuad2.A); return; } int num = -1; int num2 = -1; int num3 = -1; int num4 = -1; Vector[] vertices = _operations.GetVertices(); double scalar = _lastNode.PressureFactor; for (int i = 0; i < vertices.Length; i++) { Point point = _lastNode.Position + vertices[i % vertices.Length] * scalar; if (point == connectingQuad2.A) { num = i; } if (point == connectingQuad.B) { num2 = i; } if (point == connectingQuad.C) { num3 = i; } if (point == connectingQuad2.D) { num4 = i; } } if (num == -1 || num2 == -1 || num3 == -1 || num4 == -1) { return; } Rect nodeBounds4 = _operations.GetNodeBounds(_thisNode); if (num == num2) { if (!nodeBounds4.Contains(connectingQuad.B)) { abPoints.Add(connectingQuad.B); } } else if ((num == 0 && num2 == 3) || ((num != 3 || num2 != 0) && num > num2)) { if (!nodeBounds4.Contains(connectingQuad.B)) { abPoints.Add(connectingQuad.B); } if (!nodeBounds4.Contains(connectingQuad2.A)) { abPoints.Add(connectingQuad2.A); } } else { Point intersection3 = GetIntersection(connectingQuad.A, connectingQuad.B, connectingQuad2.A, connectingQuad2.B); Rect rect3 = Rect.Union(_operations.GetNodeBounds(previous._lastNode), _operations.GetNodeBounds(_lastNode)); rect3.Inflate(1.0, 1.0); if (!rect3.Contains(intersection3)) { missingIntersection = true; return; } abPoints.Add(intersection3); } if (num3 == num4) { if (!nodeBounds4.Contains(connectingQuad.C)) { dcPoints.Add(connectingQuad.C); } } else if ((num3 == 0 && num4 == 3) || ((num3 != 3 || num4 != 0) && num3 > num4)) { if (!nodeBounds4.Contains(connectingQuad.C)) { dcPoints.Add(connectingQuad.C); } if (!nodeBounds4.Contains(connectingQuad2.D)) { dcPoints.Add(connectingQuad2.D); } } else { Point intersection4 = GetIntersection(connectingQuad.D, connectingQuad.C, connectingQuad2.D, connectingQuad2.C); Rect rect4 = Rect.Union(_operations.GetNodeBounds(previous._lastNode), _operations.GetNodeBounds(_lastNode)); rect4.Inflate(1.0, 1.0); if (rect4.Contains(intersection4)) { dcPoints.Add(intersection4); } else { missingIntersection = true; } } }