Example #1
0
 internal StrokeNode this[int index, int previousIndex]
 {
     get
     {
         if (_stylusPoints == null || index < 0 || index >= _stylusPoints.Count || previousIndex < -1 || previousIndex >= index)
         {
             throw new IndexOutOfRangeException();
         }
         StylusPoint stylusPoint  = _stylusPoints[index];
         StylusPoint stylusPoint2 = (previousIndex == -1) ? default(StylusPoint) : _stylusPoints[previousIndex];
         float       pressure     = 1f;
         float       pressure2    = 1f;
         if (_usePressure)
         {
             pressure  = GetNormalizedPressureFactor(stylusPoint.PressureFactor);
             pressure2 = GetNormalizedPressureFactor(stylusPoint2.PressureFactor);
         }
         StrokeNodeData nodeData     = new StrokeNodeData((System.Windows.Point)stylusPoint, pressure);
         StrokeNodeData lastNodeData = StrokeNodeData.Empty;
         if (previousIndex != -1)
         {
             lastNodeData = new StrokeNodeData((System.Windows.Point)stylusPoint2, pressure2);
         }
         return(new StrokeNode(_operations, previousIndex + 1, nodeData, lastNodeData, index == _stylusPoints.Count - 1));
     }
 }
Example #2
0
        internal override bool HitTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour)
        {
            double         num = 0.0;
            StrokeNodeData strokeNodeData;
            Vector         vector;

            if (beginNode.IsEmpty || (quad.IsEmpty && endNode.PressureFactor > beginNode.PressureFactor))
            {
                strokeNodeData = endNode;
                StrokeNodeData empty = StrokeNodeData.Empty;
                vector = default(Vector);
            }
            else
            {
                strokeNodeData = beginNode;
                StrokeNodeData empty = endNode;
                num    = _radius * (double)empty.PressureFactor;
                num   *= num;
                vector = empty.Position - strokeNodeData.Position;
                if (!_nodeShapeToCircle.IsIdentity)
                {
                    vector = _nodeShapeToCircle.Transform(vector);
                }
            }
            double num2 = _radius * (double)strokeNodeData.PressureFactor;

            num2 *= num2;
            bool flag  = false;
            bool flag2 = true;

            foreach (ContourSegment item in hitContour)
            {
                if (!item.IsArc)
                {
                    Vector vector2 = item.Begin - strokeNodeData.Position;
                    Vector vector3 = vector2 + item.Vector;
                    if (!_nodeShapeToCircle.IsIdentity)
                    {
                        vector2 = _nodeShapeToCircle.Transform(vector2);
                        vector3 = _nodeShapeToCircle.Transform(vector3);
                    }
                    if (StrokeNodeOperations.GetNearest(vector2, vector3).LengthSquared <= num2)
                    {
                        flag = true;
                        break;
                    }
                    if (!quad.IsEmpty && (StrokeNodeOperations.GetNearest(vector2 - vector, vector3 - vector).LengthSquared <= num || StrokeNodeOperations.HitTestQuadSegment(quad, item.Begin, item.End)))
                    {
                        flag = true;
                        break;
                    }
                    if (flag2 && StrokeNodeOperations.WhereIsVectorAboutVector(endNode.Position - item.Begin, item.Vector) != HitResult.Right)
                    {
                        flag2 = false;
                    }
                }
            }
            return(flag | flag2);
        }
 internal virtual bool HitTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour)
 {
     if (quad.IsEmpty)
     {
         return(HitTestPolygonContourSegments(hitContour, beginNode, endNode));
     }
     return(HitTestInkContour(hitContour, quad, beginNode, endNode));
 }
        internal virtual StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint)
        {
            StrokeFIndices empty = StrokeFIndices.Empty;

            for (int i = beginNode.IsEmpty ? 1 : 0; i < 2; i++)
            {
                Point  point    = (i == 0) ? beginNode.Position : endNode.Position;
                double num      = (i == 0) ? beginNode.PressureFactor : endNode.PressureFactor;
                Vector hitBegin = hitBeginPoint - point;
                Vector hitEnd   = hitEndPoint - point;
                if (num != 1.0)
                {
                    hitBegin /= num;
                    hitEnd   /= num;
                }
                if (!HitTestPolygonSegment(_vertices, hitBegin, hitEnd))
                {
                    continue;
                }
                if (i == 0)
                {
                    empty.BeginFIndex = StrokeFIndices.BeforeFirst;
                    empty.EndFIndex   = 0.0;
                    continue;
                }
                empty.EndFIndex = StrokeFIndices.AfterLast;
                if (beginNode.IsEmpty)
                {
                    empty.BeginFIndex = StrokeFIndices.BeforeFirst;
                }
                else if (empty.BeginFIndex != StrokeFIndices.BeforeFirst)
                {
                    empty.BeginFIndex = 1.0;
                }
            }
            if (empty.IsFull)
            {
                return(empty);
            }
            if (empty.IsEmpty && (quad.IsEmpty || !HitTestQuadSegment(quad, hitBeginPoint, hitEndPoint)))
            {
                return(empty);
            }
            if (empty.BeginFIndex != StrokeFIndices.BeforeFirst)
            {
                empty.BeginFIndex = ClipTest((endNode.Position - beginNode.Position) / beginNode.PressureFactor, endNode.PressureFactor / beginNode.PressureFactor - 1f, (hitBeginPoint - beginNode.Position) / beginNode.PressureFactor, (hitEndPoint - beginNode.Position) / beginNode.PressureFactor);
            }
            if (empty.EndFIndex != StrokeFIndices.AfterLast)
            {
                empty.EndFIndex = 1.0 - ClipTest((beginNode.Position - endNode.Position) / endNode.PressureFactor, beginNode.PressureFactor / endNode.PressureFactor - 1f, (hitBeginPoint - endNode.Position) / endNode.PressureFactor, (hitEndPoint - endNode.Position) / endNode.PressureFactor);
            }
            if (IsInvalidCutTestResult(empty))
            {
                return(StrokeFIndices.Empty);
            }
            return(empty);
        }
