microsoft / Win2D

Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration. It is available to C#, C++ and VB developers writing apps for the Windows Universal Platform (UWP). It utilizes the power of Direct2D, and integrates seamlessly with XAML and CoreWindow.
http://microsoft.github.io/Win2D
Other
1.79k stars 284 forks source link

CanvasVirtualControl visible region not keeping up with parent size #870

Open dumidumi opened 2 years ago

dumidumi commented 2 years ago

Greetings,

I'm trying to use a CanvasVirtualControl. I noticed that when my window is above a certain size, the drawing is truncated. It seems that the visible region bounds are incorrect.

In the example below, the width of the visible region (as determined from the event args) will not go above 1904, even if I extend the window on two monitors. W.r.t. the height, the behavior seems to be similar, but I cannot actually see the truncation on my setup.

The screenshot is from a maximized window on a 2560x1440 screen. The debug output was obtained by using an explicit invalidation via a mouse click, after the window was maximized. The truncation is apparent on the right side of the screen/window. The width of the window is larger than the width of the total invalidated area, which is larger than the width of what is reported as the visible region (which corresponds to the large rounded rectangle).

If I scroll horizontally, new regions will start to be invalidated and drawn, but they will always 'lag behind' the width of the window.

My expectation is that the size of the visible region should be the same as the size of the scroll viewer's viewport, and that the total invalidated area should be at least as large.

Is this a bug or am I missing something?

Thank you.

xaml:

<Window
    x:Class="VirtualCanvasTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:VirtualCanvasTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
    mc:Ignorable="d">
    <ScrollViewer x:Name="scroller" HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto">
        <canvas:CanvasVirtualControl x:Name="canvas" Width="10000" Height="10000"
                                     RegionsInvalidated="OnRegionsInvalidated" Tapped="OnClicked"/>
    </ScrollViewer>
</Window>

cpp:

void MainWindow::OnRegionsInvalidated(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasVirtualControl const& sender,
                                      winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasRegionsInvalidatedEventArgs const& args)
{
    print("Sender actual size:", sender.ActualWidth(), sender.ActualHeight());
    print("Args visible region:", args.VisibleRegion().X, args.VisibleRegion().Y, args.VisibleRegion().Width, args.VisibleRegion().Height);
    print("Window bounds:", Bounds().X, Bounds().Y, Bounds().Width, Bounds().Height);
    print("Scroller actual size:", scroller().ActualWidth(), scroller().ActualHeight());
    print("Scroller extent size:", scroller().ExtentWidth(), scroller().ExtentHeight());
    print("Scroller viewport size:", scroller().ViewportWidth(), scroller().ViewportHeight());
    print("Scroller scrollable size:", scroller().ScrollableWidth(), scroller().ScrollableHeight());
    print("Scroller offsets:", scroller().HorizontalOffset(), scroller().VerticalOffset());

    for (auto&& rect : args.InvalidatedRegions())
    {
        print("Invalidated region:", rect.X, rect.Y, rect.Width, rect.Height);

        auto session{sender.CreateDrawingSession(rect)};
        session.FillRoundedRectangle(rect, 100.0, 100.0, Windows::UI::Color{100, 100, 100});
    }

    print();
}

void MainWindow::OnClicked(winrt::Windows::Foundation::IInspectable const& sender,
                           winrt::Microsoft::UI::Xaml::Input::TappedRoutedEventArgs const& e)
{
    canvas().Invalidate();
}

output:

Sender actual size: 10000 10000 
Args visible region: 0 0 1904 990 
Window bounds: 0 0 2560 1377 
Scroller actual size: 2560 1377 
Scroller extent size: 10000 10000 
Scroller viewport size: 2560 1377 
Scroller scrollable size: 7440 8623 
Scroller offsets: 0 0 
Invalidated region: 0 0 2048 1512 
Invalidated region: 2048 0 472 1512 

screenshot: Capture

getrou commented 1 year ago

This all looks right to my eyes. Thinking about how to debug this, I wonder, what is your DPI setting on your monitor? Does changing the scaling factor to 100% make this problem go away?