tkawa
Topic Author
Posts: 6
Joined: 07 Nov 2018, 05:34

[c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

15 Mar 2019, 07:56

I'm using the Path class to draw on a canvas in Noesis and even though I set StrokeThickness = 1, the line shows up 2 pixels wide - it's almost as if the minimum thickness is two. How do I draw a line that is truly 1 pixel thick?

https://stackoverflow.com/questions/287 ... ixel-thick
<Border BorderThickness="1" BorderBrush="Red" Height="20">
    <Canvas>
        <Path SnapsToDevicePixels="True" Stroke="Red" StrokeThickness="1" Data="M 5,5 L 100,5"/>
        <Path SnapsToDevicePixels="True" Stroke="Red" StrokeThickness="1" Data="M 5,10 L 100,10"/>
        <Path SnapsToDevicePixels="True" Stroke="Red" StrokeThickness="1" Data="M 5,15 L 100,15"/>

        <Path Stroke="Red" StrokeThickness="1" Data="M 5,25 L 100,25"/>
        <Path Stroke="Red" StrokeThickness="1" Data="M 5,30 L 100,30"/>
        <Path Stroke="Red" StrokeThickness="1" Data="M 5,35 L 100,35"/>
    </Canvas>
</Border>
Attachments
thickness.png
thickness.png (2.92 KiB) Viewed 57 times

Tags:
 
stonstad
Posts: 54
Joined: 06 Jun 2016, 18:14

Re: [c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

15 Mar 2019, 12:22

I am very new to Noesis. But I just wanted to throw out a suggestion for something to try. What happens if you turn off PPAA (pixel perfect anti-aliasing) on the view?
 
User avatar
jsantos
Site Admin
Posts: 2350
Joined: 20 Jan 2012, 17:18
Contact:

Re: [c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

16 Mar 2019, 08:28

This is almost for sure related to PPAA (our cheap antialiasing emulation). If this is the reason, there are two solutions:

You can disable PPAA in the NoesisView component and use GPU MSAA. This will probably give you overall better quality but probably less performance.

Disable, selectively PPAA on those elements you know they don't need it using the noesis:Element.PPAAMode property. For example:
<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:noesis="clr-namespace:NoesisGUIExtensions"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    Background="White">

  <Grid x:Name="_LayoutRoot">
    <Grid.RowDefinitions>
      <RowDefinition Height="1*" />
      <RowDefinition Height="8*" />
      <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="1*" />
      <ColumnDefinition Width="8*" />
      <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>

      <Grid Width="600" Height="480" Grid.Row="1" Grid.Column="1" UseLayoutRounding="True" noesis:Element.PPAAMode="Disabled">
 
tkawa
Topic Author
Posts: 6
Joined: 07 Nov 2018, 05:34

Re: [c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

18 Mar 2019, 07:19

Thanks for the reply.

I've tried setting
UseLayoutRounding="True" noesis:Element.PPAAMode="Disabled"
on the Window, the Grid, the Canvas, and the Path.
But, UseLayoutRounding and PPAAMode doesn't seem to have same effect with SnapsToDevicePixels.
This behavior is same in WPF.
<Grid Background="White">
    <StackPanel Orientation="Horizontal">
        <Border BorderThickness="1" BorderBrush="Red" Width="100" >
            <Canvas SnapsToDevicePixels="True" >
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,0 L 100,100"       />
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,50 L 100,50"    />
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,100 L 100,0" />
            </Canvas>
        </Border>
        <Border BorderThickness="1" BorderBrush="Blue" Width="100" >
            <Canvas UseLayoutRounding="True" >
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,0 L 100,100"       />
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,50 L 100,50"    />
                <Path Stroke="Red" StrokeThickness="1" Data="M 0,100 L 100,0" />
            </Canvas>
        </Border>
    </StackPanel>
</Grid>
It may not be easy to see, but width of path is not changed from 2px when set UseLayoutRounding=True.
WPF image ↓
Attachments
thickness2.png
thickness2.png (2.03 KiB) Viewed 27 times
 
nikobarli
Posts: 149
Joined: 26 Apr 2017, 06:23

Re: [c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

18 Mar 2019, 08:45

Hi, I think the problem is with the anti-aliasing. Our integration layer (which is also used by tkawa) is using MSAA (PPAA is disabled) for anti-aliasing and it caused the problem that thin lines appear to be blurred. Disabling MSAA fixed the problem, but at the cost of anti-aliasing in other parts.

Using PPAA and disabling it in parts that we need crisp rendering may solve the problem, but overall PPAA seems slower and not as pretty as MSAA.

Do you have a better recommendation ?
 
User avatar
jsantos
Site Admin
Posts: 2350
Joined: 20 Jan 2012, 17:18
Contact:

Re: [c++]How do you draw a line on a canvas in Noesis that is 1 pixel thick

18 Mar 2019, 20:44

What is happening is that the stroked line needs to be displaced by half-width to properly align with the pixels. Something like this is working fine in both Noesis and Blend:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  UseLayoutRounding="True" Background="White">
    <Border BorderThickness="1" BorderBrush="Black" Height="20">
        <Canvas>
            <Path Stroke="Red" StrokeThickness="1" Data="M 5,5.5 L 100,5.5"/>
            <Path Stroke="Red" StrokeThickness="1" Data="M 5,10.5 L 100,10.5"/>
            <Path Stroke="Red" StrokeThickness="1" Data="M 5,15.5 L 100,15.5"/>
        </Canvas>
    </Border>
</Grid>
Note that in Noesis, SnapsToDevicePixels is not implemented.

Who is online

Users browsing this forum: No registered users and 4 guests