WynApse Home Page
Home    Blog    About    Contact       
Latest Article:

My Tags:
My Sponsors:

Lifetime Member:

Silverlight Rectangles, Paths, and Line Comparison

Get Microsoft Silverlight

Silverlight 2 Beta 2 Update

I've updated this code for Beta 2, it didn't take much to do so. The biggest part was to just recompile with all the B2 bits in place.

One thing I did notice with Beta 2 that maybe was there with Beta 1, and I just didn't notice was that in the designer surface, the image appeared different on more than one level. I had remarked about the Black rectangles drawn with Lines looking nice and crisp in the designer but not at run-time. In Beta 2, those Line-drawn rectangles are the only thing that DOES look correct in the designer. Here's an expanded screenshot of the designer running the code that is running above:

For comparison, I've taken a screenshot of the run-time and blown it up to 400% also:

You can clearly see from the screen-shot of the designer that the only objects not being displayed anti-aliased in the designer are the two black rectangles drawn with Path and Line objects. Curiously, those are the only two that are antialiased at run-time.


This whole article sequence began with a Silverlight.net forum query back in the WPF/E days, and a few of us took it to conclusion which I described in an article titled Silverlight Rectangles, Paths, and Line Comparison. All the history, discussion, and people are mentioned in that post.

It goes without saying that the problem described and the solution offered still exists in the latest version of Silverlight 1.0. I don't mean to imply there's a problem with Silverlight 1.0, I'm saying there's an issue that needs attention when you're laying out objects on a canvas.

I then did a Tooltip that addresses the issue from a different perspective. Once again, the line display on the page is live Silverlight 1.0, and still demonstrates the situation.

Enter Silverlight 2

As should be obvious, I have not done much Silverlight 2 yet, or none that is showing on my site, but on May 27th I blogged about an article by Dave Relyea, Pixel Snapping - the Snapper Element. Dave's article got me to thinking that I wonder what the tests I did in Silverlight 1.0 would look like in Silverlight 2.

I opened a new Silverlight 2 project and dropped this XAML from my Silverlight 1.0 article in place:

<UserControl x:Class="Silverlight2Lines.Page"
Width="150" Height="100" >
<Canvas Background="White">
<Rectangle Canvas.Left="50" Canvas.Top="5" Width="50" Height="50" Stroke="Black" StrokeThickness="1" />
<Path Stroke="Black" StrokeThickness="1"
Data="M20,20 L70,20 L70,70 L20,70z"/>
<Line Stroke="Black" StrokeThickness="1" X1="80" Y1="20" X2="130" Y2="20" />
<Line Stroke="Black" StrokeThickness="1" X1="130" Y1="20" X2="130" Y2="70" />
<Line Stroke="Black" StrokeThickness="1" X1="130" Y1="70" X2="80" Y2="70" />
<Line Stroke="Black" StrokeThickness="1" X1="80" Y1="70" X2="80" Y2="20" />
<Path Stroke="Red" StrokeThickness="2"
Data="M35,40 L115,40 L115,85 L35,85z"/>
<Path Stroke="Blue" StrokeThickness="1"
Data="M5.5,45.5 L60.5,45.5 L60.5,95.5 L5.5,95.5z"/>
<Line Stroke="Blue" StrokeThickness="1" X1="90.5" Y1="45.5" X2="145.5" Y2="45.5" />
<Line Stroke="Blue" StrokeThickness="1" X1="145.5" Y1="45.5" X2="145.5" Y2="95.5" />
<Line Stroke="Blue" StrokeThickness="1" X1="145.5" Y1="95.5" X2="90.5" Y2="95.5" />
<Line Stroke="Blue" StrokeThickness="1" X1="90.5" Y1="95.5" X2="90.5" Y2="45.5" />

and hmmm... the display surface looked perfect... thin lines on everything. WOW... how cool is that? I walked away from the workstation contemplating the meaning of that and how it tied in with Dave's article and how there was no article in it for me...

But wait... I had just looked at the Silverlight 1.0 pages on my site and the anti-aliasing was still present, so now what did that mean?

Back in here, and ran the project rather than just looking at it in the designer and whoa... it exactly matches the Silverlight 1.0 page!

Enter Silverlight 2

So now a few problems emerge from all that...

  1. Dave's article discussed at length placing rectangles and implied other objects at the whole-pixel locations
  2. This test clearly shows that placing Lines and Paths at whole-pixel locations causes anti-aliasing
  3. The VS2008 design surface is not consistent with the run-time display

Resolving these issues (in my mind)

In Silverlight 1.0 there never was a problem with rendering rectangles on whole-pixel coordinates, and to be perfectly honest, I'm not sure I ever tried moving a rectangle to a 'partial pixel' location such as Dave described in his article. Possibly that is a problem in 1.0 as well.

The issue arose for me when trying to draw 3 sides of a rectangle at a stroke of 1 pixel. If I do that in Silverlight 1.0 or Silverlight 2, I get anti-aliasing for all the reasons discussed over a year ago.

The only item I can't resolve in my mind is the difference between the VS2008 display surface and the run-time display of my sample. I will report this to the Insider's group and see what the project folks make of it, and I'll report anything I hear back to this article.

Oh yeah... one more thing...

I took a shot at the XAML from the Silverlight 1.0 Tooltip I referenced above:

<UserControl x:Class="Silverlight2Lines.Page"
Width="210" Height="110" >
<Canvas Background="White">
<TextBlock FontSize="12" Text=".0 Line:" />
<Line X1="45" Y1="10" X2="200" Y2="10" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="10" FontSize="12" Text=".1 Path:" />
<Path Data="M45.1,20.1 L200.1,20.1" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="20" FontSize="12" Text=".2 Line:" />
<Line X1="45.2" Y1="30.2" X2="200.2" Y2="30.2" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="30" FontSize="12" Text=".3 Path:" />
<Path Data="M45.3,40.3 L200.3,40.3" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="40" FontSize="12" Text=".4 Line:" />
<Line X1="45.4" Y1="50.4" X2="200.4" Y2="50.4" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="50" FontSize="12" Text=".5 Path:" />
<Path Data="M45.5,60.5 L200.5,60.5" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="60" FontSize="12" Text=".6 Line:" />
<Line X1="45.6" Y1="70.6" X2="200.6" Y2="70.6" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="70" FontSize="12" Text=".7 Path:" />
<Path Data="M45.7,80.7 L200.7,80.7" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="80" FontSize="12" Text=".8 Line:" />
<Line X1="45.8" Y1="90.8" X2="200.8" Y2="90.8" StrokeThickness="1" Stroke="Blue" />
<TextBlock Canvas.Top="90" FontSize="12" Text=".9 Path:" />
<Path Data="M45.9,100.9 L200.9,100.9" StrokeThickness="1" Stroke="Blue" />
<Path Data="M45.5,20.5 L200.5,80.5" StrokeThickness="1" Stroke="Green" />
<Line X1="45.6" Y1="30.6" X2="200.6" Y2="90.6" StrokeThickness="1" Stroke="Green" />

and came up with this:

Get Microsoft Silverlight

That certainly looks identical to the results from Silverlight 1.0! And as a note, the design surface of VS2008 looks identical to this.

So I feel pretty good... the Silverlight 1.0 code runs the same as Silverlight 2, and the only difficulty is the display surface in VS2008.

Plus... as a bonus, I just presented my first content page (this one) with Silverlight 2 product on it, and two canvases to boot...

Stay in the Light!

Copyright © 2006-2017, WynApse