Example #5
0
        internal override Quad GetConnectingQuad(StrokeNodeData beginNode, StrokeNodeData endNode)
        {
            if (beginNode.IsEmpty || endNode.IsEmpty || DoubleUtil.AreClose(beginNode.Position, endNode.Position))
            {
                return(Quad.Empty);
            }
            Vector vector = endNode.Position - beginNode.Position;

            if (!_nodeShapeToCircle.IsIdentity)
            {
                vector = _nodeShapeToCircle.Transform(vector);
            }
            double num           = _radius * (double)beginNode.PressureFactor;
            double num2          = _radius * (double)endNode.PressureFactor;
            double lengthSquared = vector.LengthSquared;
            double num3          = num2 - num;
            double num4          = DoubleUtil.IsZero(num3) ? 0.0 : (num3 * num3);

            if (DoubleUtil.LessThanOrClose(lengthSquared, num4))
            {
                return(Quad.Empty);
            }
            double num5 = Math.Sqrt(lengthSquared);

            vector /= num5;
            Vector vector2 = vector;
            double y       = vector2.Y;

            vector2.Y = 0.0 - vector2.X;
            vector2.X = y;
            double num6 = num4 / lengthSquared;
            Vector vector3;
            Vector vector4;

            if (DoubleUtil.IsZero(num6))
            {
                vector3 = vector2;
                vector4 = -vector2;
            }
            else
            {
                vector2 *= Math.Sqrt(1.0 - num6);
                vector  *= Math.Sqrt(num6);
                if (beginNode.PressureFactor < endNode.PressureFactor)
                {
                    vector = -vector;
                }
                vector3 = vector + vector2;
                vector4 = vector - vector2;
            }
            if (!_circleToNodeShape.IsIdentity)
            {
                vector3 = _circleToNodeShape.Transform(vector3);
                vector4 = _circleToNodeShape.Transform(vector4);
            }
            return(new Quad(beginNode.Position + vector3 * num, endNode.Position + vector3 * num2, endNode.Position + vector4 * num2, beginNode.Position + vector4 * num));
        }
Example #6
0
 internal StrokeNode(StrokeNodeOperations operations, int index, StrokeNodeData nodeData, StrokeNodeData lastNodeData, bool isLastNode)
 {
     _operations     = operations;
     _index          = index;
     _thisNode       = nodeData;
     _lastNode       = lastNodeData;
     _isQuadCached   = lastNodeData.IsEmpty;
     _connectingQuad = Quad.Empty;
     _isLastNode     = isLastNode;
 }
