Search code examples
vb.netgdi+polygonoutlinegraphicspath

Using Angus J Clipper library to outline GraphicsPath text in vb.net


I am creating text in a GDI+ GraphicsPath, using DrawString, and then outputting this to PDF as a path.

This is all working perfectly at the moment.

The time I have an issue is when the chosen font causes the outlines to overlap each other. I have an image example though being a new user i can't upload it... (seems pointless..?..)

I found a library and also someone who has achieved the same as what I am looking for in this blog

I have converted the code snippet to vb.net though I keep getting an empty solution from the library.

Has anybody else managed to pass in a graphicsPath containing a string and retrieve outlined text using this or a similar library?


Solution

  • Here's some C# code that works ...

        using ClipperLib;
    
        static public void PathToPolygon(GraphicsPath path, Polygons polys, Single scale)
        {
            GraphicsPathIterator pathIterator = new GraphicsPathIterator(path);
            pathIterator.Rewind();
            polys.Clear();
            PointF[] points = new PointF[pathIterator.Count];
            byte[] types = new byte[pathIterator.Count];
            pathIterator.Enumerate(ref points, ref types);
            int i = 0;
            while (i < pathIterator.Count)
            {
                Polygon pg = new Polygon();
                polys.Add(pg);
                do {
    
                    IntPoint pt = new IntPoint((int)(points[i].X * scale), (int)(points[i].Y * scale));
                        pg.Add(pt);
                    i++;
                }
                while (i < pathIterator.Count && types[i] != 0);
            }
        }
    
    
        static private PointF[] PolygonToPointFArray(Polygon pg, float scale)
        {
            PointF[] result = new PointF[pg.Count];
            for (int i = 0; i < pg.Count; ++i)
            {
                result[i].X = (float)pg[i].X / scale;
                result[i].Y = (float)pg[i].Y / scale;
            }
            return result;
        }
    
    
        private void DrawBitmap()
        {
            Font f = new Font("Arial", 90);
            Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6);
            SolidBrush myBrush = new SolidBrush(Color.FromArgb(127, 0xDD, 0xDD, 0xF0));
            path.Reset();
            Polygons polys;
            path.AddString("ABC", f.FontFamily, (int)f.Style, f.Size, new Point(100, 100), null);
            path.Flatten();
            //scale all points up by 100 because Clipper uses integer coordinates
            PathToPolygon(path, polys, 100);
            path.Reset();
            //offset polys remembering to multiply delta by scaling amount ...
            polys = Clipper.OffsetPolygons(polys, 7 * 100, JoinType.jtRound);
            for (int i = 0; i < polys.Count(); i++)
            {
                //reverses scaling ...
                PointF[] pts2 = PolygonToPointFArray(polys[i], 100);
                path.AddPolygon(pts2);
            }
            newgraphic.FillPath(myBrush, path);
            newgraphic.DrawPath(myPen, path);
        }
    

    enter image description here