A quick note regarding something I’ve been meaning to post a short note about for a while, for those that might be running into problems resulting from shapes drawn in flash with an outline. I ran into this recently again, so I thought I’d post for any concerned parties out there.
Regardless of whether or not a shape, such as a rectangle, is drawn in Flash with a hairline border line, or a borderline of 1, the result on an unscaled shape is essentially the same. The crisp outline of the shape is drawn with a pixel width of 1. The downside of this occurs when trying to create pixel perfect UI’s, and especially those using shapes with a scalenine grid assigned to them.
Using the AS3 drawing API, you can create a rectangle that has a lineStyle with a width of 1, and some fill, which would look something like this:
var sh:Shape = new Shape(); sh.graphics.lineStyle(1, 0xFF0000); sh.graphics.beginFill(0xFF6600); sh.graphics.drawRect(0, 0, 100, 100); sh.graphics.endFill(); addChild(sh); trace("Size: " + sh.width + " x " + sh.height);
The code above so draws an orange rectangle with a red border that is 201 pixels wide and 101 pixels tall. If you don’t know why, the reason is because flash draws the line on the pixel width and height of the rectangle with a line size of 1. This makes your shape 201 x 101; thankfully, Flash will report the width and height correctly as 201 x 101.
This gets stickier if you have a shape that is used as a component skin, and has a scale9Grid applied to it. In this case you will likely be working with a component that you expect to take up 200×100 pixels on the stage when you tell it to be that size. However, if the skin used features “line” outlines at its borders, your component will get drawn on the stage with extra pixels. If you dig into the Flash component skins, you will notice that most of the skins use fills for any borders on the shapes (even 1 pixel wide borders) so that the scale9Grid enabled shapes will scale correctly to the pixel. That being said, the proper way to draw the simple skin shape in this case, programmatically, would be:
var sh2:Shape = new Shape(); sh2.graphics.beginFill(0xFF0000); sh2.graphics.drawRect(0, 0, 200, 100); sh2.graphics.beginFill(0xFF6600); sh2.graphics.drawRect(1, 1, 198, 98); sh2.graphics.endFill(); addChild(sh2); trace("Size: " + sh2.width + " x " + sh2.height);
Incidentally, this also often cleans up some anti-aliasing at the corners of rectangular shapes which I believe is cause by some weirdness in the way the “caps” are drawn on the shapes. (but don’t quote me on that…)