Reputation: 42239
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);
}
}
I would like to draw it like so:
I've tried using Flatten();
and CloseAllFigures();
but these don't work.
I'm looking for an effect like Union:
Is this possible with GraphicsPath?
Upvotes: 4
Views: 3262
Reputation: 26
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();
}
}
}
Upvotes: 1
Reputation: 133
You will need to use Regions for this, here is an example adapted from your existing code. It should be noted that you can also call Exclude, Intersect, and Xor on the region! :)
private void Form1_Paint(object sender, PaintEventArgs e)
{
GraphicsPath Shape1 = new GraphicsPath();
Shape1.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
GraphicsPath Shape2 = new GraphicsPath();
Shape2.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
Region UnitedRegion = new Region();
UnitedRegion.MakeEmpty();
UnitedRegion.Union(Shape1);
UnitedRegion.Union(Shape2);
e.Graphics.FillRegion(Brushes.Black, UnitedRegion);
}
Upvotes: 0
Reputation: 5899
I know this is not a perfect solution, but take it as one option:
using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
{
using (GraphicsPath path = new GraphicsPath())
{
var rect1 = new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height - 1);
var rect2 = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width - 1, 40);
path.AddRectangle(rect1);
path.AddRectangle(rect2);
e.Graphics.DrawPath(Pens.DimGray, path);
var bgRect1 = new Rectangle(rect1.X + 1, rect1.Y + 1, rect1.Width - 1, rect1.Height - 1);
var bgRect2 = new Rectangle(rect2.X + 1, rect2.Y + 1, rect2.Width - 1, rect2.Height - 1);
using (GraphicsPath backgroundPath = new GraphicsPath())
{
backgroundPath.AddRectangle(bgRect1);
backgroundPath.AddRectangle(bgRect2);
e.Graphics.FillPath(Brushes.White, backgroundPath);
}
}
}
This is the result:
Upvotes: 1
Reputation: 2142
It's possible and what you're after is regions. Take a look at:
I'm guessing your next step would be to outline the region. This is the difficult part because there's no API to do that. Easiest approach is to:
This would produce the second picture you attached. Region operations require a bit of creativity due to the lack of edge-detect, contours or region-to-path APIs to help you draw the result.
Upvotes: 0