Search code examples
c#.netgdi+gdigraphicspath

GraphicsPath and DrawPath - Removing Intersecting Lines


The following code draws a cross:

using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
{
    using(GraphicsPath path = new GraphicsPath())
    {
        path.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
        path.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
        path.FillMode = FillMode.Winding;
        e.Graphics.DrawPath(Pens.DimGray, path);
    }
}

enter image description here

I would like to draw it like so:

enter image description here

I've tried using Flatten(); and CloseAllFigures(); but these don't work.

I'm looking for an effect like Union:

enter image description here

Is this possible with GraphicsPath?


Solution

  • It is possible to use Regions.But you should use the API FrameRgn in GDI to draw the frame of the region if there is no other solutions.

            Graphics g = e.Graphics;
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
            {
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
                    path.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
                    path.FillMode = FillMode.Winding;
                    using (Region region = new Region(path))
                    {
                        IntPtr reg = region.GetHrgn(g);
                        IntPtr hdc = g.GetHdc();
                        IntPtr brushPtr = Win32.GetStockObject(Win32.WHITE_BRUSH);
                        IntPtr oldbrushPtr = Win32.SelectObject(hdc, brushPtr);
                        Win32.FrameRgn(hdc, reg, brushPtr, 1, 1);
                        Win32.DeleteObject(brushPtr);
                        Win32.SelectObject(hdc, oldbrushPtr);
                        region.ReleaseHrgn(reg);
                        g.ReleaseHdc();
                    }
                }
            }