Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering sharp lines in WPF

If I render the following:

<Grid>
  <Canvas SnapsToDevicePixels="True">  
    <Path Fill="#FF000000" SnapsToDevicePixels="True" Data="M 0.00,0.00 L 2.50,0.00 0.00,10.00 " />
    <Path Fill="#FF260014" SnapsToDevicePixels="True" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
    <Canvas.RenderTransform>
      <ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
    </Canvas.RenderTransform>
  </Canvas>
  <Slider x:Name="slider" Minimum="0" Maximum="50" Value="30"/>
</Grid>

I get this result (Kaxaml):

enter image description here

Notice the thin white line between the two shapes. I searched around and found out this has to do with pixel alignment. I would expect that settings SnapsToDevicePixels="True" would be enough to get rid of the line, but this doesn't work!

Any ideas how to get rid of the white line?

like image 259
Robbert Dam Avatar asked Dec 01 '09 09:12

Robbert Dam


2 Answers

Try turning edge aliasing on with RenderOptions, like this (see Grid properties)

<Grid RenderOptions.EdgeMode="Aliased">
  <Canvas SnapsToDevicePixels="True">  
        <Path Fill="#FF000000" SnapsToDevicePixels="True" Data="M 0.00,0.00 L 2.50,0.00 0.00,10.00 " />
        <Path Fill="#FF260014" SnapsToDevicePixels="True" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
        <Canvas.RenderTransform>
          <ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
        </Canvas.RenderTransform>
  </Canvas>

  <Slider x:Name="slider" Minimum="0" Maximum="50" Value="30"/>
</Grid>
like image 91
Max Galkin Avatar answered Sep 20 '22 15:09

Max Galkin


Remember that SnapsToDevicePixels only controls that individual points do not lie on fractional pixel values. For horizontal and vertical lines this is most easily observed. In your case you are seeing an entirely different problem. The edges of your shapes are anti-aliased and therefore blended with the background. Since your shapes are exactly adjacent to each other both will be blended with the white background of the window. You can try putting one shape behind the other instead:

<Canvas>  
      <Path Fill="#FF000000" Data="M 0.00,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
      <Path Fill="#FF260014" Data="M 2.50,0.00 L 7.50,0.00 2.50,10.00 0.00,10.00 " />
      <Canvas.RenderTransform>
           <ScaleTransform ScaleX="{Binding ElementName=slider,Path=Value}" ScaleY="{Binding ElementName=slider,Path=Value}" />
      </Canvas.RenderTransform>
</Canvas>

which should render correctly. You see similar rendering errors in many vector file formats that render primarily to screen, such as SVG.

The other option would be to turn off anti-aliasing but that will make your edges jaggy which may not be what you want (anti-aliasing turned off in the upper half):

alt text

like image 22
Joey Avatar answered Sep 21 '22 15:09

Joey