I’m trying to draw on a canvas where there is a circle overlapping a rectangle. I want a border around the circle of a few pixels, but to be of the window background color.
I’m trying to clear a slightly larger oval behind the one that will be visible, so it appear that the rectangle has a cutout.
I know there is a clearRectangle method, but there isn’t a similar clearOval.
If I try drawingColor = color.clear, it (obviously) draws nothing and the existing color remains.
I think you need to clip the drawing of the rectangle rather than trying to erase it afterwards.
I’ve had a quick look at the latest Xojo documentation and I think you could use Graphics.ClipToPath.
• Create a GraphicsPath that consists of the slightly larger oval.
• Save the graphics state
• Call ClipToPath
• Draw your rectangle
• Restore the graphics state
• Draw your circle
So… this is all going to depend a lot on the target OS. macOS now gives their windows a slightly translucent effect and using FillColor to fill a circle is going to stand out like a sore thumb.
My suggestion is that you draw this special rectangle with the cutout using a picture with an alpha channel. The color portion of the picture will be solid (whatever color the rectangle is supposed to be). The alpha channel will be black where the color should appear and white where it should be transparent. Then you draw that image onto the canvas.
That’s a reasonable workaround for Xojo’s lack of even-odd/winding rule when filling paths. Without taking steps, though, it won’t properly utilize the proper resolution of a scaled interface (i.e. high resolution) and may run into color matching issues between graphics drawn directly to a screen context and those initially drawn to an off-screen buffer.
The lack of compound paths in Xojo is pretty surprising, considering that GraphicsPath is right there; the Object2D stuff isn’t structured in such a way to easily accommodate this feature.
Sure it will. You can get the scale factor from the graphics context. Then you just make sure you create the picture and graphics context correctly. I’ve done it hundreds of times.
// scalex and scalex are the same
Dim sf as double = g.scalex
Dim w as integer = 150
Dim h as integer = 100
Dim p as new picture(w * sf, h * sf)
Dim gg as graphics = p.graphics
gg.scalex = sf
gg.scaley = sf