-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Describe the bug
VisualBrush shows letterboxing (black bars) when source and destination have identical size
Summary
When using a VisualBrush to paint a sibling visual that has the same layout size as the destination (same parent, same width and height), Stretch="Uniform" still produces letterboxing (empty strips at top/bottom or left/right). The empty area shows the destination control’s background (e.g. black), so we get unwanted black bars even though the source and target are the same size in the visual tree.
Expected behavior
If the brush’s source visual and the control being painted have identical size (same parent, same bounds), then with Stretch="Uniform" the brush content should fill the destination with no letterboxing — effectively a 1:1 mapping.
Actual behavior
Letterboxing appears (e.g. black bars at top and bottom). This suggests that internally the brush uses a different “content size” or coordinate system when drawing, so the source and destination are not treated as the same size even though they are in layout.
Reproduction
Structure (simplified):
- A
Gridcontains two children that both fill the grid (so same size):- Source: A
Grid(orCanvas) namedFrostedBlurSourcewith content (e.g. anImageand other controls). - Destination: A
BordernamedFrostedBlurBorder(same size as the grid) whoseBackgroundis aVisualBrushwithVisual="{Binding #FrostedBlurSource}"andStretch="Uniform".
- Source: A
So in the layout tree, source and destination have the same width, height, and aspect ratio.
Result: The VisualBrush still leaves empty strips (letterboxing) at top/bottom or left/right. Where the brush does not draw, the Border’s background (e.g. Background="Black") is visible, so we see black bars.
Additional observations:
- With
Stretch="Fill"orStretch="UniformToFill", the letterboxing disappears but the content is scaled/misaligned and we see ghosting (double image), as if the brush content and the underlying visual are not aligned. - With
Stretch="None", the brush content does not fill the destination and the effect is largely invisible.
So we have to choose between: correct alignment but letterboxing (Uniform), or no letterboxing but ghosting (Fill/UniformToFill).
Relevant AXAML (minimal repro)
Source and destination are siblings in the same Grid; both fill the grid so they have the same size. The brush uses Stretch="Uniform" and paints the source visual onto the inner Border. Black bars appear at top and bottom.
<Grid x:Name="FrostedBlurGrid" ClipToBounds="True">
<!-- Source: same size as grid -->
<Grid x:Name="FrostedBlurSource">
<Image Source="/Assets/bg_sample.png" Stretch="UniformToFill" />
<!-- optional: more children for testing -->
</Grid>
<!-- Destination: same size as grid; VisualBrush paints FrostedBlurSource -->
<Border x:Name="FrostedBlurBorder" Background="Black">
<Border Opacity="0.5">
<Border.Background>
<VisualBrush Visual="{Binding #FrostedBlurSource}" Stretch="Uniform" />
</Border.Background>
<Border.Effect>
<BlurEffect Radius="10" />
</Border.Effect>
</Border>
</Border>
</Grid>With this layout, FrostedBlurSource and FrostedBlurBorder have identical layout bounds, but the VisualBrush still shows letterboxing (black strips at top/bottom).
Environment
- Avalonia: 11.3.7
- .NET: 8.0
- OS: Windows 10 (10.0.19045)
Possible relation
This may be related to Issue #1614 – Visual Brush doesn't work well with DPI Scaling, where the brush content is reported to be skewed or to use a different scale. Here, even at 100% DPI with source and destination having the same layout size, we still get letterboxing, which suggests the internal size or coordinate system used for the brush content does not match the destination size.
Question
Is there a recommended way to get a true 1:1 mapping (no letterboxing, no scaling) when the source visual and the painted control have the same layout size, or is this a known limitation/bug that is tracked elsewhere?
Thank you.
To Reproduce
- Create a Grid with two children that both fill the grid (so they have the same size):
- Source: A Grid named
FrostedBlurSourcewith any content (e.g. an Image). - Destination: A Border named
FrostedBlurBorderwithBackground="Black", whose inner content uses a VisualBrush:Visual="{Binding #FrostedBlurSource}"andStretch="Uniform".
- Source: A Grid named
- Place that Grid in a window so it gets a non-zero size (e.g. in the main content area).
- Run the app and open the window.
Result: Black bars (letterboxing) appear at the top and bottom of the blurred area, even though FrostedBlurSource and FrostedBlurBorder have identical layout bounds in the same parent.
Expected behavior
No response
Avalonia version
11.3.7
OS
Windows
Additional context
No response