Incorrect borders drawn for non-uniform border thickness
tomlm opened this issue · 3 comments
Describe the bug
When applying a non-uniform border thickness the layout of the content vs the layout of the strokes is off by 1 or 2 pixels
This is applying a 1 thickness border to a 8x8 rectangle. You will see that the vertical layout of the rectangle moves up and down more than the thickness of the stroke, and that the stroke has gaps between it and the rectangle.
Sometimes the stroke aligns with the rectangle, sometimes not
When the layout is horizontal then the mistakes on the strokes happen on the vertical borders
When the layout is vertical then the mistakes happen on the horizontal borders.
To Reproduce
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Horizontal">
<Border BorderThickness="0 0 0 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 0 1 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 0 1 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 1 0 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 1 0 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 1 1 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="0 1 1 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 0 0 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 0 0 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 0 1 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 0 1 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 1 0 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 1 0 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 1 1 0" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
<Border BorderThickness="1 1 1 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
</StackPanel>
Expected behavior
The border to be aligned with the content
The border to not have gaps between it and the content
NOTES
I discovered by trial and error that this bug only occurs when being the controls are in a stackpanel together.
If I wrap each border in its own stack panel like this:
<StackPanel>
<Border BorderThickness="1 1 1 1" Margin="2" BorderBrush="Blue">
<Rectangle Fill="AntiqueWhite" Width="8" Height="8"/>
</Border>
</StackPanel>
<StackPanel>
<Border>
...
Then it correctly renders all of the strokes with no errors.
Avalonia version
11.2.1
OS
Windows
Additional context
Related Issue
Consolonia jinek/Consolonia#200 is blocked on the resolution of this bug.
I imagine this is by design as I get similar results with WPF with the gaps. BorderThickness
is a property that participates in layout, therefore you will have borders that are 8, 9, and 10px in height/width (with the 8x8 child rectangle inside). Any edge with a 0px or 1px thickness will necessarily shift the layout differently. There's some more complications with the StackPanel
adjusting all of the DesiredSize
height's to 10px (the tallest on the line in horizontal alignment). I removed the fixed 2px Margin
which I assumed was for item separation and not for making the layout size of each item consistent.
Instead, I suggest you cover up the deficits with Padding
(or Margin
). See the example below:
<Window.Styles>
<Style Selector="Rectangle">
<Setter Property="Width" Value="8" />
<Setter Property="Height" Value="8" />
<Setter Property="Fill" Value="AntiqueWhite" />
</Style>
<Style Selector="StackPanel > Border">
<Setter Property="BorderBrush" Value="Blue" />
</Style>
</Window.Styles>
<Viewbox RenderOptions.EdgeMode="Aliased">
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Top"
Orientation="Horizontal">
<Border Padding="1,1,1,0" BorderThickness="0,0,0,1">
<Rectangle />
</Border>
<Border Padding="1,1,0,1" BorderThickness="0,0,1,0">
<Rectangle />
</Border>
<Border Padding="1,1,0,0" BorderThickness="0,0,1,1">
<Rectangle />
</Border>
<Border Padding="1,0,1,1" BorderThickness="0,1,0,0">
<Rectangle />
</Border>
<Border Padding="1,0,1,0" BorderThickness="0,1,0,1">
<Rectangle />
</Border>
<Border Padding="1,0,0,1" BorderThickness="0,1,1,0">
<Rectangle />
</Border>
<Border Padding="1,0,0,0" BorderThickness="0,1,1,1">
<Rectangle />
</Border>
<Border Padding="0,1,1,1" BorderThickness="1,0,0,0">
<Rectangle />
</Border>
<Border Padding="0,1,1,0" BorderThickness="1,0,0,1">
<Rectangle />
</Border>
<Border Padding="0,1,0,1" BorderThickness="1,0,1,0">
<Rectangle />
</Border>
<Border Padding="0,1,0,0" BorderThickness="1,0,1,1">
<Rectangle />
</Border>
<Border Padding="0,0,1,1" BorderThickness="1,1,0,0">
<Rectangle />
</Border>
<Border Padding="0,0,1,0" BorderThickness="1,1,0,1">
<Rectangle />
</Border>
<Border Padding="0,0,0,1" BorderThickness="1,1,1,0">
<Rectangle />
</Border>
<Border Padding="0,0,0,0" BorderThickness="1,1,1,1">
<Rectangle />
</Border>
</StackPanel>
</Viewbox>
Please leave the issue open for a maintainer to decide.
Thanks, that indeed helps immensely. It feels wrong to have the gaps between the edge of the rectangle and the strokes, but at with padding I do indeed have a workaround which makes relative sense.
Are you using LayoutRounding probably or SnapToDevicePixels?