Example #7
0
        internal override StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint)
        {
            Vector vector  = beginNode.IsEmpty ? new Vector(0.0, 0.0) : (beginNode.Position - endNode.Position);
            Vector vector2 = hitBeginPoint - endNode.Position;
            Vector vector3 = hitEndPoint - endNode.Position;

            if (!_nodeShapeToCircle.IsIdentity)
            {
                vector  = _nodeShapeToCircle.Transform(vector);
                vector2 = _nodeShapeToCircle.Transform(vector2);
                vector3 = _nodeShapeToCircle.Transform(vector3);
            }
            StrokeFIndices empty = StrokeFIndices.Empty;
            double         num   = 0.0;
            double         num2  = _radius * (double)endNode.PressureFactor;

            if (StrokeNodeOperations.GetNearest(vector2, vector3).LengthSquared <= num2 * num2)
            {
                empty.EndFIndex   = StrokeFIndices.AfterLast;
                empty.BeginFIndex = (beginNode.IsEmpty ? StrokeFIndices.BeforeFirst : 1.0);
            }
            if (!beginNode.IsEmpty)
            {
                num = _radius * (double)beginNode.PressureFactor;
                if (StrokeNodeOperations.GetNearest(vector2 - vector, vector3 - vector).LengthSquared <= num * num)
                {
                    empty.BeginFIndex = StrokeFIndices.BeforeFirst;
                    if (!DoubleUtil.AreClose(empty.EndFIndex, StrokeFIndices.AfterLast))
                    {
                        empty.EndFIndex = 0.0;
                    }
                }
            }
            if (empty.IsFull || quad.IsEmpty || (empty.IsEmpty && !StrokeNodeOperations.HitTestQuadSegment(quad, hitBeginPoint, hitEndPoint)))
            {
                return(empty);
            }
            if (!DoubleUtil.AreClose(empty.BeginFIndex, StrokeFIndices.BeforeFirst))
            {
                empty.BeginFIndex = ClipTest(-vector, num, num2, vector2 - vector, vector3 - vector);
            }
            if (!DoubleUtil.AreClose(empty.EndFIndex, StrokeFIndices.AfterLast))
            {
                empty.EndFIndex = 1.0 - ClipTest(vector, num2, num, vector2, vector3);
            }
            if (IsInvalidCutTestResult(empty))
            {
                return(StrokeFIndices.Empty);
            }
            return(empty);
        }
        private double CalculateClipLocation(ContourSegment hitSegment, StrokeNodeData beginNode, Vector spineVector, double pressureDelta)
        {
            double num = StrokeFIndices.BeforeFirst;

            if (hitSegment.IsArc || WhereIsVectorAboutVector(beginNode.Position - hitSegment.Begin, hitSegment.Vector) == HitResult.Left)
            {
                num = (hitSegment.IsArc ? ClipTestArc(spineVector, pressureDelta, (hitSegment.Begin + hitSegment.Radius - beginNode.Position) / beginNode.PressureFactor, hitSegment.Radius / beginNode.PressureFactor) : ClipTest(spineVector, pressureDelta, (hitSegment.Begin - beginNode.Position) / beginNode.PressureFactor, (hitSegment.End - beginNode.Position) / beginNode.PressureFactor));
                if (num == StrokeFIndices.AfterLast)
                {
                    num = StrokeFIndices.BeforeFirst;
                }
            }
            return(num);
        }
Example #9
0
        internal override bool HitTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint)
        {
            StrokeNodeData strokeNodeData;
            StrokeNodeData strokeNodeData2;

            if (beginNode.IsEmpty || (quad.IsEmpty && endNode.PressureFactor > beginNode.PressureFactor))
            {
                strokeNodeData  = endNode;
                strokeNodeData2 = StrokeNodeData.Empty;
            }
            else
            {
                strokeNodeData  = beginNode;
                strokeNodeData2 = endNode;
            }
            Vector vector  = hitBeginPoint - strokeNodeData.Position;
            Vector vector2 = hitEndPoint - strokeNodeData.Position;

            if (!_nodeShapeToCircle.IsIdentity)
            {
                vector  = _nodeShapeToCircle.Transform(vector);
                vector2 = _nodeShapeToCircle.Transform(vector2);
            }
            bool   result = false;
            double num    = _radius * (double)strokeNodeData.PressureFactor;

            if (StrokeNodeOperations.GetNearest(vector, vector2).LengthSquared <= num * num)
            {
                result = true;
            }
            else if (!quad.IsEmpty)
            {
                Vector vector3 = strokeNodeData2.Position - strokeNodeData.Position;
                if (!_nodeShapeToCircle.IsIdentity)
                {
                    vector3 = _nodeShapeToCircle.Transform(vector3);
                }
                double num2 = _radius * (double)strokeNodeData2.PressureFactor;
                if (StrokeNodeOperations.GetNearest(vector - vector3, vector2 - vector3).LengthSquared <= num2 * num2 || StrokeNodeOperations.HitTestQuadSegment(quad, hitBeginPoint, hitEndPoint))
                {
                    result = true;
                }
            }
            return(result);
        }
