Oaz / AvaloniaUI.PrintToPDF

Create PDF documents from Avalonia UI visuals
MIT License
94 stars 7 forks source link

Wrong result when use viewbox or PanAndZoom #1

Open Makstvell opened 2 years ago

Makstvell commented 2 years ago

When I use contain ViewBox some text disappears in pdf.

Program 1

PDF image

Oaz commented 2 years ago

Do you have some code to reproduce the issue?

Makstvell commented 2 years ago
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        x:Class="Client_Application.Views.PrintGraph"
        Title="PrintGraph"
        xmlns:agc="clr-namespace:AvaloniaGraphControl;assembly=AvaloniaGraphControl"
        xmlns:local="using:Client_Application.Models"
        xmlns:paz="using:Avalonia.Controls.PanAndZoom"
        >
    <StackPanel>

        <paz:ZoomBorder Name="ZoomBorder" Stretch="None" ZoomSpeed="1.2"
                        ClipToBounds="True" Focusable="True"
                        VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="700">

            <agc:GraphPanel  Graph="{Binding MyGraph}" LayoutMethod="SugiyamaScheme">
                <agc:GraphPanel.DataTemplates>
                    <DataTemplate DataType="{x:Type local:StandardItemRel}">
                        <agc:TextSticker Text="{Binding Name}" Shape="{Binding Shape}"
                                         Background="{Binding Background}"
                                         BorderForeground="{Binding BorderColor}"  FontSize="{Binding TextSize}" TextForeground="{Binding TextColor}" FontWeight="{Binding FontWeight}"
                                         Padding="{Binding Thick}"/>
                    </DataTemplate>
                </agc:GraphPanel.DataTemplates>
            </agc:GraphPanel>

    </paz:ZoomBorder>

    <Button Content="Save" Click="SavePDF" ></Button>

    </StackPanel>
</Window>
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using AvaloniaGraphControl;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Media;
using Avalonia.Rendering;
using Avalonia.Skia;
using Avalonia.Skia.Helpers;
using Avalonia.VisualTree;
using System.IO;

namespace Client_Application.Views
{
    public partial class PrintGraph : Window
    {
        public PrintGraph()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            AvaloniaXamlLoader.Load(this);

        }

        public async void SavePDF(object sender , RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.InitialFileName = "graph.pdf";

            var res = await dlg.ShowAsync(this);

            string? path = res;

            if (path != "" && path != null) {

                AvaloniaUI.PrintToPDF.Print.ToFile(path,this);

            }

            this.Close();
        }

    }
}
Makstvell commented 2 years ago

If i replace paz:ZoomBorder to viewbox result will the same.

Makstvell commented 2 years ago

I think it is can be a way to solve the problem. The logic of the program. If I click to print button

image

I open a new window with this start form. image

Next I use PanZoom or ViewBox to change my graph length and height.

image

Then I click to save button and create a pdf file.

Result:

image

Oaz commented 2 years ago

That will be difficult to reproduce on my side without a fully executable project but, in this case, maybe we do not need it.

Actually the execution of AvaloniaUI.PrintToPDF.Print.ToFile(path,this) is quite simple since Avalonia 0.10 (it used to be tricky in the previous versions)

I suggest that, in your code, you replace AvaloniaUI.PrintToPDF.Print.ToFile(path,this) by the following code :

using var doc = SKDocument.CreatePdf(path);
var page = doc.BeginPage((float)Width, (float)Height);
using var context = new DrawingContext(DrawingContextHelper.WrapSkiaCanvas(page, SkiaPlatform.DefaultDpi));
ImmediateRenderer.Render(this, context);
doc.EndPage();
doc.Close();

You will just need to reference SkiaSharp in your project because that's where the real pdf work is done. At this point, you no longer need AvaloniaUI.PrintToPdf because its other features are only used when you need to print parts of a window.

Makstvell commented 2 years ago

Ok, thank you for your reply.