Odd artifact when drawing rounded corners in canvas

I’ve been messing about with this for hours and can’t come up with a solution.

What I want is a nice rounded end - the canvas is 30 pixels high.

This is the code:

g.ForeColor = kGrayMid g.FillRoundRect (0,0,me.width,me.height,30,30) g.PenHeight=1 g.PenWidth=1 g.DrawRoundRect (0,0,me.width,me.height,30,30)

You can see the odd artifact in image 1 with the vertical line at the beginning of the shape.

With the code posted above, I’ve drawn a 1px keyline around the object - YES, this does cause the artifact, but if I don’t have that 1px keyline, then I have a different artifact as in image 2, which has a semi-transparent (anti-aliased) outline - and not as sharp as image 1, not good enough either.

That brings us to image 3. This shows a 15px radius. OR is it? The artifact has disappeared but that throws up other questions about rounded corners. In my experience using Adobe Illustrator and Autocad, to get a complete semi-circle rounded end, you simply make the radius of the corners half the height, ie. 15 in my case with a 30px high rectangle - so what is going on here?

So, we finally come to image 4. As a test I changed the code to:
g.FillRoundRect (0,0,me.width,me.height,50,50)

The 50 pixels result is very familiar. The radius is larger than the height of the rectangle and therefore shows XOR as in when bezier curves overlap - I think.

Nevertheless, I’d like sharp rounded corners.

Cheers.

I used two icons with round rects in a Canvas / Windows and do not have this effect.

Are-you sure the vertical line is not in your image ?

Did you add a new Canvas and set that image (alone) on it to be sure of what you get ?

At last, did you try to draw the rect (around the Canvas)… around the Canvas (in the window) ?

Platform?
OS version?
Xojo version?

This works for me in Mac on Xojo 2015, and looks most like number 2

g.ForeColor = &c808080 g.FillRoundRect (0,0,me.width,me.height,me.height,me.height)

Here is an alternative you might like to try:

dim o as new RoundRectShape o.width = me.width o.height = me.height o.FillColor = &c808080 o.CornerHeight = me.height +1 o.CornerWidth = me.height +1 g.DrawObject o, me.width/2,me.height/2

Thanks Emile, no the line is definitely not in the image.

Yeah, thanks Jeff, sorry I forgot to post the vital info:
WIN7
Xojo2016R3

I tried RoundRectShape but the result is actually worse (the top image):

RoundRectShape has a Segment property which I increased, but the best I got is as shown.

The bottom image shows the object unfilled with a 1px outline. You’ll notice that the artifact only appears at top left. So if I wanted to draw an unfilled round ended pill shape, it seems I wouldn’t be able to.

Anyway, I’ve spent way too much time on this - I’m just going to have to live with the version without the outline.

Cheers.

90% of the time spent on 10% of the features.

I think I may have got this when the corner size was too large. Try reducing it.

@Jeff.
I do tend to get obsessed with small things like this and can’t seem to let it go and move forward. I should just continue on with finishing the code and come back to it later.

I did try that thanks Kevin. If you refer to image 3 in the first post, that is 15px. I did go all the way up toward 30px until it appeared - it starts to appear at 22 pixels.

Yes…if it helps - if all the shapes (including the white bits) looked like image 3, it would still look tidy …

?

Image 3 (15px) has the outline, that’s why it looks sharper. Image 2 is the one I have to live with.

That’s because I WANT the rounded pill shape. I can’t let go of that one :slight_smile:

steve:

in a current project, I add a Canvas, Copy / Paste your code in its Paint Event (and define the Grey color Konstant), then run it in the IDE: works nice.

Nota: macOS X (El Capitan) / Xojo 2015r1.