Example #10
0
        internal override IEnumerable <ContourSegment> GetContourSegments(StrokeNodeData node, Quad quad)
        {
            if (quad.IsEmpty)
            {
                Point position = node.Position;
                position.X += _radius;
                yield return(new ContourSegment(position, position, node.Position));
            }
            else if (_nodeShapeToCircle.IsIdentity)
            {
                yield return(new ContourSegment(quad.A, quad.B));

                yield return(new ContourSegment(quad.B, quad.C, node.Position));

                yield return(new ContourSegment(quad.C, quad.D));

                yield return(new ContourSegment(quad.D, quad.A));
            }
        }
        internal virtual IEnumerable <ContourSegment> GetContourSegments(StrokeNodeData node, Quad quad)
        {
            if (quad.IsEmpty)
            {
                Point begin = node.Position + _vertices[_vertices.Length - 1] * node.PressureFactor;
                for (int k = 0; k < _vertices.Length; k++)
                {
                    Point nextVertex2 = node.Position + _vertices[k] * node.PressureFactor;
                    yield return(new ContourSegment(begin, nextVertex2));

                    begin = nextVertex2;
                }
                yield break;
            }
            yield return(new ContourSegment(quad.A, quad.B));

            int j = 0;

            for (int count = _vertices.Length; j < count; j++)
            {
                Point point = node.Position + _vertices[j] * node.PressureFactor;
                if (!(point == quad.B))
                {
                    continue;
                }
                for (int i = 0; i < count; i++)
                {
                    if (!(point != quad.C))
                    {
                        break;
                    }
                    j = (j + 1) % count;
                    Point nextVertex = node.Position + _vertices[j] * node.PressureFactor;
                    yield return(new ContourSegment(point, nextVertex));

                    point = nextVertex;
                }
                break;
            }
            yield return(new ContourSegment(quad.C, quad.D));

            yield return(new ContourSegment(quad.D, quad.A));
        }
        internal void GetNodeContourPoints(StrokeNodeData node, List <Point> pointBuffer)
        {
            double num = node.PressureFactor;

            if (DoubleUtil.AreClose(num, 1.0))
            {
                for (int i = 0; i < _vertices.Length; i++)
                {
                    pointBuffer.Add(node.Position + _vertices[i]);
                }
            }
            else
            {
                for (int j = 0; j < _vertices.Length; j++)
                {
                    pointBuffer.Add(node.Position + _vertices[j] * num);
                }
            }
        }
        internal Rect GetNodeBounds(StrokeNodeData node)
        {
            if (_shapeBounds.IsEmpty)
            {
                int i;
                for (i = 0; i + 1 < _vertices.Length; i += 2)
                {
                    _shapeBounds.Union(new Rect((Point)_vertices[i], (Point)_vertices[i + 1]));
                }
                if (i < _vertices.Length)
                {
                    _shapeBounds.Union((Point)_vertices[i]);
                }
            }
            Rect   result = _shapeBounds;
            double num    = node.PressureFactor;

            if (!DoubleUtil.AreClose(num, 1.0))
            {
                result = new Rect(_shapeBounds.X * num, _shapeBounds.Y * num, _shapeBounds.Width * num, _shapeBounds.Height * num);
            }
            result.Location += (Vector)node.Position;
            return(result);
        }
        internal virtual bool HitTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, Point hitBeginPoint, Point hitEndPoint)
        {
            if (quad.IsEmpty)
            {
                Point  position;
                double num;
                if (beginNode.IsEmpty || endNode.PressureFactor > beginNode.PressureFactor)
                {
                    position = endNode.Position;
                    num      = endNode.PressureFactor;
                }
                else
                {
                    position = beginNode.Position;
                    num      = beginNode.PressureFactor;
                }
                Vector hitBegin = hitBeginPoint - position;
                Vector hitEnd   = hitEndPoint - position;
                if (num != 1.0)
                {
                    hitBegin /= num;
                    hitEnd   /= num;
                }
                return(HitTestPolygonSegment(_vertices, hitBegin, hitEnd));
            }
            Vector    hitBegin2 = hitBeginPoint - beginNode.Position;
            Vector    hitEnd2   = hitEndPoint - beginNode.Position;
            HitResult hitResult = WhereIsSegmentAboutSegment(hitBegin2, hitEnd2, quad.C - beginNode.Position, quad.D - beginNode.Position);

            if (HitResult.Left == hitResult)
            {
                return(false);
            }
            HitResult hitResult2    = hitResult;
            HitResult prevHitResult = hitResult;
            double    num2          = beginNode.PressureFactor;
            int       num3          = 0;
            int       num4          = _vertices.Length;
            Vector    vector        = default(Vector);

            for (num3 = 0; num3 < num4; num3++)
            {
                vector = _vertices[num3] * num2;
                if (beginNode.Position + vector == quad.D)
                {
                    break;
                }
            }
            for (int i = 0; i < 2; i++)
            {
                Point point  = (i == 0) ? beginNode.Position : endNode.Position;
                Point point2 = (i == 0) ? quad.A : quad.C;
                num4 = _vertices.Length;
                while (point + vector != point2 && num4 != 0)
                {
                    num3 = (num3 + 1) % _vertices.Length;
                    Vector vector2 = (num2 == 1.0) ? _vertices[num3] : (_vertices[num3] * num2);
                    hitResult = WhereIsSegmentAboutSegment(hitBegin2, hitEnd2, vector, vector2);
                    if (hitResult == HitResult.Hit)
                    {
                        return(true);
                    }
                    if (IsOutside(hitResult, prevHitResult))
                    {
                        return(false);
                    }
                    prevHitResult = hitResult;
                    vector        = vector2;
                    num4--;
                }
                if (i == 0)
                {
                    num2 = endNode.PressureFactor;
                    Vector vector3 = endNode.Position - beginNode.Position;
                    vector    -= vector3;
                    hitBegin2 -= vector3;
                    hitEnd2   -= vector3;
                    num4       = _vertices.Length;
                    while (endNode.Position + _vertices[num3] * num2 != quad.B && num4 != 0)
                    {
                        num3 = (num3 + 1) % _vertices.Length;
                        num4--;
                    }
                    num3--;
                }
            }
            return(!IsOutside(hitResult2, hitResult));
        }
