Пример #1
0
        public virtual void NextSubpath_Int_Int_Bool() 
		{
            GraphicsPath path = new GraphicsPath ();
			path.AddLine (new Point (100, 100), new Point (400, 100));
			path.AddLine (new Point (400, 200), new Point (10, 100));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddBezier( 10, 10, 50, 250, 100, 5, 200, 280);
			path.CloseFigure ();
			path.StartFigure ();
			path.SetMarkers ();
			path.AddRectangle (new Rectangle (10, 20, 300, 400));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddLine (new Point (400, 400), new Point (400, 10));

			GraphicsPathIterator iterator = new GraphicsPathIterator (path);

			int start;
			int end;
			bool isClosed;

			int count = iterator.NextSubpath (out start, out end, out isClosed);
			Assert.AreEqual (4, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (3, end);
			Assert.IsFalse (isClosed);

			count = iterator.NextSubpath (out start, out end, out isClosed);
			Assert.AreEqual (4, count);
			Assert.AreEqual (4, start);
			Assert.AreEqual (7, end);
			Assert.IsTrue (isClosed);

			count = iterator.NextSubpath (out start, out end, out isClosed);
			Assert.AreEqual (4, count);
			Assert.AreEqual (8, start);
			Assert.AreEqual (11, end);
			Assert.IsTrue (isClosed);

			count = iterator.NextSubpath (out start, out end, out isClosed);
			Assert.AreEqual (2, count);
			Assert.AreEqual (12, start);
			Assert.AreEqual (13, end);
			Assert.IsFalse (isClosed);

			count = iterator.NextSubpath (out start, out end, out isClosed);
			Assert.AreEqual (0, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (0, end);
			Assert.IsTrue (isClosed);
        }
Пример #2
0
        public Analyzer(double meanX, double meanY, GraphicsPath path)
        {
            Counters = new RunningCount[Enum.GetValues(typeof(AnalysisMetric)).Length];

            foreach(AnalysisMetric metric in Enum.GetValues(typeof(AnalysisMetric)))
                Counters[(int)metric] = new RunningCount(metric);

            MeanX = meanX;
            MeanY = meanY;

            path.Flatten();

            using(GraphicsPathIterator PathIterator = new GraphicsPathIterator(path))
            {
                using(GraphicsPath Subpath = new GraphicsPath())
                {
                    Paths = new List<PointF[]>();

                    bool Closed;

                    while(PathIterator.NextSubpath(Subpath, out Closed) > 0)
                    {
                        Paths.Add(Subpath.PathPoints);
                        Subpath.Reset();
                    }
                }
            }
        }
Пример #3
0
		public void NextSubpath_Null ()
		{
			using (GraphicsPath gp = new GraphicsPath ()) {
				gp.AddLines (pts_2f);
				using (GraphicsPathIterator gpi = new GraphicsPathIterator (gp)) {
					bool closed;
					Assert.AreEqual (0, gpi.NextSubpath (null, out closed));
					Assert.IsTrue (closed, "Closed");
				}
			}
		}
Пример #4
0
        public void PathIterator7(Graphics g)
        {
            // Create a graphics path.
            GraphicsPath myPath = new GraphicsPath();

            // Set up primitives to add to myPath.
            Point[] myPoints = {new Point(20, 20), new Point(120, 120),
                new Point(20, 120),new Point(20, 20) };
            Rectangle myRect = new Rectangle(120, 120, 100, 100);

            // Add 3 lines, a rectangle, an ellipse, and 2 markers.
            myPath.AddLines(myPoints);
            myPath.SetMarkers();
            myPath.AddRectangle(myRect);
            myPath.SetMarkers();
            myPath.AddEllipse(220, 220, 100, 100);

            // Get the total number of points for the path,

            // and the arrays of the points and types.
            int myPathPointCount = myPath.PointCount;
            PointF[] myPathPoints = myPath.PathPoints;
            byte[] myPathTypes = myPath.PathTypes;

            // Set up variables for listing all of the path's

            // points to the screen.
            int i;
            float j = 20;
            Font myFont = new Font("Arial", 8);
            SolidBrush myBrush = new SolidBrush(Color.Black);

            // List the values of all the path points and types to the screen.
            for(i=0; i<myPathPointCount; i++)
            {
                g.DrawString(myPathPoints[i].X.ToString()+
                                      ", " + myPathPoints[i].Y.ToString() + ", " +
                                      myPathTypes[i].ToString(),
                                      myFont,
                                      myBrush,
                                      20,
                                      j);
                j+=20;
            }

            // Create a GraphicsPathIterator for myPath.
            GraphicsPathIterator myPathIterator = new
                GraphicsPathIterator(myPath);

            // Rewind the iterator.
            myPathIterator.Rewind();

            // Create the GraphicsPath section.
            GraphicsPath myPathSection = new GraphicsPath();

            // Iterate to the 3rd subpath and list the number of points therein

            // to the screen.
            int subpathPoints;
            bool IsClosed2;

            // Iterate to the third subpath.
            subpathPoints = myPathIterator.NextSubpath(
                myPathSection, out IsClosed2);
            subpathPoints = myPathIterator.NextSubpath(
                myPathSection, out IsClosed2);
            subpathPoints = myPathIterator.NextSubpath(
                myPathSection, out IsClosed2);

            // Write the number of subpath points to the screen.
            g.DrawString("Subpath: 3"  +
                                  "   Num Points: " +
                                  subpathPoints.ToString(),
                                  myFont,
                                  myBrush,
                                  200,
                                  20);
        }
Пример #5
0
        public void PathIterator3(Graphics g)
        {
            // Create the GraphicsPath.
            GraphicsPath myPath = new GraphicsPath();

            Point[] myPoints = {new Point(20, 20), new Point(120, 120),
                new Point(20, 120),new Point(20, 20) };
            Rectangle myRect = new Rectangle(120, 120, 100, 100);

            // Add 3 lines, a rectangle, and an ellipse.
            myPath.AddLines(myPoints);
            myPath.AddRectangle(myRect);
            myPath.AddEllipse(220, 220, 100, 100);

            // List all of the path points to the screen.
            ListPathPoints(g, myPath, null, 20, 1);

            // Create a GraphicsPathIterator.
            GraphicsPathIterator myPathIterator = new
                GraphicsPathIterator(myPath);

            // Rewind the Iterator.
            myPathIterator.Rewind();

            // Iterate the subpaths and types, and list the results to

            // the screen.
            int i, j = 20;
            int mySubPaths, subPathStartIndex, subPathEndIndex;
            Boolean IsClosed;
            byte subPathPointType;
            int pointTypeStartIndex,  pointTypeEndIndex, numPointsFound;
            Font myFont = new Font("Arial", 8);
            SolidBrush myBrush = new SolidBrush(Color.Black);
            j = 20;
            for(i = 0;i < 3; i++)
            {
                mySubPaths = myPathIterator.NextSubpath(
                    out subPathStartIndex,
                    out subPathEndIndex,
                    out IsClosed);
                numPointsFound = myPathIterator.NextPathType(
                    out subPathPointType,
                    out pointTypeStartIndex,
                    out pointTypeEndIndex);
                g.DrawString(
                    "SubPath: " + i +
                    "  Points Found: " + numPointsFound.ToString() +
                    "  Type of Points: " + subPathPointType.ToString(),
                    myFont,
                    myBrush,
                    200,
                    j);
                j+=20;
            }

            // List the total number of path points to the screen.
            ListPathPoints(g, myPath, myPathIterator, 200, 2);
        }
Пример #6
0
        public void OutputPaths(string title, GraphicsPath myPath)
        {
            var iterator = new GraphicsPathIterator(myPath);
            int startIndex, endIndex;
            bool isClosed;
            int subPaths = iterator.SubpathCount;
            var pathData = myPath.PathData;

            Console.WriteLine("{0} - num paths {1}", title, subPaths);
            for (int sp = 0; sp < subPaths; sp++)
            {

                var numOfPoints = iterator.NextSubpath(out startIndex, out endIndex, out isClosed);
                Console.WriteLine("subPath {0} - from {1} to {2} closed {3}", sp + 1, startIndex, endIndex, isClosed);

                for (int pp = startIndex; pp <= endIndex; pp++)
                {
                    Console.WriteLine("         {0} - {1}", pathData.Points[pp], (PathPointType)pathData.Types[pp]);
                }

            }
        }
Пример #7
0
    protected override void DoPerformLayout(RenderContext context)
    {
      base.DoPerformLayout(context);

      // Setup brushes
      if (Fill != null || ((Stroke != null && StrokeThickness > 0)))
      {
        using (GraphicsPath path = CalculateTransformedPath(ParsePath(), _innerRect))
        {
          if (Fill != null && !_fillDisabled)
          {
            using (GraphicsPathIterator gpi = new GraphicsPathIterator(path))
            {
              PositionColoredTextured[][] subPathVerts = new PositionColoredTextured[gpi.SubpathCount][];
              using (GraphicsPath subPath = new GraphicsPath())
              {
                for (int i = 0; i < subPathVerts.Length; i++)
                {
                  bool isClosed;
                  gpi.NextSubpath(subPath, out isClosed);
                  PointF[] pathPoints = subPath.PathPoints;
                  TriangulateHelper.Triangulate(pathPoints, 1, out subPathVerts[i]);
                  if (subPathVerts[i] == null)
                    ServiceRegistration.Get<ILogger>().Warn("Failed to triangulate Path \"{0}\"!", Name);
                }
              }
              PositionColoredTextured[] verts;
              GraphicsPathHelper.Flatten(subPathVerts, out verts);
              if (verts != null)
              {
                Fill.SetupBrush(this, ref verts, context.ZOrder, true);
                PrimitiveBuffer.SetPrimitiveBuffer(ref _fillContext, ref verts, PrimitiveType.TriangleList);
              }
            }
          }
          else
            PrimitiveBuffer.DisposePrimitiveBuffer(ref _fillContext);

          if (Stroke != null && StrokeThickness > 0)
          {
            using (GraphicsPathIterator gpi = new GraphicsPathIterator(path))
            {
              PositionColoredTextured[][] subPathVerts = new PositionColoredTextured[gpi.SubpathCount][];
              using (GraphicsPath subPath = new GraphicsPath())
              {
                for (int i = 0; i < subPathVerts.Length; i++)
                {
                  bool isClosed;
                  gpi.NextSubpath(subPath, out isClosed);
                  PointF[] pathPoints = subPath.PathPoints;
                  TriangulateHelper.TriangulateStroke_TriangleList(pathPoints, (float) StrokeThickness, isClosed, 1, StrokeLineJoin,
                      out subPathVerts[i]);
                }
              }
              PositionColoredTextured[] verts;
              GraphicsPathHelper.Flatten(subPathVerts, out verts);
              if (verts != null)
              {
                Stroke.SetupBrush(this, ref verts, context.ZOrder, true);
                PrimitiveBuffer.SetPrimitiveBuffer(ref _strokeContext, ref verts, PrimitiveType.TriangleList);
              }
            }
          }
          else
            PrimitiveBuffer.DisposePrimitiveBuffer(ref _strokeContext);
        }
      }
    }
Пример #8
0
        static void WidenPath(GraphicsPath path, Pen pen, out List<PointF> widePoints, out List<byte> wideTypes)
        {
            widePoints = new List<PointF> ();
            wideTypes = new List<byte> ();

            var pathData = path.PathData;

            var iterator = new GraphicsPathIterator(path);
            var subPaths = iterator.SubpathCount;

            int startIndex = 0;
            int endIndex = 0;
            bool isClosed = false;

            var flattenedSubpath = new Paths();
            var offsetPaths = new Paths();

            var width = (pen.Width / 2) * scale;
            var miterLimit = pen.MiterLimit * scale;

            var joinType = JoinType.jtMiter;
            switch (pen.LineJoin)
            {
            case LineJoin.Round:
                joinType = JoinType.jtRound;
                break;
            case LineJoin.Bevel:
                joinType = JoinType.jtSquare;
                break;
            }

            for (int sp = 0; sp < subPaths; sp++)
            {

                var numOfPoints = iterator.NextSubpath(out startIndex, out endIndex, out isClosed);
                //Console.WriteLine("subPath {0} - from {1} to {2} closed {3}", sp+1, startIndex, endIndex, isClosed);

                var subPoints = pathData.Points.Skip(startIndex).Take(numOfPoints).ToArray();

                //for (int pp = startIndex; pp <= endIndex; pp++)
                //{
                //    Console.WriteLine("         {0} - {1}", pathData.Points[pp], (PathPointType)pathData.Types[pp]);
                //}

                // Load our Figure Subpath
                flattenedSubpath.Clear();
                flattenedSubpath.Add(Region.PointFArrayToIntArray(subPoints, scale));

                // Calculate the outter offset region
                var outerOffsets = Clipper.OffsetPaths(flattenedSubpath, width, joinType, EndType.etClosed, miterLimit);
                // Calculate the inner offset region
                var innerOffsets = Clipper.OffsetPaths(flattenedSubpath, -width, joinType, EndType.etClosed, miterLimit);

                // Add the offsets to our paths
                offsetPaths.AddRange(outerOffsets);

                // revers our innerOffsets so that they create a hole when filling
                Clipper.ReversePaths (innerOffsets);
                offsetPaths.AddRange(innerOffsets);

            }

            foreach (var offPath in offsetPaths)
            {
                if (offPath.Count < 1)
                    continue;

                var pointArray = Region.PathToPointFArray(offPath, scale);

                var type = (byte)PathPointType.Start;
                widePoints.Add (pointArray [0]);
                wideTypes.Add (type);

                type = (byte)PathPointType.Line;
                for (int i = 1; i < offPath.Count; i++)
                {
                    widePoints.Add (pointArray [i]);
                    wideTypes.Add (type);

                }

                if (widePoints.Count > 0)
                    wideTypes [wideTypes.Count-1] = (byte) (wideTypes [wideTypes.Count-1] | (byte) PathPointType.CloseSubpath);

            }
        }
Пример #9
0
		public void NextSubpath_NextMarker()
		{
			GraphicsPath path = new GraphicsPath();
			
			path.AddLine (10, 10, 50, 50); // figure #1
			path.AddLine (50, 50, 80, 80);
			path.AddLine (90, 90, 100, 100);
			path.SetMarkers (); // marker #1
			path.AddLine (150, 150, 180, 180);
			path.SetMarkers (); // marker #2
			path.StartFigure (); // figure #2
			path.SetMarkers (); // marker #3 is actually marker #2
			path.AddRectangle (new Rectangle (200, 200, 200, 200)); 
			path.SetMarkers (); // marker #4
			path.AddLine (150, 150, 180, 180); 
			path.StartFigure (); // figure #3
			path.AddBezier (400, 400, 500, 500, 600, 600, 700, 700);
			path.AddBezier (450, 450, 550, 550, 650, 650, 750, 750);

			GraphicsPathIterator iterator = new GraphicsPathIterator (path);

			int start;
			int end;
			bool isClosed;
			int count = iterator.NextMarker (out start,out end); // marker #1
			Assert.AreEqual (5, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (4, end);

			count = iterator.NextSubpath (out start,out end,out isClosed); // figure #1
			Assert.AreEqual (7, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (6, end);
			Assert.AreEqual (false, isClosed);

			count = iterator.NextMarker (out start,out end); // marker #2 (and #3)
			Assert.AreEqual (2, count);
			Assert.AreEqual (5, start);
			Assert.AreEqual (6, end);

			count = iterator.NextSubpath (out start,out end,out isClosed); // figure #2
			Assert.AreEqual (4, count);
			Assert.AreEqual (7, start);
			Assert.AreEqual (10, end);
			Assert.AreEqual (true, isClosed);

			count = iterator.NextSubpath (out start,out end,out isClosed); // figure #3
			Assert.AreEqual (2, count);
			Assert.AreEqual (11, start);
			Assert.AreEqual (12, end);
			Assert.AreEqual (false, isClosed);

			count = iterator.NextMarker (out start,out end); // marker #5 (end)
			Assert.AreEqual (4, count);
			Assert.AreEqual (7, start);
			Assert.AreEqual (10, end);

			count = iterator.NextMarker (out start,out end); // marker #5 (end)
			Assert.AreEqual (10, count);
			Assert.AreEqual (11, start);
			Assert.AreEqual (20, end);

			// we dont want to be bug compliant with .net
			/*
			count = iterator.NextMarker (out start,out end); // no more markers
			Assert.AreEqual (0, count);
			Assert.AreEqual (11, start);
			Assert.AreEqual (20, end);
			*/

			count = iterator.NextSubpath (out start,out end,out isClosed); // figure #4
			Assert.AreEqual (8, count);
			Assert.AreEqual (13, start);
			Assert.AreEqual (20, end);
			Assert.AreEqual (false, isClosed);

			// we dont want to be bug compliant with .net
			/*
			count = iterator.NextMarker (out start,out end); // no more markers
			Assert.AreEqual (0, count);
			Assert.AreEqual (13, start);
			Assert.AreEqual (20, end);
			*/

			count = iterator.NextSubpath (out start,out end,out isClosed); // no more figures
			Assert.AreEqual (0, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (0, end);
			Assert.AreEqual (true, isClosed);

			count = iterator.NextMarker (out start,out end); // no more markers
			Assert.AreEqual (0, count);
			Assert.AreEqual (0, start);
			Assert.AreEqual (0, end);			
		}
Пример #10
0
        public GraphicsPath RandomWarp(GraphicsPath path)
        {
            // Add line //
            int PsCount = 10;
            PointF[] curvePs = new PointF[PsCount * 2];
            for (int u = 0; u < PsCount; u++)
            {
                curvePs[u].X = u * (Width / PsCount);
                curvePs[u].Y = Height / 2;
            }
            for (int u = PsCount; u < (PsCount * 2); u++)
            {
                curvePs[u].X = (u - PsCount) * (Width / PsCount);
                curvePs[u].Y = Height / 2 + 2;
            }


            double eps = Height * 0.05;

            double amp = rnd.NextDouble() * (double)(Height / 3);
            double size = rnd.NextDouble() * (double)(Width / 4) + Width / 8;

            double offset = (double)(Height / 3);


            PointF[] pn = new PointF[path.PointCount];
            byte[] pt = new byte[path.PointCount];

            GraphicsPath np2 = new GraphicsPath();

            GraphicsPathIterator iter = new GraphicsPathIterator(path);
            for (int i = 0; i < iter.SubpathCount; i++)
            {
                GraphicsPath sp = new GraphicsPath();
                bool closed;
                iter.NextSubpath(sp, out closed);

                Matrix m = new Matrix();
                m.RotateAt(Convert.ToSingle(rnd.NextDouble() * 30 - 15), sp.PathPoints[0]);

                m.Translate(-1 * i, 0);//uncomment

                sp.Transform(m);

                np2.AddPath(sp, true);
            }




            for (int i = 0; i < np2.PointCount; i++)
            {
                //pn[i] = Noise( path.PathPoints[i] , eps);
                pn[i] = Wave(np2.PathPoints[i], amp, size);
                pt[i] = np2.PathTypes[i];
            }

            GraphicsPath newpath = new GraphicsPath(pn, pt);

            return newpath;

        }
Пример #11
0
        /// <summary>
        /// Warps one path to the flattened (<see cref="GraphicsPath.Flatten()"/>) version of another path.
        /// This comes in handy for
        /// <list type="Bullet">
        /// <item>Linestyles that cannot be created with available <see cref="Pen"/>-properties</item>
        /// <item>Warping Text to curves</item>
        /// <item>...</item>
        /// </list>
        /// </summary>
        /// <param name="pathToWarpTo">The path to warp to. This path is flattened before being used, so there is no need to call <see cref="GraphicsPath.Flatten()"/> prior to this function call.</param>
        /// <param name="pathToWarp">The path to warp</param>
        /// <param name="isPattern">Defines whether <paramref name="pathToWarp"/> is a pattern or not. If <paramref name="pathToWarp"/> is a pattern, it is repeated until it has the total length of <see paramref="pathToWarpTo"/></param>
        /// <param name="interval">The interval in which the pattern should be repeated</param>
        /// <returns>Warped <see cref="GraphicsPath"/></returns>
        /// <exception cref="ArgumentNullException">If either pathToWarpTo or pathToWarp is null</exception>
        public static GraphicsPath Warp(GraphicsPath pathToWarpTo, GraphicsPath pathToWarp, bool isPattern, float interval)
        {
            //Test for valid arguments
            if (pathToWarpTo == null)
                throw new ArgumentNullException("pathToWarpTo");
            if (pathToWarp == null)
                throw new ArgumentNullException("pathToWarp");

            //Remove all curves from path to warp to, get total length.
            SortedList<float, GraphSegment> edges;
            pathToWarpTo.Flatten();
            Double pathLength = GetPathLength(pathToWarpTo, out edges);
            if (pathLength == 0)
                return pathToWarp;

            //Prepare path to warp
            pathToWarp = PreparePathToWarp(pathToWarp, isPattern, pathLength, interval);
            if (pathToWarp == null || pathToWarp.PointCount == 0) return null;
            GraphicsPath warpedPath = new GraphicsPath(pathToWarp.FillMode);
            using (GraphicsPathIterator iter = new GraphicsPathIterator(pathToWarp))
            {
                GraphicsPath subPath = new GraphicsPath();
                int currentIndex = 0;
                if (iter.SubpathCount > 1)
                {
                    bool isClosed;
                    while (iter.NextSubpath(subPath, out isClosed) > 0)
                    {
                        GraphicsPath warpedSubPath = WarpSubpath(subPath, edges, ref currentIndex);
                        if (isClosed) warpedSubPath.CloseFigure();
                        warpedPath.AddPath(warpedSubPath, true);
                        warpedPath.SetMarkers();
                    }
                }
                else
                {
                    warpedPath = WarpSubpath(pathToWarp, edges, ref currentIndex);
                }
            }
            return warpedPath;
        }
        public void RenderingPolygonsWithGdiVectorRendererProducesCorrectGdiPaths()
        {
            using (GdiVectorRenderer vectorRenderer = new GdiVectorRenderer())
            {
                BasicGeometryRenderer2D<GdiRenderObject> geometryRenderer
                    = new BasicGeometryRenderer2D<GdiRenderObject>(vectorRenderer);

                FeatureProvider provider = DataSourceHelper.CreateFeatureDatasource(_geoFactory);

                FeatureQueryExpression query 
                    = FeatureQueryExpression.Intersects(provider.GetExtents());

                foreach (IFeatureDataRecord record in provider.ExecuteFeatureQuery(query))
                {
                    IEnumerable<GdiRenderObject> renderedObjects 
                        = geometryRenderer.RenderFeature(record);

                    foreach (GdiRenderObject ro in renderedObjects)
                    {
                        IGeometry g = record.Geometry;

                        if (g is IPolygon)
                        {
                            IPolygon p = g as IPolygon;
                            using (GraphicsPathIterator iter = new GraphicsPathIterator(ro.GdiPath))
                            {
                                Int32 start, end;
                                Boolean isClosed;
                                iter.NextSubpath(out start, out end, out isClosed);

                                Assert.IsTrue(isClosed);
                                Assert.AreEqual(p.ExteriorRing.Coordinates.Count, end - start + 1);

                                for (Int32 vertexIndex = 0; 
                                     vertexIndex < p.ExteriorRing.Coordinates.Count; 
                                     vertexIndex++)
                                {
                                    ICoordinate v = (ICoordinate)p.ExteriorRing.Coordinates[vertexIndex];
                                    PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                    Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                    Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                }

                                foreach (ILineString interiorRing in p.InteriorRings)
                                {
                                    iter.NextSubpath(out start, out end, out isClosed);
                                    Assert.IsTrue(isClosed);
                                    Assert.AreEqual(interiorRing.PointCount, end - start + 1);

                                    for (Int32 vertexIndex = 0;
                                         vertexIndex < interiorRing.PointCount;
                                         vertexIndex++)
                                    {
                                        ICoordinate v = interiorRing.Coordinates[vertexIndex];
                                        PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                        Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                        Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                    }
                                }
                            }
                        }
                        else if (g is IMultiPolygon)
                        {
                            IMultiPolygon mp = g as IMultiPolygon;

                            using (GraphicsPathIterator iter = new GraphicsPathIterator(ro.GdiPath))
                            {
                                foreach (IPolygon p in (IEnumerable<IPolygon>)mp)
                                {
                                    Int32 start, end;
                                    Boolean isClosed;
                                    iter.NextSubpath(out start, out end, out isClosed);

                                    Assert.IsTrue(isClosed);
                                    Int32 exteriorPointCount = p.ExteriorRing.PointCount;
                                    Assert.AreEqual(exteriorPointCount, end - start + 1);

                                    for (Int32 vertexIndex = 0; 
                                         vertexIndex < exteriorPointCount; 
                                         vertexIndex++)
                                    {
                                        ICoordinate v = p.ExteriorRing.Coordinates[vertexIndex];
                                        PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                        Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                        Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                    }

                                    foreach (ILineString interiorRing in p.InteriorRings)
                                    {
                                        iter.NextSubpath(out start, out end, out isClosed);
                                        Assert.IsTrue(isClosed);
                                        Assert.AreEqual(interiorRing.PointCount, end - start + 1);

                                        for (Int32 vertexIndex = 0;
                                             vertexIndex < interiorRing.PointCount;
                                             vertexIndex++)
                                        {
                                            ICoordinate v = interiorRing.Coordinates[vertexIndex];
                                            PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                            Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                            Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public void RenderingLinesWithGdiVectorRendererProducesCorrectGdiPaths()
        {
            using (GdiVectorRenderer vectorRenderer = new GdiVectorRenderer())
            {
                BasicGeometryRenderer2D<GdiRenderObject> geometryRenderer
                    = new BasicGeometryRenderer2D<GdiRenderObject>(vectorRenderer);

                FeatureProvider provider = DataSourceHelper.CreateFeatureDatasource(_geoFactory);

                FeatureQueryExpression query
                    = FeatureQueryExpression.Intersects(provider.GetExtents());

                foreach (IFeatureDataRecord record in provider.ExecuteFeatureQuery(query))
                {
                    IEnumerable<GdiRenderObject> renderedObjects = geometryRenderer.RenderFeature(record);

                    Int32 geoIndex = 0;
                    IGeometry g = record.Geometry;

                    foreach (GdiRenderObject ro in renderedObjects)
                    {
                        using (GraphicsPathIterator iter = new GraphicsPathIterator(ro.GdiPath))
                        {
                            Int32 start, end;
                            Boolean isClosed;
                            iter.NextSubpath(out start, out end, out isClosed);

                            if (g is ILineString)
                            {
                                Assert.IsFalse(isClosed);
                                ILineString ls = g as ILineString;
                                Assert.AreEqual(1, iter.SubpathCount);
                                for (Int32 vertexIndex = 0; vertexIndex < ls.Coordinates.Count; vertexIndex++)
                                {
                                    ICoordinate v = (ICoordinate)ls.Coordinates[vertexIndex];
                                    PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                    Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                    Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                }
                            }
                            else if (g is IMultiLineString)
                            {
                                Assert.IsFalse(isClosed);
                                IMultiLineString mls = g as IMultiLineString;
                                Assert.AreEqual(mls.Count, iter.SubpathCount);
                                foreach (ILineString lineString in (IEnumerable<ILineString>)mls)
                                {
                                    for (Int32 vertexIndex = 0; vertexIndex < lineString.Coordinates.Count; vertexIndex++)
                                    {
                                        ICoordinate v = (ICoordinate)lineString.Coordinates[vertexIndex];
                                        PointF gdiPoint = ro.GdiPath.PathPoints[vertexIndex + start];
                                        Assert.AreEqual(v[Ordinates.X], gdiPoint.X);
                                        Assert.AreEqual(v[Ordinates.Y], gdiPoint.Y);
                                    }

                                    iter.NextSubpath(out start, out end, out isClosed);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #14
0
		/// <summary>
		/// Renders the flattened path to the device using the specified color. 
		/// </summary>
		/// <param name="device">The device to use for rendering the path.</param>
		/// <param name="color">The color to use for the vertices.</param>
		/// <param name="flattenedPath">The path to render.</param>
		protected virtual void Render(Device device, int color, GraphicsPath flattenedPath) {
			PointF[] points = flattenedPath.PathPoints;
			device.VertexFormat = CustomVertex.PositionColored.Format;

			bool isClosed;
			GraphicsPathIterator pi = new GraphicsPathIterator(flattenedPath);

			while(pi.NextSubpath(flattenedPath, out isClosed)!=0) {
				byte type;
				int start, end;

				while(pi.NextPathType(out type, out start, out end)!=0) {
					int numDistinctPoints = end-start+1;
					int totNumPoints = numDistinctPoints;
					if (isClosed) totNumPoints++;

					CustomVertex.PositionColored[] colVerts = new CustomVertex.PositionColored[totNumPoints];
					P3Util.CreateColoredVertexList(colVerts, points, start, 0, numDistinctPoints, color);

					if (isClosed){
						colVerts[numDistinctPoints] = colVerts[0];
					}

					device.DrawUserPrimitives(PrimitiveType.LineStrip, totNumPoints-1, colVerts);
				}
			}
		}
Пример #15
0
		/// <summary>
		/// Cache a flattened path.
		/// </summary>
		/// <param name="flattenedPath">The flattened path to cache.</param>
		protected virtual void CacheFlatPath(GraphicsPath flattenedPath) {
			bool isClosed;
			GraphicsPathIterator pi = new GraphicsPathIterator(flattenedPath);
			PointF[] points = flattenedPath.PathPoints;

			while(pi.NextSubpath(flattenedPath, out isClosed)!=0) {
				byte type;
				int start, end;
				int oldCount = renderList.Count;

				while(pi.NextPathType(out type, out start, out end)!=0) {
					for (int i = start; i <= end; i++) {
						renderList.Add(points[i]);
					}

					if (isClosed){
						renderList.Add(points[start]);
					}

					renderListTypes.Add(new PrimitiveTypeInfo(oldCount, renderList.Count-1, pen.Color.ToArgb(), PrimitiveType.LineStrip));
				}
			}
		}
Пример #16
0
        /// <summary>
        /// Converts the GDI+ GraphicsPath to the MapScript shape object.
        /// </summary>
        /// <param name="path">The GraphicsPath object to convert.</param>
        /// <returns>The converted shapeObj</returns>
        public shapeObj GraphicsPathToShape(GraphicsPath path)
        {
            shapeObj feature = null;

            if (path != null)
            {
                using (GraphicsPathIterator myPathIterator = new GraphicsPathIterator(path))
                {
                    int myStartIndex;
                    int myEndIndex;
                    bool myIsClosed;
                    // get the number of Subpaths.
                    int numSubpaths = myPathIterator.SubpathCount;
                    while (myPathIterator.NextSubpath(out myStartIndex, out myEndIndex, out myIsClosed) > 0)
                    {
                        lineObj line = new lineObj();
                        for (int i = myStartIndex; i <= myEndIndex; i++)
                        {
                            if (i == myStartIndex ||
                                (path.PathPoints[i].X != path.PathPoints[i - 1].X &&
                                 path.PathPoints[i].Y != path.PathPoints[i - 1].Y))
                                line.add(new pointObj(Pixel2MapX(path.PathPoints[i].X), Pixel2MapY(path.PathPoints[i].Y), 0, 0));
                        }
                        if (feature == null)
                        {
                            if (myIsClosed && line.numpoints > 2)
                                feature = new shapeObj((int)MS_SHAPE_TYPE.MS_SHAPE_POLYGON);
                            else
                                feature = new shapeObj((int)MS_SHAPE_TYPE.MS_SHAPE_LINE);
                        }
                        if (line.numpoints >= 2)
                            feature.add(line);
                    }
                }
            }
            return feature;
        }
Пример #17
0
        public virtual void NextPathType() 
		{
            GraphicsPath path = new GraphicsPath ();
			path.AddLine (new Point (100, 100), new Point (400, 100));
			path.AddBezier( 100, 100, 500, 250, 100, 50, 250, 280);
			path.AddLine (new Point (400, 200), new Point (10, 100));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddBezier( 10, 10, 50, 250, 100, 5, 200, 280);
			path.StartFigure ();
			path.SetMarkers ();
			path.AddRectangle (new Rectangle (10, 20, 300, 400));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddLine (new Point (400, 400), new Point (400, 10));

			GraphicsPathIterator iterator = new GraphicsPathIterator (path);

			byte pathType;
			int start;
			int end;
			bool isClosed;

			int count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (0, count);
			Assert.AreEqual ((byte)PathPointType.Start, pathType);
			Assert.AreEqual (0, start);
			Assert.AreEqual (0, end);

			iterator.NextSubpath (out start, out end, out isClosed);
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (3, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (0, start);
			Assert.AreEqual (2, end);

			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (4, count);
			Assert.AreEqual ((byte)PathPointType.Bezier3, pathType);
			Assert.AreEqual (2, start);
			Assert.AreEqual (5, end);

			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (3, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (5, start);
			Assert.AreEqual (7, end);
			
			// we don't want to be a bug compliant with .net
			/* 
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (0, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (5, start);
			Assert.AreEqual (7, end);
			*/

			iterator.NextSubpath (out start, out end, out isClosed);
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (4, count);
			Assert.AreEqual ((byte)PathPointType.Bezier3, pathType);
			Assert.AreEqual (8, start);
			Assert.AreEqual (11, end);

			iterator.NextSubpath (out start, out end, out isClosed);
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (4, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (12, start);
			Assert.AreEqual (15, end);

			iterator.NextSubpath (out start, out end, out isClosed);
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (2, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (16, start);
			Assert.AreEqual (17, end);

			iterator.NextSubpath (out start, out end, out isClosed);
			count = iterator.NextPathType (out pathType, out start, out end);
			Assert.AreEqual (0, count);
			Assert.AreEqual ((byte)PathPointType.Line, pathType);
			Assert.AreEqual (0, start);
			Assert.AreEqual (0, end);
        }
        ///<summary>
        /// Extracts the points of the paths in a flat {@link PathIterator} into
        /// a list of Coordinate arrays.
        ///</summary>
        /// <param name="pathIt">A path iterator</param>
        /// <returns>A list of coordinate arrays</returns>
        /// <exception cref="ArgumentException">If a non-linear segment type is encountered</exception>
        public static IList<Coordinate[]> ToCoordinates(GraphicsPathIterator pathIt)
        {
            if (pathIt.HasCurve())
                throw new ArgumentException("Path must not have non-linear segments");

            var coordArrays = new List<Coordinate[]>();
            int startIndex, endIndex;
            bool isClosed;

            while (pathIt.NextSubpath(out startIndex, out endIndex, out isClosed) > 0)
            {
                Coordinate[] pts = NextCoordinateArray(pathIt, startIndex, endIndex, isClosed);
                coordArrays.Add(pts);
                if (endIndex == pathIt.Count - 1) break;

            }
            return coordArrays;
        }
Пример #19
0
        public virtual void NextSubpath_GraphicsPath_Bool() 
		{
            GraphicsPath path = new GraphicsPath ();
			path.AddLine (new Point (100, 100), new Point (400, 100));
			path.AddLine (new Point (400, 200), new Point (10, 100));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddBezier( 10, 10, 50, 250, 100, 5, 200, 280);
			path.CloseFigure ();
			path.StartFigure ();
			path.SetMarkers ();
			path.AddRectangle (new Rectangle (10, 20, 300, 400));
			path.StartFigure ();
			path.SetMarkers ();
			path.AddLine (new Point (400, 400), new Point (400, 10));

			GraphicsPathIterator iterator = new GraphicsPathIterator (path);
			GraphicsPath path2 = new GraphicsPath ();

			bool isClosed;

			int count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (4, count);
			Assert.IsFalse (isClosed);

			PointF [] actualPoints = path2.PathPoints;
			byte [] actualTypes = path2.PathTypes;

			PointF [] expectedPoints = new PointF [] {	new PointF(100f, 100f), 
														new PointF(400f, 100f), 
														new PointF(400f, 200f), 
														new PointF(10f, 100f)};
			
			for(int i = 0; i < expectedPoints.Length; i++) {
				DrawingTest.AssertAlmostEqual(expectedPoints [i], actualPoints [i]);
			}

			byte [] expectedTypes = new byte [] {	(byte) PathPointType.Start, 
													(byte) PathPointType.Line, 
													(byte) PathPointType.Line, 
													(byte) (PathPointType.Line | PathPointType.PathMarker)};

			for (int i=0; i < expectedTypes.Length; i++) {
				Assert.AreEqual (expectedTypes [i], actualTypes [i]);
			}

			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (4, count);
			Assert.IsTrue (isClosed);

			actualPoints = path2.PathPoints;
			actualTypes = path2.PathTypes;

			expectedPoints = new PointF [] {new PointF(10f, 10f), 
											new PointF(50f, 250f), 
											new PointF(100f, 5f), 
											new PointF(200f, 280f)};
			
			for(int i = 0; i < expectedPoints.Length; i++) {
				DrawingTest.AssertAlmostEqual(expectedPoints [i], actualPoints [i]);
			}

			expectedTypes = new byte [] {	(byte) PathPointType.Start, 
								(byte) PathPointType.Bezier3, 
								(byte) PathPointType.Bezier3, 
								(byte) (PathPointType.Bezier3 | PathPointType.CloseSubpath | PathPointType.PathMarker)};
			
			for (int i=0; i < expectedTypes.Length; i++) {
				Assert.AreEqual (expectedTypes [i], actualTypes [i]);
			}

			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (4, count);
			Assert.IsTrue (isClosed);

			actualPoints = path2.PathPoints;
			actualTypes = path2.PathTypes;

			expectedPoints = new PointF [] {new PointF(10f, 20f), 
											new PointF(310f, 20f), 
											new PointF(310f, 420f), 
											new PointF(10f, 420f)};
			
			for(int i = 0; i < expectedPoints.Length; i++) {
				DrawingTest.AssertAlmostEqual(expectedPoints [i], actualPoints [i]);
			}

			expectedTypes = new byte [] {	(byte) PathPointType.Start, 
											(byte) PathPointType.Line, 
											(byte) PathPointType.Line, 
											(byte) (PathPointType.Line | PathPointType.CloseSubpath | PathPointType.PathMarker)};

			for (int i=0; i < expectedTypes.Length; i++) {
				Assert.AreEqual (expectedTypes [i], actualTypes [i]);
			}

			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (2, count);
			Assert.IsFalse (isClosed);

			actualPoints = path2.PathPoints;
			actualTypes = path2.PathTypes;

			expectedPoints = new PointF [] {new PointF(400f, 400f), 
											new PointF(400f, 10f)};
			
			for(int i = 0; i < expectedPoints.Length; i++) {
				DrawingTest.AssertAlmostEqual(expectedPoints [i], actualPoints [i]);
			}

			expectedTypes = new byte [] {	(byte) PathPointType.Start, 
											(byte) PathPointType.Line};

			for (int i=0; i < expectedTypes.Length; i++) {
				Assert.AreEqual (expectedTypes [i], actualTypes [i]);
			}

			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (0, count);

			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (0, count);
			Assert.IsTrue (isClosed);
			Assert.AreEqual (2, path2.PointCount);

			actualPoints = path2.PathPoints;
			actualTypes = path2.PathTypes;

			expectedPoints = new PointF [] {new PointF(400f, 400f), 
											new PointF(400f, 10f)};
			
			for(int i = 0; i < expectedPoints.Length; i++) {
				DrawingTest.AssertAlmostEqual(expectedPoints [i], actualPoints [i]);
			}

			expectedTypes = new byte [] {	(byte) PathPointType.Start, 
											(byte) PathPointType.Line};

			for (int i=0; i < expectedTypes.Length; i++) {
				Assert.AreEqual (expectedTypes [i], actualTypes [i]);
			}

			path = new GraphicsPath ();
			path.AddBezier( 10, 10, 50, 250, 100, 5, 200, 280);
			iterator = new GraphicsPathIterator (path);
			
			path2 = new GraphicsPath ();			
			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (4, count);
			Assert.IsFalse (isClosed);
			
			path2 = new GraphicsPath ();
			count = iterator.NextSubpath (path2, out isClosed);
			Assert.AreEqual (0, count);
			Assert.IsTrue (isClosed);
        }
Пример #20
0
        /// <summary>
        /// Given the points on this line decoration, this will cycle through and handle
        /// the drawing as dictated by this decoration.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="path"></param>
        /// <param name="scaleWidth">The double scale width for controling markers</param>
        public void Draw(Graphics g, GraphicsPath path, double scaleWidth)
        {
            if (NumSymbols == 0) return;
            GraphicsPathIterator myIterator = new GraphicsPathIterator(path);
            myIterator.Rewind();
            int start, end;
            bool isClosed;
            Size2D symbolSize = _symbol.GetSize();
            Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height);
            Graphics sg = Graphics.FromImage(symbol);
            _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height));
            sg.Dispose();

            Matrix oldMat = g.Transform;
            PointF[] points;
            if (path.PointCount == 0) return;
            try
            {
                points = path.PathPoints;
            }
            catch
            {
                return;
            }
            PointF offset;

            int count = 0;
            while (myIterator.NextSubpath(out start, out end, out isClosed) > 0)
            {
                count = count + 1;
                // First marker
                PointF startPoint = points[start];
                PointF stopPoint = points[start + 1];
                float angle = 0F;
                if (_rotateWithLine) angle = GetAngle(startPoint, stopPoint);
                if (FlipFirst && !FlipAll) FlipAngle(ref angle);
                offset = GetOffset(startPoint, stopPoint);
                startPoint = new PointF(startPoint.X + offset.X, startPoint.Y + offset.Y);
                Matrix rotated = g.Transform;
                rotated.RotateAt(angle, startPoint);
                g.Transform = rotated;
                DrawImage(g, startPoint, symbol);
                g.Transform = oldMat;

                // Second marker
                if (NumSymbols > 1)
                {
                    angle = 0F;
                    if (_rotateWithLine) angle = GetAngle(points[end - 1], points[end]);
                    if (FlipAll) FlipAngle(ref angle);
                    offset = GetOffset(points[end - 1], points[end]);
                    PointF endPoint = new PointF(points[end].X + offset.X, points[end].Y + offset.Y);
                    rotated = g.Transform;
                    rotated.RotateAt(angle, endPoint);
                    g.Transform = rotated;
                    DrawImage(g, endPoint, symbol);
                    g.Transform = oldMat;
                }
                if (NumSymbols > 2)
                {
                    double totalLength = GetLength(points, start, end);
                    double span = totalLength / (NumSymbols - 1);
                    for (int i = 1; i < NumSymbols - 1; i++)
                    {
                        DecorationSpot spot = GetPosition(points, span * i, start, end);
                        angle = 0F;
                        if (_rotateWithLine) angle = GetAngle(spot.Before, spot.After);
                        offset = GetOffset(spot.Before, spot.After);
                        PointF location = new PointF(spot.Position.X + offset.X, spot.Position.Y + offset.Y);
                        if (FlipAll) FlipAngle(ref angle);
                        rotated = g.Transform;
                        rotated.RotateAt(angle, location);
                        g.Transform = rotated;
                        DrawImage(g, location, symbol);
                        g.Transform = oldMat;
                    }
                }
            }
        }
Пример #21
0
		/// <summary>
		/// Tesselates the specified path, notifying the
		/// <see cref="UMD.HCIL.PiccoloDirect3D.Util.TesselationVisitor">TesselationVisitor</see>
		/// as each new triangle primitive is added.
		/// </summary>
		/// <param name="path">The path to tesselate.</param>
		/// <param name="visitor">The tesselation visitor to notify.</param>
		public virtual void Tesselate(GraphicsPath path, TesselationVisitor visitor) {	
			this.visitor = visitor;

			switch (path.FillMode) {
				case FillMode.Alternate: //even/odd
					P3Util.SetWindingRule(tess, P3Util.GlTessWinding.WindingOdd);
					break;
				case FillMode.Winding: //nonzero
					P3Util.SetWindingRule(tess, P3Util.GlTessWinding.WindingNonzero);
					break;
			}

			P3Util.GluTessBeginPolygon(tess, IntPtr.Zero);

			bool isClosed;
			GraphicsPathIterator pi = new GraphicsPathIterator(path);
			PointF[] points = path.PathPoints;

			while(pi.NextSubpath(path, out isClosed)!=0) {
				byte type;
				int start, end;
				while(pi.NextPathType(out type, out start, out end)!=0) {
					PathPointType ppType = (PathPointType)type;

					P3Util.GluTessBeginContour(tess);

					for (int i = start; i <= end; i++) {
						PointF point = points[i];
						double[] coords = new double[3];
						coords[0] = point.X;
						coords[1] = point.Y;
						coords[2] = 0;
						GCHandle handle = GCHandle.Alloc(coords, GCHandleType.Pinned);
						P3Util.GluTessVertex(tess, coords, (IntPtr)handle);
						handles.Add(handle);
					}

					P3Util.GluTessEndContour(tess);
				}
			}

			P3Util.GluTessEndPolygon(tess);	

			ClearHandles();
		}
Пример #22
0
        /// <summary>
        /// Given the points on this line decoration, this will cycle through and handle
        /// the drawing as dictated by this decoration.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="path"></param>
        /// <param name="scaleWidth">The double scale width for controling markers</param>
        public void Draw(Graphics g, GraphicsPath path, double scaleWidth)
        {
            if (NumSymbols == 0) return;
            GraphicsPathIterator myIterator = new GraphicsPathIterator(path);
            myIterator.Rewind();
            int start, end;
            bool isClosed;
            Size2D symbolSize = _symbol.GetSize();
            Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height);
            Graphics sg = Graphics.FromImage(symbol);
            _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height));
            sg.Dispose();

            Matrix oldMat = g.Transform;
            PointF[] points;
            if (path.PointCount == 0) return;
            try
            {
                points = path.PathPoints;
            }
            catch
            {
                return;
            }


            while (myIterator.NextSubpath(out start, out end, out isClosed) > 0)
            {
                if (NumSymbols == 1) //single decoration spot
                {
                    if (_percentualPosition == 0) // at start of the line
                    {
                        DrawImage(g, points[start], points[start + 1], points[start], (FlipFirst ^ FlipAll), symbol, oldMat);
                    }
                    else if (_percentualPosition == 100) // at end of the line
                    {
                        DrawImage(g, points[end - 1], points[end], points[end], (FlipFirst ^ FlipAll), symbol, oldMat);
                    }
                    else  //somewhere in between start and end
                    {
                        double totalLength = GetLength(points, start, end);
                        double span = totalLength * (double)_percentualPosition / 100;
                        List<DecorationSpot> spot = GetPosition(points, span, start, end);
                        if (spot.Count > 1)
                            DrawImage(g, spot[1].Before, spot[1].After, spot[1].Position, (FlipFirst ^ FlipAll), symbol, oldMat);
                    }
                }
                else // more than one decoration spot
                {
                    double totalLength = GetLength(points, start, end);
                    double span = Math.Round(totalLength / (NumSymbols - 1), 4);
                    List<DecorationSpot> spots = GetPosition(points, span, start, end);
                    spots.Add(new DecorationSpot(points[end - 1], points[end], points[end])); //add the missing end point
                    for (int i = 0; i < spots.Count; i++)
                        DrawImage(g, spots[i].Before, spots[i].After, spots[i].Position, i == 0 ? (FlipFirst ^ FlipAll) : FlipAll, symbol, oldMat);
                }
            }
        }