Beside some wasted KB, why don’t you draw the grey round rect, save it as a picture and load / display it ?
(as a work-around 'till the bug will be removed)

Same here. I don’t see any issues (on Windows 10).

2016r3 and HiDPI on Windows has quite some graphics drawing/positioning issues.
While I don’t think this is the case here I’d like to add one more idea:
What happens if you compose your shape with Ovals and Rects?

g.ForeColor = kGrayMid g.PenHeight=1 g.PenWidth=1 g.FillOval(0, 0, 30, 30) g.FillOval(me.Width-30, 0, 30, 30) g.FillRect(15, 0, me.Width-30, 30)

Another idea:

Did you try to run the project using Xojo 2017r2.1 ?
(just run, not save nor compile)

[quote=360495:@Emile Schwarz]steve:
. . . Beside some wasted KB, why don’t you draw the grey round rect, save it as a picture and load / display it ?[/quote]

And that is exactly what I just did. I’ve always known that I could do this, as I have drawn many custom buttons this way (as per above), but I prefer to use Xojo’s native drawing controls when I can.

You can see from the above image - it’s the best I’ll get at this resolution.

The problem with inserting images is that it can be a pain to have to go back and change them if you change the size of the control.
.
.

[quote=360496:@Jürg Otter]Same here.
What happens if you compose your shape with Ovals and Rects?

g.ForeColor = kGrayMid g.PenHeight=1 g.PenWidth=1 g.FillOval(0, 0, 30, 30) g.FillOval(me.Width-30, 0, 30, 30) g.FillRect(15, 0, me.Width-30, 30)[/quote]

Thanks Jürg - I’ve thought about that approach and I think it may well work with what I need right now, but it would not work if I wanted just an outline, as you would see the construction shapes of circles and squares etc…
.
.

[quote=360503:@Emile Schwarz]Another idea:
Did you try to run the project using Xojo 2017r2.1 ?
(just run, not save nor compile)[/quote]

At this point I’ve stuck with 2016R3, when it looks like some of the windows issues have been resolved, then I’ll upgrade. I’m just unsure if I can open my code in the new framework without me having to change things.

My bad. I meant to use Xojo 2017r2.1 just for testings.

Your code snippet worked for me on my Mac but you say it doesn’t work on MS-Windows. That is possibly a difference in how the round rects are being drawn on different platforms. Round Rects were a Mac operating system feature so RB / Xojo probably just uses what the operating system provided. I don’t think Windows has round rects so Xojo is possibly emulating them using bezier curves or arcs.

Here is some code to draw a round rect that should be similar in appearance to the ones generated on a Mac. You might be able to use this code to get a better result:

[code]Sub RoundRect(Extends p As Picture, pX As Integer, pY As Integer, pWidth As Integer, pHeight As Integer, pArcSizeX As Integer, pArcSizeY As Integer)
Dim fs As FigureShape
Dim rx, ry As Single
Dim hx, hy As Single

fs = New FigureShape
fs.Border = 100
fs.BorderWidth = 1
fs.BorderColor = RGB(0, 0, 0)
fs.Fill = 100
fs.FillColor = RGB(128, 128, 128)

pArcSizeX = Max(pArcSizeX, 0)
pArcSizeY = Max(pArcSizeY, 0)
pArcSizeX = Min(pArcSizeX, pWidth)
pArcSizeY = Min(pArcSizeY, pHeight)

rx = pArcSizeX / 2
ry = pArcSizeY / 2

hx = rx * 0.5522847497
hy = ry * 0.5522847497

fs.AddCubic(0, ry, rx, 0, 0, ry - hy, rx - hx, 0)

fs.AddLine(rx, 0, -rx + pWidth, 0)

fs.AddCubic(-rx + pWidth, 0, pWidth, ry, - rx + pWidth + hx, 0, pWidth, ry - hy)

fs.AddLine(pWidth, ry, pWidth, pHeight - ry)

fs.AddCubic(pWidth, pHeight - ry, pWidth - rx, pHeight, pWidth, - ry + pHeight + hy, pWidth + hx - rx, pHeight)

fs.AddLine(pWidth - rx, pHeight, rx, pHeight)

fs.AddCubic(rx, pHeight, 0, pHeight - ry, rx - hx, pHeight, 0, pHeight + hy - ry)

fs.AddLine(0, pHeight - ry, 0, ry)

p.Graphics.DrawObject(fs, pX, pY)
End Sub[/code]

This is a bug with GDI+ in 2016r3 which was fixed in 2016r4 when everything went to Direct2D

Its only evident in DrawRoundRect and not FillRoundRect.

[quote=360372:@Steve Kelepouris] g.ForeColor = kGrayMid
g.FillRoundRect (0,0,me.width,me.height,30,30)
g.PenHeight=1
g.PenWidth=1
g.DrawRoundRect (0,0,me.width,me.height,30,30)[/quote]

Is there any reason why you’re drawing over the filled rectangle with another rectangle outline of the same colour or was this just a demo and you actually use another colour for the DrawRoundRect in your actual program?

[quote=360585:@JulianS]

This is a bug with GDI+ in 2016r3 which was fixed in 2016r4 when everything went to Direct2D

Its only evident in DrawRoundRect and not FillRoundRect.[/quote]
Then I would suggest that you use FillRoundRect twice. Firstly with the marker (outline) colour and the width and height are +2 pixels. The second with your ‘normal’ colour but left and top offset by 1 pixel to the first FillRoundRect.

That will give you the desired effect.

Simon.

The reason I have the outline is that it makes it look sharper.

The 3 small gray slugs in the image below:
1st. Outline only
2nd. Filled, no outline
3rd. Filled, plus outline = Sharper

The only reason I noticed was because of the small space top and bottom of the time symbol. Image 1 appears sharper and thicker, but has the artifact.

[quote]This is a bug with GDI+ in 2016r3 which was fixed in 2016r4 when everything went to Direct2D
Its only evident in DrawRoundRect and not FillRoundRect.[/quote]

Thanks for the explanation Julian. I now at least know why :slight_smile:

@Simon, thanks Simon but I don’t think that will work as it would still have the anti-aliased edges.

Cheers.