| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 | using Drawie.Backend.Core.Bridge;using Drawie.Backend.Core.Vector;using Drawie.Numerics;using Drawie.Skia;using DrawiEngine;using PixiEditor.Views.Overlays.PathOverlay;namespace PixiEditor.Tests;public class EditableVectorPathTests : PixiEditorTest{    [Fact]    public void TestThatRectVectorShapeReturnsCorrectSubShapes()    {        VectorPath path = new VectorPath();        path.AddRect(new RectD(0, 0, 10, 10));        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Single(editablePath.SubShapes);        Assert.True(editablePath.SubShapes[0].IsClosed);        Assert.Equal(4, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(10, 0), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(10, 10), editablePath.SubShapes[0].Points[2].Position);        Assert.Equal(new VecF(0, 10), editablePath.SubShapes[0].Points[3].Position);    }        [Fact]    public void TestThatOvalVectorShapeReturnsCorrectSubShapes()    {        VectorPath path = new VectorPath();        path.AddOval(RectD.FromCenterAndSize(new VecD(5, 5), new VecD(10, 10)));        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Single(editablePath.SubShapes);        Assert.True(editablePath.SubShapes[0].IsClosed);        Assert.Equal(4, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(10, 5), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(5, 10), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(0, 5), editablePath.SubShapes[0].Points[2].Position);        Assert.Equal(new VecF(5, 0), editablePath.SubShapes[0].Points[3].Position);    }        [Fact]    public void TestThatLineVectorShapeReturnsCorrectSubShapes()    {        VectorPath path = new VectorPath();        path.LineTo(new VecF(2, 2));        path.Close();        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Single(editablePath.SubShapes);        Assert.True(editablePath.SubShapes[0].IsClosed);        Assert.Equal(2, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[1].Position);    }        [Fact]    public void TestThatNotClosedPolyReturnsCorrectSubShape()    {        VectorPath path = new VectorPath();                path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Single(editablePath.SubShapes);        Assert.False(editablePath.SubShapes[0].IsClosed);        Assert.Equal(3, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(4, 4), editablePath.SubShapes[0].Points[2].Position);    }        [Fact]    public void TestThatMultipleRectsReturnCorrectSubShapes()    {        VectorPath path = new VectorPath();        path.AddRect(new RectD(0, 0, 10, 10));        path.AddRect(new RectD(10, 10, 20, 20));        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Equal(2, editablePath.SubShapes.Count);                Assert.True(editablePath.SubShapes[0].IsClosed);        Assert.Equal(4, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(10, 0), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(10, 10), editablePath.SubShapes[0].Points[2].Position);        Assert.Equal(new VecF(0, 10), editablePath.SubShapes[0].Points[3].Position);                Assert.True(editablePath.SubShapes[1].IsClosed);        Assert.Equal(4, editablePath.SubShapes[1].Points.Count);                Assert.Equal(new VecF(10, 10), editablePath.SubShapes[1].Points[0].Position);        Assert.Equal(new VecF(30, 10), editablePath.SubShapes[1].Points[1].Position);        Assert.Equal(new VecF(30, 30), editablePath.SubShapes[1].Points[2].Position);        Assert.Equal(new VecF(10, 30), editablePath.SubShapes[1].Points[3].Position);    }    [Fact]    public void TestThatTwoPolysWithSecondUnclosedReturnsCorrectShapeData()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();                path.MoveTo(new VecF(10, 10));        path.LineTo(new VecF(12, 12));        path.LineTo(new VecF(14, 14));        EditableVectorPath editablePath = new EditableVectorPath(path);        Assert.Equal(2, editablePath.SubShapes.Count);                Assert.True(editablePath.SubShapes[0].IsClosed);        Assert.Equal(3, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(4, 4), editablePath.SubShapes[0].Points[2].Position);                Assert.False(editablePath.SubShapes[1].IsClosed);        Assert.Equal(3, editablePath.SubShapes[1].Points.Count);                Assert.Equal(new VecF(10, 10), editablePath.SubShapes[1].Points[0].Position);        Assert.Equal(new VecF(12, 12), editablePath.SubShapes[1].Points[1].Position);        Assert.Equal(new VecF(14, 14), editablePath.SubShapes[1].Points[2].Position);    }    [Fact]    public void TestThatStartAndEndIndexesForMultipleShapesAreCorrect()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();                path.MoveTo(new VecF(10, 10));        path.LineTo(new VecF(12, 12));        path.Close();                int expectedFirstShapeStartIndex = 0;        int expectedFirstShapeEndIndex = 2;                int expectedSecondShapeStartIndex = 3;        int expectedSecondShapeEndIndex = 5;                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(2, editablePath.SubShapes.Count);    }        [Fact]    public void TestThatGetNextPointInTriangleShapeReturnsCorrectPoint()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();        EditableVectorPath editablePath = new EditableVectorPath(path);        ShapePoint nextPoint = editablePath.SubShapes[0].GetNextPoint(0);                Assert.Equal(new VecF(2, 2), nextPoint.Position);        Assert.Equal(1, nextPoint.Index);                nextPoint = editablePath.SubShapes[0].GetNextPoint(1);                Assert.Equal(new VecF(4, 4), nextPoint.Position);        Assert.Equal(2, nextPoint.Index);                nextPoint = editablePath.SubShapes[0].GetNextPoint(2);                Assert.Equal(new VecF(0, 0), nextPoint.Position);        Assert.Equal(0, nextPoint.Index);    }        [Fact]    public void TestThatGetPreviousPointInTriangleShapeReturnsCorrectPoint()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();        EditableVectorPath editablePath = new EditableVectorPath(path);        ShapePoint previousPoint = editablePath.SubShapes[0].GetPreviousPoint(0);                Assert.Equal(new VecF(4, 4), previousPoint.Position);        Assert.Equal(2, previousPoint.Index);                previousPoint = editablePath.SubShapes[0].GetPreviousPoint(1);                Assert.Equal(new VecF(0, 0), previousPoint.Position);        Assert.Equal(0, previousPoint.Index);                previousPoint = editablePath.SubShapes[0].GetPreviousPoint(2);                Assert.Equal(new VecF(2, 2), previousPoint.Position);        Assert.Equal(1, previousPoint.Index);    }    [Fact]    public void TestThatVerbsInTriangleAreCorrect()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(3, editablePath.SubShapes[0].Points.Count);                Assert.Equal(PathVerb.Line, editablePath.SubShapes[0].Points[0].Verb.VerbType);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Verb.From);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[0].Verb.To);                Assert.Equal(PathVerb.Line, editablePath.SubShapes[0].Points[1].Verb.VerbType);                Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[1].Verb.From);        Assert.Equal(new VecF(4, 4), editablePath.SubShapes[0].Points[1].Verb.To);                Assert.Equal(PathVerb.Line, editablePath.SubShapes[0].Points[2].Verb.VerbType);                Assert.Equal(new VecF(4, 4), editablePath.SubShapes[0].Points[2].Verb.From);        Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[2].Verb.To);    }    [Fact]    public void TestThatVerbsInOvalAreCorrect()    {        const float conic = 0.70710769f;        const float rangeLower = conic - 0.001f;        const float rangeUpper = conic + 0.001f;        VectorPath path = new VectorPath();        path.AddOval(RectD.FromCenterAndSize(new VecD(5, 5), new VecD(10, 10)));                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(4, editablePath.SubShapes[0].Points.Count);                Assert.Equal(PathVerb.Conic, editablePath.SubShapes[0].Points[0].Verb.VerbType);                Assert.Equal(new VecF(10, 5), editablePath.SubShapes[0].Points[0].Verb.From);        Assert.Equal(new VecF(5, 10), editablePath.SubShapes[0].Points[0].Verb.To);        Assert.InRange(editablePath.SubShapes[0].Points[0].Verb.ConicWeight, rangeLower, rangeUpper);                Assert.Equal(PathVerb.Conic, editablePath.SubShapes[0].Points[1].Verb.VerbType);        Assert.Equal(new VecF(5, 10), editablePath.SubShapes[0].Points[1].Verb.From);        Assert.Equal(new VecF(0, 5), editablePath.SubShapes[0].Points[1].Verb.To);        Assert.InRange(editablePath.SubShapes[0].Points[1].Verb.ConicWeight, rangeLower, rangeUpper);                Assert.Equal(PathVerb.Conic, editablePath.SubShapes[0].Points[2].Verb.VerbType);        Assert.Equal(new VecF(0, 5), editablePath.SubShapes[0].Points[2].Verb.From);        Assert.Equal(new VecF(5, 0), editablePath.SubShapes[0].Points[2].Verb.To);        Assert.InRange(editablePath.SubShapes[0].Points[2].Verb.ConicWeight, rangeLower, rangeUpper);                Assert.Equal(PathVerb.Conic, editablePath.SubShapes[0].Points[3].Verb.VerbType);        Assert.Equal(new VecF(5, 0), editablePath.SubShapes[0].Points[3].Verb.From);        Assert.Equal(new VecF(10, 5), editablePath.SubShapes[0].Points[3].Verb.To);        Assert.InRange(editablePath.SubShapes[0].Points[3].Verb.ConicWeight, rangeLower, rangeUpper);    }    [Fact]    public void TestThatOverlappingPolyPointsReturnCorrectSubShapePoints()    {        VectorPath path = new VectorPath();                /*          *     |\         *     |_\         *     |         */        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(0, 2));        path.LineTo(new VecF(0, 4));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(0, 2));        path.Close();                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(5, editablePath.SubShapes[0].Points.Count);                Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Verb.From);        Assert.Equal(new VecF(0, 2), editablePath.SubShapes[0].Points[0].Verb.To);                Assert.Equal(new VecF(0, 2), editablePath.SubShapes[0].Points[1].Verb.From);        Assert.Equal(new VecF(0, 4), editablePath.SubShapes[0].Points[1].Verb.To);                Assert.Equal(new VecF(0, 4), editablePath.SubShapes[0].Points[2].Verb.From);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[2].Verb.To);                Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[3].Verb.From);        Assert.Equal(new VecF(0, 2), editablePath.SubShapes[0].Points[3].Verb.To);                Assert.Equal(new VecF(0, 2), editablePath.SubShapes[0].Points[4].Verb.From);        Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[4].Verb.To);    }    [Fact]    public void TestThatMultiSubShapesWithUnclosedReturnsCorrectPoints()    {        VectorPath path = new VectorPath();                path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(0, 4));                path.AddOval(RectD.FromCenterAndSize(new VecD(5, 5), new VecD(10, 10)));                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(2, editablePath.SubShapes.Count);                Assert.Equal(3, editablePath.SubShapes[0].Points.Count);        Assert.Equal(new VecF(0, 0), editablePath.SubShapes[0].Points[0].Position);        Assert.Equal(new VecF(2, 2), editablePath.SubShapes[0].Points[1].Position);        Assert.Equal(new VecF(0, 4), editablePath.SubShapes[0].Points[2].Position);                Assert.False(editablePath.SubShapes[0].IsClosed);                Assert.Equal(4, editablePath.SubShapes[1].Points.Count);        Assert.Equal(new VecF(10, 5), editablePath.SubShapes[1].Points[0].Position);        Assert.Equal(new VecF(5, 10), editablePath.SubShapes[1].Points[1].Position);        Assert.Equal(new VecF(0, 5), editablePath.SubShapes[1].Points[2].Position);        Assert.Equal(new VecF(5, 0), editablePath.SubShapes[1].Points[3].Position);                Assert.True(editablePath.SubShapes[1].IsClosed);    }        [Fact]    public void TestThatMoveToProducesEmptyVerb()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Single(editablePath.SubShapes);        Assert.Single(editablePath.SubShapes[0].Points);                Assert.Equal(null, editablePath.SubShapes[0].Points[0].Verb.VerbType);    }        [Fact]    public void TestThatMultipleMoveToProduceEmptyVerbs()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.MoveTo(new VecF(2, 2));                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(2, editablePath.SubShapes.Count);                Assert.Single(editablePath.SubShapes[0].Points);        Assert.Single(editablePath.SubShapes[1].Points);                Assert.Null(editablePath.SubShapes[0].Points[0].Verb.VerbType);        Assert.Null(editablePath.SubShapes[1].Points[0].Verb.VerbType);    }    [Fact]    public void TestThatEditingPointResultsInCorrectVectorPath()    {        VectorPath path = new VectorPath();        path.MoveTo(new VecF(0, 0));        path.LineTo(new VecF(2, 2));        path.LineTo(new VecF(4, 4));        path.Close();                EditableVectorPath editablePath = new EditableVectorPath(path);                editablePath.SubShapes[0].SetPointPosition(1, new VecF(3, 3), true);                VectorPath newPath = editablePath.ToVectorPath();                PathVerb[] sequence = [ PathVerb.Move, PathVerb.Line, PathVerb.Line, PathVerb.Line, PathVerb.Close, PathVerb.Done ];        VecF[] points = [ new VecF(0, 0), new VecF(3, 3), new VecF(4, 4), new VecF(0, 0) ];        int i = 0;        foreach (var data in newPath)        {            Assert.Equal(sequence[i], data.verb);            if(data.verb != PathVerb.Close && data.verb != PathVerb.Done)            {                Assert.Equal(points[i], Verb.GetPointFromVerb(data));            }            i++;        }    }    [Theory]    [InlineData(0, 0)]    [InlineData(1, 0)]    [InlineData(2, 0)]    [InlineData(3, 0)]    [InlineData(4, 1)]    [InlineData(5, 1)]    [InlineData(6, 1)]    [InlineData(7, 1)]    public void TestThatGetSubShapeByPointIndexReturnsCorrectSubShapeIndex(int index, int expected)    {        VectorPath path = new VectorPath();        path.AddOval(RectD.FromCenterAndSize(new VecD(5, 5), new VecD(10, 10)));        path.AddOval(RectD.FromCenterAndSize(new VecD(15, 15), new VecD(20, 20)));                EditableVectorPath editablePath = new EditableVectorPath(path);                Assert.Equal(expected, editablePath.SubShapes.ToList().IndexOf(editablePath.GetSubShapeContainingIndex(index)));    }}
 |