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 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(); } }