Example #15
0
        internal override StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour)
        {
            Vector vector = beginNode.IsEmpty ? new Vector(0.0, 0.0) : (beginNode.Position - endNode.Position);

            if (!_nodeShapeToCircle.IsIdentity)
            {
                vector = _nodeShapeToCircle.Transform(vector);
            }
            double num  = 0.0;
            double num2 = 0.0;
            double num3 = _radius * (double)endNode.PressureFactor;
            double num4 = num3 * num3;

            if (!beginNode.IsEmpty)
            {
                num  = _radius * (double)beginNode.PressureFactor;
                num2 = num * num;
            }
            bool           flag   = true;
            StrokeFIndices result = StrokeFIndices.Empty;

            foreach (ContourSegment item in hitContour)
            {
                if (!item.IsArc)
                {
                    Vector vector2 = item.Begin - endNode.Position;
                    Vector vector3 = vector2 + item.Vector;
                    if (!_nodeShapeToCircle.IsIdentity)
                    {
                        vector2 = _nodeShapeToCircle.Transform(vector2);
                        vector3 = _nodeShapeToCircle.Transform(vector3);
                    }
                    bool flag2 = false;
                    if (StrokeNodeOperations.GetNearest(vector2, vector3).LengthSquared < num4)
                    {
                        flag2 = true;
                        if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))
                        {
                            result.EndFIndex = StrokeFIndices.AfterLast;
                            if (beginNode.IsEmpty)
                            {
                                result.BeginFIndex = StrokeFIndices.BeforeFirst;
                                break;
                            }
                            if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst))
                            {
                                break;
                            }
                        }
                    }
                    if (!beginNode.IsEmpty && (!flag2 || !DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst)) && StrokeNodeOperations.GetNearest(vector2 - vector, vector3 - vector).LengthSquared < num2)
                    {
                        flag2 = true;
                        if (!DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst))
                        {
                            result.BeginFIndex = StrokeFIndices.BeforeFirst;
                            if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))
                            {
                                break;
                            }
                        }
                    }
                    if (beginNode.IsEmpty || (!flag2 && (quad.IsEmpty || !StrokeNodeOperations.HitTestQuadSegment(quad, item.Begin, item.End))))
                    {
                        if (flag && StrokeNodeOperations.WhereIsVectorAboutVector(endNode.Position - item.Begin, item.Vector) != HitResult.Right)
                        {
                            flag = false;
                        }
                    }
                    else
                    {
                        flag = false;
                        CalculateCutLocations(vector, vector2, vector3, num3, num, ref result);
                        if (result.IsFull)
                        {
                            break;
                        }
                    }
                }
            }
            if (!result.IsFull)
            {
                if (flag)
                {
                    result = StrokeFIndices.Full;
                }
                else if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst) && !DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast))
                {
                    result.EndFIndex = StrokeFIndices.AfterLast;
                }
                else if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast) && !DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst))
                {
                    result.BeginFIndex = StrokeFIndices.BeforeFirst;
                }
            }
            if (IsInvalidCutTestResult(result))
            {
                return(StrokeFIndices.Empty);
            }
            return(result);
        }
        private bool HitTestStrokeNodes(ContourSegment hitSegment, StrokeNodeData beginNode, StrokeNodeData endNode, ref StrokeFIndices result)
        {
            bool flag = false;

            for (int i = 0; i < 2; i++)
            {
                Point  position;
                double num;
                if (i == 0)
                {
                    if (flag && DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst))
                    {
                        continue;
                    }
                    position = beginNode.Position;
                    num      = beginNode.PressureFactor;
                }
                else
                {
                    if (flag && DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))
                    {
                        continue;
                    }
                    position = endNode.Position;
                    num      = endNode.PressureFactor;
                }
                Vector vector;
                Vector vector2;
                if (hitSegment.IsArc)
                {
                    vector  = hitSegment.Begin - position + hitSegment.Radius;
                    vector2 = hitSegment.Radius;
                }
                else
                {
                    vector  = hitSegment.Begin - position;
                    vector2 = vector + hitSegment.Vector;
                }
                if (num != 1.0)
                {
                    vector  /= num;
                    vector2 /= num;
                }
                if (!(hitSegment.IsArc ? HitTestPolygonCircle(_vertices, vector, vector2) : HitTestPolygonSegment(_vertices, vector, vector2)))
                {
                    continue;
                }
                flag = true;
                if (i == 0)
                {
                    result.BeginFIndex = StrokeFIndices.BeforeFirst;
                    if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))
                    {
                        break;
                    }
                    continue;
                }
                result.EndFIndex = StrokeFIndices.AfterLast;
                if (beginNode.IsEmpty)
                {
                    result.BeginFIndex = StrokeFIndices.BeforeFirst;
                    break;
                }
                if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst))
                {
                    break;
                }
            }
            return(flag);
        }
        private bool HitTestInkContour(IEnumerable <ContourSegment> hitContour, Quad quad, StrokeNodeData beginNode, StrokeNodeData endNode)
        {
            bool flag  = false;
            bool flag2 = true;

            foreach (ContourSegment item in hitContour)
            {
                Vector    vector;
                Vector    vector2;
                HitResult hitResult;
                if (item.IsArc)
                {
                    vector    = item.Begin + item.Radius - beginNode.Position;
                    vector2   = item.Radius;
                    hitResult = WhereIsCircleAboutSegment(vector, vector2, quad.C - beginNode.Position, quad.D - beginNode.Position);
                }
                else
                {
                    vector    = item.Begin - beginNode.Position;
                    vector2   = vector + item.Vector;
                    hitResult = WhereIsSegmentAboutSegment(vector, vector2, quad.C - beginNode.Position, quad.D - beginNode.Position);
                }
                if (HitResult.Left == hitResult)
                {
                    if (flag2)
                    {
                        flag2 = (item.IsArc ? (WhereIsVectorAboutArc(-vector, -item.Radius, item.Vector - item.Radius) != HitResult.Hit) : (WhereIsVectorAboutVector(-vector, item.Vector) == HitResult.Right));
                    }
                }
                else
                {
                    HitResult hitResult2    = hitResult;
                    HitResult prevHitResult = hitResult;
                    double    scalar        = beginNode.PressureFactor;
                    int       num           = 0;
                    int       num2          = _vertices.Length;
                    Vector    vector3       = default(Vector);
                    for (num = 0; num < num2; num++)
                    {
                        vector3 = _vertices[num] * scalar;
                        if (DoubleUtil.AreClose(beginNode.Position + vector3, quad.D))
                        {
                            break;
                        }
                    }
                    int i;
                    for (i = 0; i < 2; i++)
                    {
                        num2 = _vertices.Length;
                        Point point  = (i == 0) ? beginNode.Position : endNode.Position;
                        Point point2 = (i == 0) ? quad.A : quad.C;
                        while (point + vector3 != point2 && num2 != 0)
                        {
                            num = (num + 1) % _vertices.Length;
                            Vector vector4 = _vertices[num] * scalar;
                            hitResult = (item.IsArc ? WhereIsCircleAboutSegment(vector, vector2, vector3, vector4) : WhereIsSegmentAboutSegment(vector, vector2, vector3, vector4));
                            if (hitResult == HitResult.Hit)
                            {
                                return(true);
                            }
                            if (IsOutside(hitResult, prevHitResult))
                            {
                                i = 3;
                                break;
                            }
                            prevHitResult = hitResult;
                            vector3       = vector4;
                            num2--;
                        }
                        if (i == 0)
                        {
                            scalar = endNode.PressureFactor;
                            Vector vector5 = endNode.Position - beginNode.Position;
                            vector3 -= vector5;
                            vector  -= vector5;
                            if (!item.IsArc)
                            {
                                vector2 -= vector5;
                            }
                            num2 = _vertices.Length;
                            while (!DoubleUtil.AreClose(endNode.Position + _vertices[num] * scalar, quad.B) && num2 != 0)
                            {
                                num = (num + 1) % _vertices.Length;
                                num2--;
                            }
                            num--;
                        }
                    }
                    if (i == 2 && !IsOutside(hitResult2, hitResult))
                    {
                        flag = true;
                        break;
                    }
                    if (flag2)
                    {
                        flag2 = (item.IsArc ? (WhereIsVectorAboutArc(-vector, -item.Radius, item.Vector - item.Radius) != HitResult.Hit) : (WhereIsVectorAboutVector(-vector, item.Vector) == HitResult.Right));
                    }
                }
            }
            return(flag | flag2);
        }
        private bool HitTestPolygonContourSegments(IEnumerable <ContourSegment> hitContour, StrokeNodeData beginNode, StrokeNodeData endNode)
        {
            bool   flag  = false;
            bool   flag2 = true;
            Point  position;
            double num;

            if (beginNode.IsEmpty || endNode.PressureFactor > beginNode.PressureFactor)
            {
                position = endNode.Position;
                num      = endNode.PressureFactor;
            }
            else
            {
                position = beginNode.Position;
                num      = beginNode.PressureFactor;
            }
            foreach (ContourSegment item in hitContour)
            {
                if (item.IsArc)
                {
                    Vector center = item.Begin + item.Radius - position;
                    Vector radius = item.Radius;
                    if (!DoubleUtil.AreClose(num, 1.0))
                    {
                        center /= num;
                        radius /= num;
                    }
                    if (HitTestPolygonCircle(_vertices, center, radius))
                    {
                        flag = true;
                        break;
                    }
                    if (flag2 && WhereIsVectorAboutArc(position - item.Begin - item.Radius, -item.Radius, item.Vector - item.Radius) == HitResult.Hit)
                    {
                        flag2 = false;
                    }
                }
                else
                {
                    Vector vector = item.Begin - position;
                    Vector hitEnd = vector + item.Vector;
                    if (!DoubleUtil.AreClose(num, 1.0))
                    {
                        vector /= num;
                        hitEnd /= num;
                    }
                    if (HitTestPolygonSegment(_vertices, vector, hitEnd))
                    {
                        flag = true;
                        break;
                    }
                    if (flag2 && WhereIsVectorAboutVector(position - item.Begin, item.Vector) != HitResult.Right)
                    {
                        flag2 = false;
                    }
                }
            }
            return(flag2 | flag);
        }
        internal virtual StrokeFIndices CutTest(StrokeNodeData beginNode, StrokeNodeData endNode, Quad quad, IEnumerable <ContourSegment> hitContour)
        {
            if (beginNode.IsEmpty)
            {
                if (HitTest(beginNode, endNode, quad, hitContour))
                {
                    return(StrokeFIndices.Full);
                }
                return(StrokeFIndices.Empty);
            }
            StrokeFIndices result         = StrokeFIndices.Empty;
            bool           flag           = true;
            Vector         spineVector    = (endNode.Position - beginNode.Position) / beginNode.PressureFactor;
            Vector         spineVector2   = (beginNode.Position - endNode.Position) / endNode.PressureFactor;
            double         pressureDelta  = endNode.PressureFactor / beginNode.PressureFactor - 1f;
            double         pressureDelta2 = beginNode.PressureFactor / endNode.PressureFactor - 1f;

            foreach (ContourSegment item in hitContour)
            {
                bool flag2 = HitTestStrokeNodes(item, beginNode, endNode, ref result);
                if (result.IsFull)
                {
                    return(result);
                }
                if (!flag2)
                {
                    if (!quad.IsEmpty)
                    {
                        flag2 = (item.IsArc ? HitTestQuadCircle(quad, item.Begin + item.Radius, item.Radius) : HitTestQuadSegment(quad, item.Begin, item.End));
                    }
                    if (!flag2)
                    {
                        if (flag)
                        {
                            flag = (item.IsArc ? (WhereIsVectorAboutArc(endNode.Position - item.Begin - item.Radius, -item.Radius, item.Vector - item.Radius) != HitResult.Hit) : (WhereIsVectorAboutVector(endNode.Position - item.Begin, item.Vector) == HitResult.Right));
                        }
                        continue;
                    }
                }
                flag = false;
                if (!DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.BeforeFirst))
                {
                    double num = CalculateClipLocation(item, beginNode, spineVector, pressureDelta);
                    if (num != StrokeFIndices.BeforeFirst && result.BeginFIndex > num)
                    {
                        result.BeginFIndex = num;
                    }
                }
                if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.AfterLast))
                {
                    double num2 = CalculateClipLocation(item, endNode, spineVector2, pressureDelta2);
                    if (num2 != StrokeFIndices.BeforeFirst)
                    {
                        num2 = 1.0 - num2;
                        if (result.EndFIndex < num2)
                        {
                            result.EndFIndex = num2;
                        }
                    }
                }
            }
            if (DoubleUtil.AreClose(result.BeginFIndex, StrokeFIndices.AfterLast))
            {
                if (!DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst))
                {
                    result.BeginFIndex = StrokeFIndices.BeforeFirst;
                }
            }
            else if (DoubleUtil.AreClose(result.EndFIndex, StrokeFIndices.BeforeFirst))
            {
                result.EndFIndex = StrokeFIndices.AfterLast;
            }
            if (IsInvalidCutTestResult(result))
            {
                return(StrokeFIndices.Empty);
            }
            if (!result.IsEmpty || !flag)
            {
                return(result);
            }
            return(StrokeFIndices.Full);
        }
        internal virtual IEnumerable <ContourSegment> GetNonBezierContourSegments(StrokeNodeData beginNode, StrokeNodeData endNode)
        {
            Quad quad = beginNode.IsEmpty ? Quad.Empty : GetConnectingQuad(beginNode, endNode);

            return(GetContourSegments(endNode, quad));
        }
        internal virtual Quad GetConnectingQuad(StrokeNodeData beginNode, StrokeNodeData endNode)
        {
            if (beginNode.IsEmpty || endNode.IsEmpty || DoubleUtil.AreClose(beginNode.Position, endNode.Position))
            {
                return(Quad.Empty);
            }
            Quad   empty  = Quad.Empty;
            bool   flag   = false;
            bool   flag2  = false;
            Vector vector = endNode.Position - beginNode.Position;
            double num    = endNode.PressureFactor - beginNode.PressureFactor;
            int    num2   = _vertices.Length;
            int    num3   = 0;
            int    num4   = num2 - 1;

            while (num3 < num2)
            {
                Vector vector2 = vector + _vertices[num3] * num;
                if (num != 0.0 && vector2.X == 0.0 && vector2.Y == 0.0)
                {
                    return(Quad.Empty);
                }
                HitResult hitResult = WhereIsVectorAboutVector(vector2, _vertices[(num3 + 1) % num2] - _vertices[num3]);
                if (hitResult == HitResult.Left)
                {
                    if (!flag)
                    {
                        HitResult hitResult2 = WhereIsVectorAboutVector(_vertices[num3] - _vertices[num4], vector2);
                        if (HitResult.Right != hitResult2)
                        {
                            flag    = true;
                            empty.A = beginNode.Position + _vertices[num3] * beginNode.PressureFactor;
                            empty.B = endNode.Position + _vertices[num3] * endNode.PressureFactor;
                            if (flag2)
                            {
                                break;
                            }
                        }
                    }
                }
                else if (!flag2)
                {
                    HitResult hitResult3 = WhereIsVectorAboutVector(_vertices[num3] - _vertices[num4], vector2);
                    if (HitResult.Right == hitResult3)
                    {
                        flag2   = true;
                        empty.C = endNode.Position + _vertices[num3] * endNode.PressureFactor;
                        empty.D = beginNode.Position + _vertices[num3] * beginNode.PressureFactor;
                        if (flag)
                        {
                            break;
                        }
                    }
                }
                num3++;
                num4 = (num4 + 1) % num2;
            }
            if (!flag || !flag2 || (num != 0.0 && Vector.Determinant(empty.B - empty.A, empty.D - empty.A) == 0.0))
            {
                return(Quad.Empty);
            }
            return(empty);
        }