Circle shapes from SWF being cropped slightly

I’m using a mix of SWF assets and code-drawn objects in my game, and I’m noticing that SWF-derived circles/curved shapes sometimes seem a bit cropped by 1-2 pixels on one size, as if a slightly-too-small AABB mask was applied to them. This isn’t happening at the screen level, or a result of aliasing, because a circle object that’s rotated 45-degrees will have the 1-2 pixel crop running diagonally on the same edge. Here’s a screengrab captured at 100% scale (1920x1080):


The black-outlined red dot is drawn using code, while the blue elements are generated from SWF.

When I run the game in full-screen, scaled to 2560x1440, the crop is still visible, and still 1-2 pixels, but somewhat less noticeable because the asset itself is larger:


Any idea what’s going on here?

(I’m using Haxe 3.4.7 and OpenFL 8.9.1 and can’t update because of other dependencies, so if it’s something that’s been improved with the newer way of doing SWFs in OpenFL 9 I might have to figure that out or come up with another workaround.)

It is possible that the off-screen surface used to cache and draw vector graphics is slightly too small. The code here has been the same for a long time however it is still possible that it’s slightly off. We want surfaces to stay small so they can to save memory however it’s the first thing that comes to my mind.

Take a look here… in an older version of OpenFL this would be located in “src/openfl/display/Graphics.hx” (instead of being under “packages”)

This code “inflates” the bounds for the target size of the generated surface by two different points in order to accommodate the size of the circle. Perhaps this logic is a little bit wrong? It might be that the circle requires an extra pixel always (not sure that’s true) or perhaps the stroke padding value is a little too small considering the value of your line width

Stroke padding is set here:

If your line width is not a whole number… perhaps this should be Math.ceil in order to accommodate partial values?

I’ve been putting off dealing with this, but as it popped up in a different project (using OpenFL 9), I thought I’d better follow up on your suggestion.

I poked around in Graphics.hx and sure enough, just adding 1 to __strokePadding in the lineStyle function appeared to do the trick.

if (joints == JointStyle.MITER){
	if (thickness > __strokePadding) __strokePadding = thickness + 1;
} else {
	if (thickness / 2 > __strokePadding) __strokePadding = thickness / 2 + 1;

Screenshot 2021-01-07 063503

The wrinkle here is that this other project I’m testing this on doesn’t actually use strokes (in the Flash sense) to draw these circles (even though it looks like it does), just filled shapes. The code makes sense, but the variable name makes it a little confusing. This is probably a legacy of AS3, but doesn’t this describe a “path,” rather than a line or stroke?

Thanks for so quickly pointing me in the right direction on this!

perhaps this should be Math.ceil in order to accommodate partial values?

Sure enough, Math.ceil(thickness / 2) also works. That seems like the most efficient way to address it.

I can’t really test it with JointStyle.MITER, since a separate bug means that all strokes/paths imported from a SWF will use JointStyle.ROUND, so the value is always divided by 2.

Could you do a quick pull request for this?

Thank you! :smiley:

Sure! It’s been awhile since I’ve done a PR, but it was nice to have a reason to re-learn how to do it: