diff --git a/QuestPDF.Previewer.Examples/Program.cs b/QuestPDF.Previewer.Examples/Program.cs index 8a42c86..7d57716 100644 --- a/QuestPDF.Previewer.Examples/Program.cs +++ b/QuestPDF.Previewer.Examples/Program.cs @@ -1,4 +1,5 @@ -using Avalonia.Media; +using System.Net.Http.Headers; +using Avalonia.Media; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; @@ -7,11 +8,13 @@ using QuestPDF.ReportSample; using QuestPDF.ReportSample.Layouts; using Colors = QuestPDF.Helpers.Colors; -var model = DataSource.GetReport(); -var report = new StandardReport(model); -report.ShowInPreviewer(); +ImagePlaceholder.Solid = true; -return; +// var model = DataSource.GetReport(); +// var report = new StandardReport(model); +// report.ShowInPreviewer().Wait(); +// +// return; Document .Create(container => @@ -48,6 +51,16 @@ Document }); x.Item().Text("Modify this line and the preview should show your changes instantly."); + + // for testing exception handling + // try + // { + // throw new ArgumentException("This file does not exists... peace.png"); + // } + // catch (Exception e) + // { + // throw new FileNotFoundException("This is the top exception!", e); + // } }); page.Footer() @@ -63,7 +76,6 @@ Document { page.Size(PageSizes.A4); page.Margin(2, Unit.Centimetre); - page.PageColor(Colors.Red.Medium); page.DefaultTextStyle(x => x.FontSize(20)); page.Content() @@ -77,4 +89,4 @@ Document }); }); }) - .ShowInPreviewer(); \ No newline at end of file + .ShowInPreviewer().Wait(); \ No newline at end of file diff --git a/QuestPDF.Previewer/CommunicationService.cs b/QuestPDF.Previewer/CommunicationService.cs new file mode 100644 index 0000000..2a25863 --- /dev/null +++ b/QuestPDF.Previewer/CommunicationService.cs @@ -0,0 +1,65 @@ +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using SkiaSharp; + +namespace QuestPDF.Previewer; + +class CommunicationService +{ + public static CommunicationService Instance { get; } = new (); + + public event Action> OnDocumentRefreshed; + + private WebApplication? Application { get; set; } + + private readonly JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNameCaseInsensitive = true + }; + + private CommunicationService() + { + + } + + public Task Start(int port) + { + var builder = WebApplication.CreateBuilder(); + builder.Services.AddLogging(x => x.ClearProviders()); + Application = builder.Build(); + + Application.MapGet("ping", () => Results.Ok()); + Application.MapGet("version", () => Results.Ok(GetType().Assembly.GetName().Version)); + Application.MapPost("update/preview", HandleUpdatePreview); + + return Application.RunAsync($"http://localhost:{port}/"); + } + + public async Task Stop() + { + await Application.StopAsync(); + await Application.DisposeAsync(); + } + + private async Task HandleUpdatePreview(HttpRequest request) + { + var command = JsonSerializer.Deserialize(request.Form["command"], JsonSerializerOptions); + + var pages = command + .Pages + .Select(page => + { + using var stream = request.Form.Files[page.Id].OpenReadStream(); + var picture = SKPicture.Deserialize(stream); + + return new PreviewPage(picture, page.Width, page.Height); + }) + .ToList(); + + OnDocumentRefreshed(pages); + return Results.Ok(); + } +} \ No newline at end of file diff --git a/QuestPDF.Previewer/Helpers.cs b/QuestPDF.Previewer/Helpers.cs new file mode 100644 index 0000000..fe0a809 --- /dev/null +++ b/QuestPDF.Previewer/Helpers.cs @@ -0,0 +1,23 @@ +using SkiaSharp; + +namespace QuestPDF.Previewer; + +class Helpers +{ + public static void GeneratePdfFromDocumentSnapshots(string filePath, ICollection pages) + { + using var stream = File.Create(filePath); + + var document = SKDocument.CreatePdf(stream); + + foreach (var page in pages) + { + using var canvas = document.BeginPage(page.Width, page.Height); + canvas.DrawPicture(page.Picture); + document.EndPage(); + canvas.Dispose(); + } + + document.Close(); + } +} \ No newline at end of file diff --git a/QuestPDF.Previewer/InteractiveCanvas.cs b/QuestPDF.Previewer/InteractiveCanvas.cs new file mode 100644 index 0000000..80db1cb --- /dev/null +++ b/QuestPDF.Previewer/InteractiveCanvas.cs @@ -0,0 +1,202 @@ +using Avalonia; +using Avalonia.Platform; +using Avalonia.Rendering.SceneGraph; +using Avalonia.Skia; +using SkiaSharp; + +namespace QuestPDF.Previewer; + +class InteractiveCanvas : ICustomDrawOperation +{ + public Rect Bounds { get; set; } + public ICollection Pages { get; set; } + + private float Width => (float)Bounds.Width; + private float Height => (float)Bounds.Height; + + public float Scale { get; private set; } = 1; + public float TranslateX { get; set; } + public float TranslateY { get; set; } + + private const float MinScale = 0.1f; + private const float MaxScale = 10f; + + private const float PageSpacing = 25f; + private const float SafeZone = 25f; + + public float TotalPagesHeight => Pages.Sum(x => x.Height) + (Pages.Count - 1) * PageSpacing; + public float TotalHeight => TotalPagesHeight + SafeZone * 2 / Scale; + public float MaxWidth => Pages.Any() ? Pages.Max(x => x.Width) : 0; + + public float MaxTranslateY => TotalHeight - Height / Scale; + + public float ScrollPercentY + { + get + { + return TranslateY / MaxTranslateY; + } + set + { + TranslateY = value * MaxTranslateY; + } + } + + public float ScrollViewportSizeY + { + get + { + var viewPortSize = Height / Scale / TotalHeight; + return Math.Clamp(viewPortSize, 0, 1); + } + } + + #region transformations + + private void LimitScale() + { + Scale = Math.Max(Scale, MinScale); + Scale = Math.Min(Scale, MaxScale); + } + + private void LimitTranslate() + { + if (TotalPagesHeight > Height / Scale) + { + TranslateY = Math.Min(TranslateY, MaxTranslateY); + TranslateY = Math.Max(TranslateY, 0); + } + else + { + TranslateY = (TotalPagesHeight - Height / Scale) / 2; + } + + if (Width / Scale < MaxWidth) + { + var maxTranslateX = (Width / 2 - SafeZone) / Scale - MaxWidth / 2; + + TranslateX = Math.Min(TranslateX, -maxTranslateX); + TranslateX = Math.Max(TranslateX, maxTranslateX); + } + else + { + TranslateX = 0; + } + } + + public void TranslateWithCurrentScale(float x, float y) + { + TranslateX += x / Scale; + TranslateY += y / Scale; + + LimitTranslate(); + } + + public void ZoomToPoint(float x, float y, float factor) + { + var oldScale = Scale; + Scale *= factor; + + LimitScale(); + + TranslateX -= x / Scale - x / oldScale; + TranslateY -= y / Scale - y / oldScale; + + LimitTranslate(); + } + + #endregion + + #region rendering + + public void Render(IDrawingContextImpl context) + { + if (Pages.Count <= 0) + return; + + LimitScale(); + LimitTranslate(); + + var canvas = (context as ISkiaDrawingContextImpl)?.SkCanvas; + + if (canvas == null) + throw new InvalidOperationException($"Context needs to be ISkiaDrawingContextImpl but got {nameof(context)}"); + + var originalMatrix = canvas.TotalMatrix; + + canvas.Translate(Width / 2, 0); + + canvas.Scale(Scale); + canvas.Translate(TranslateX, -TranslateY + SafeZone / Scale); + + foreach (var page in Pages) + { + canvas.Translate(-page.Width / 2f, 0); + DrawBlankPage(canvas, page.Width, page.Height); + canvas.DrawPicture(page.Picture); + canvas.Translate(page.Width / 2f, page.Height + PageSpacing); + } + + canvas.SetMatrix(originalMatrix); + DrawInnerGradient(canvas); + } + + public void Dispose() { } + public bool Equals(ICustomDrawOperation? other) => false; + public bool HitTest(Point p) => true; + + #endregion + + #region blank page + + private static SKPaint BlankPagePaint = new SKPaint + { + Color = SKColors.White + }; + + private static SKPaint BlankPageShadowPaint = new SKPaint + { + ImageFilter = SKImageFilter.CreateBlendMode( + SKBlendMode.Overlay, + SKImageFilter.CreateDropShadowOnly(0, 6, 6, 6, SKColors.Black.WithAlpha(64)), + SKImageFilter.CreateDropShadowOnly(0, 10, 14, 14, SKColors.Black.WithAlpha(32))) + }; + + private void DrawBlankPage(SKCanvas canvas, float width, float height) + { + canvas.DrawRect(0, 0, width, height, BlankPageShadowPaint); + canvas.DrawRect(0, 0, width, height, BlankPagePaint); + } + + #endregion + + #region inner viewport gradient + + private const int InnerGradientSize = (int)SafeZone; + private static readonly SKColor InnerGradientColor = SKColor.Parse("#666"); + + private void DrawInnerGradient(SKCanvas canvas) + { + // gamma correction + var colors = Enumerable + .Range(0, InnerGradientSize) + .Select(x => 1f - x / (float) InnerGradientSize) + .Select(x => Math.Pow(x, 2f)) + .Select(x => (byte)(x * 255)) + .Select(x => InnerGradientColor.WithAlpha(x)) + .ToArray(); + + using var fogPaint = new SKPaint + { + Shader = SKShader.CreateLinearGradient( + new SKPoint(0, 0), + new SKPoint(0, InnerGradientSize), + colors, + SKShaderTileMode.Clamp) + }; + + canvas.DrawRect(0, 0, Width, InnerGradientSize, fogPaint); + } + + #endregion +} diff --git a/QuestPDF.Previewer/PreviewerApp.axaml b/QuestPDF.Previewer/PreviewerApp.axaml new file mode 100644 index 0000000..725db69 --- /dev/null +++ b/QuestPDF.Previewer/PreviewerApp.axaml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/QuestPDF.Previewer/PreviewerApp.axaml.cs b/QuestPDF.Previewer/PreviewerApp.axaml.cs new file mode 100644 index 0000000..526d0ff --- /dev/null +++ b/QuestPDF.Previewer/PreviewerApp.axaml.cs @@ -0,0 +1,27 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace QuestPDF.Previewer +{ + internal class PreviewerApp : Application + { + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new PreviewerWindow() + { + DataContext = new PreviewerWindowViewModel() + }; + } + + base.OnFrameworkInitializationCompleted(); + } + } +} diff --git a/QuestPDF.Previewer/PreviewerCanvas.cs b/QuestPDF.Previewer/PreviewerCanvas.cs new file mode 100644 index 0000000..5b25fdc --- /dev/null +++ b/QuestPDF.Previewer/PreviewerCanvas.cs @@ -0,0 +1,6 @@ +using SkiaSharp; + +namespace QuestPDF.Previewer +{ + record PreviewPage(SKPicture Picture, float Width, float Height); +} diff --git a/QuestPDF.Previewer/PreviewerControl.cs b/QuestPDF.Previewer/PreviewerControl.cs new file mode 100644 index 0000000..b433748 --- /dev/null +++ b/QuestPDF.Previewer/PreviewerControl.cs @@ -0,0 +1,118 @@ +using System.Collections.ObjectModel; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Media; + +namespace QuestPDF.Previewer +{ + class PreviewerControl : Control + { + private InteractiveCanvas InteractiveCanvas { get; set; } = new (); + + public static readonly StyledProperty> PagesProperty = + AvaloniaProperty.Register>(nameof(Pages)); + + public ObservableCollection? Pages + { + get => GetValue(PagesProperty); + set => SetValue(PagesProperty, value); + } + + public static readonly StyledProperty CurrentScrollProperty = AvaloniaProperty.Register(nameof(CurrentScroll)); + + public float CurrentScroll + { + get => GetValue(CurrentScrollProperty); + set => SetValue(CurrentScrollProperty, value); + } + + public static readonly StyledProperty ScrollViewportSizeProperty = AvaloniaProperty.Register(nameof(ScrollViewportSize)); + + public float ScrollViewportSize + { + get => GetValue(ScrollViewportSizeProperty); + set => SetValue(ScrollViewportSizeProperty, value); + } + + public PreviewerControl() + { + PagesProperty.Changed.Subscribe(x => + { + InteractiveCanvas.Pages = x.NewValue.Value; + InvalidateVisual(); + }); + + CurrentScrollProperty.Changed.Subscribe(x => + { + InteractiveCanvas.ScrollPercentY = x.NewValue.Value; + InvalidateVisual(); + }); + + ClipToBounds = true; + } + + protected override void OnPointerWheelChanged(PointerWheelEventArgs e) + { + base.OnPointerWheelChanged(e); + + if ((e.KeyModifiers & KeyModifiers.Control) != 0) + { + var scaleFactor = 1 + e.Delta.Y / 10f; + var point = new Point(Bounds.Center.X, Bounds.Top) - e.GetPosition(this); + + InteractiveCanvas.ZoomToPoint((float)point.X, -(float)point.Y, (float)scaleFactor); + } + + if (e.KeyModifiers == KeyModifiers.None) + { + var translation = (float)e.Delta.Y * 25; + InteractiveCanvas.TranslateWithCurrentScale(0, -translation); + } + + InvalidateVisual(); + } + + private bool IsMousePressed { get; set; } + private Vector MousePosition { get; set; } + + protected override void OnPointerMoved(PointerEventArgs e) + { + base.OnPointerMoved(e); + + if (IsMousePressed) + { + var currentPosition = e.GetPosition(this); + var translation = currentPosition - MousePosition; + InteractiveCanvas.TranslateWithCurrentScale((float)translation.X, -(float)translation.Y); + + InvalidateVisual(); + } + + MousePosition = e.GetPosition(this); + } + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + base.OnPointerPressed(e); + IsMousePressed = true; + } + + protected override void OnPointerReleased(PointerReleasedEventArgs e) + { + base.OnPointerReleased(e); + IsMousePressed = false; + } + + public override void Render(DrawingContext context) + { + CurrentScroll = InteractiveCanvas.ScrollPercentY; + ScrollViewportSize = InteractiveCanvas.ScrollViewportSizeY; + + InteractiveCanvas.Bounds = new Rect(0, 0, Bounds.Width, Bounds.Height); + + context.Custom(InteractiveCanvas); + base.Render(context); + } + } +} diff --git a/QuestPDF.Previewer/PreviewerRefreshCommand.cs b/QuestPDF.Previewer/PreviewerRefreshCommand.cs new file mode 100644 index 0000000..3554585 --- /dev/null +++ b/QuestPDF.Previewer/PreviewerRefreshCommand.cs @@ -0,0 +1,18 @@ +using SkiaSharp; + +namespace QuestPDF.Previewer; + +internal class DocumentSnapshot +{ + public ICollection Pages { get; set; } + + public class PageSnapshot + { + public string Id { get; set; } + + public float Width { get; set; } + public float Height { get; set; } + + public SKPicture Picture { get; set; } + } +} diff --git a/QuestPDF.Previewer/PreviewerWindow.axaml b/QuestPDF.Previewer/PreviewerWindow.axaml new file mode 100644 index 0000000..3038e5e --- /dev/null +++ b/QuestPDF.Previewer/PreviewerWindow.axaml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/QuestPDF.Previewer/PreviewerWindow.axaml.cs b/QuestPDF.Previewer/PreviewerWindow.axaml.cs new file mode 100644 index 0000000..2eb5262 --- /dev/null +++ b/QuestPDF.Previewer/PreviewerWindow.axaml.cs @@ -0,0 +1,23 @@ +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace QuestPDF.Previewer +{ + class PreviewerWindow : Window + { + public PreviewerWindow() + { + InitializeComponent(); + } + + protected override void OnClosed(EventArgs e) + { + + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} diff --git a/QuestPDF.Previewer/PreviewerWindowViewModel.cs b/QuestPDF.Previewer/PreviewerWindowViewModel.cs new file mode 100644 index 0000000..4246ed5 --- /dev/null +++ b/QuestPDF.Previewer/PreviewerWindowViewModel.cs @@ -0,0 +1,89 @@ +using System.Collections.ObjectModel; +using System.Diagnostics; +using ReactiveUI; +using Unit = System.Reactive.Unit; +using Avalonia.Threading; + +namespace QuestPDF.Previewer +{ + internal class PreviewerWindowViewModel : ReactiveObject + { + private ObservableCollection _pages = new(); + public ObservableCollection Pages + { + get => _pages; + set => this.RaiseAndSetIfChanged(ref _pages, value); + } + + private float _currentScroll; + public float CurrentScroll + { + get => _currentScroll; + set => this.RaiseAndSetIfChanged(ref _currentScroll, value); + } + + private float _scrollViewportSize; + public float ScrollViewportSize + { + get => _scrollViewportSize; + set + { + this.RaiseAndSetIfChanged(ref _scrollViewportSize, value); + VerticalScrollbarVisible = value < 1; + } + } + + private bool _verticalScrollbarVisible; + public bool VerticalScrollbarVisible + { + get => _verticalScrollbarVisible; + private set => Dispatcher.UIThread.Post(() => this.RaiseAndSetIfChanged(ref _verticalScrollbarVisible, value)); + } + + public ReactiveCommand ShowPdfCommand { get; } + public ReactiveCommand ShowDocumentationCommand { get; } + public ReactiveCommand SponsorProjectCommand { get; } + + public PreviewerWindowViewModel() + { + CommunicationService.Instance.OnDocumentRefreshed += HandleUpdatePreview; + + ShowPdfCommand = ReactiveCommand.Create(ShowPdf); + ShowDocumentationCommand = ReactiveCommand.Create(() => OpenLink("https://www.questpdf.com/documentation/api-reference.html")); + SponsorProjectCommand = ReactiveCommand.Create(() => OpenLink("https://github.com/sponsors/QuestPDF")); + } + + private void ShowPdf() + { + var filePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.pdf"); + Helpers.GeneratePdfFromDocumentSnapshots(filePath, Pages); + + OpenLink(filePath); + } + + private void OpenLink(string path) + { + var openBrowserProcess = new Process + { + StartInfo = new() + { + UseShellExecute = true, + FileName = path + } + }; + + openBrowserProcess.Start(); + } + + private void HandleUpdatePreview(ICollection pages) + { + var oldPages = Pages; + + Pages.Clear(); + Pages = new ObservableCollection(pages); + + foreach (var page in oldPages) + page.Picture.Dispose(); + } + } +} diff --git a/QuestPDF.Previewer/Program.cs b/QuestPDF.Previewer/Program.cs new file mode 100644 index 0000000..71c7e96 --- /dev/null +++ b/QuestPDF.Previewer/Program.cs @@ -0,0 +1,38 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.ReactiveUI; +using QuestPDF.Previewer; + +var applicationPort = GetCommunicationPort(); +CommunicationService.Instance.Start(applicationPort); + +if(Application.Current?.ApplicationLifetime is ClassicDesktopStyleApplicationLifetime desktop) +{ + desktop.MainWindow = new PreviewerWindow() + { + DataContext = new PreviewerWindowViewModel() + }; + + desktop.MainWindow.Show(); + desktop.Start(Array.Empty()); + + return; +} + +AppBuilder + .Configure(() => new PreviewerApp()) + .UsePlatformDetect() + .UseReactiveUI() + .StartWithClassicDesktopLifetime(Array.Empty()); + +static int GetCommunicationPort() +{ + const int defaultApplicationPort = 12500; + + var arguments = Environment.GetCommandLineArgs(); + + if (arguments.Length < 2) + return defaultApplicationPort; + + return int.TryParse(arguments[1], out var port) ? port : defaultApplicationPort; +} \ No newline at end of file diff --git a/QuestPDF.Previewer/QuestPDF.Previewer.csproj b/QuestPDF.Previewer/QuestPDF.Previewer.csproj new file mode 100644 index 0000000..0b0748c --- /dev/null +++ b/QuestPDF.Previewer/QuestPDF.Previewer.csproj @@ -0,0 +1,31 @@ + + + + exe + net6.0 + enable + enable + + true + QuestPDF.Previewer + 2022.4.0 + true + questpdf-previewer + + + + + + + + + + + + + + + + + + diff --git a/QuestPDF.Previewer/Resources/Logo.png b/QuestPDF.Previewer/Resources/Logo.png new file mode 100644 index 0000000..a0f1a19 Binary files /dev/null and b/QuestPDF.Previewer/Resources/Logo.png differ diff --git a/QuestPDF.Previewer/readme.md b/QuestPDF.Previewer/readme.md new file mode 100644 index 0000000..79ed13e --- /dev/null +++ b/QuestPDF.Previewer/readme.md @@ -0,0 +1,23 @@ +Install nuget locally (in directory where nupkg file is located) + +``` +dotnet tool install --global --add-source . QuestPDF.Previewer --global +``` + +Run on default port + +``` +questpdf-previewer +``` + +Run on custom port + +``` +questpdf-previewer 12500 +``` + +Remove nuget locally + +``` +dotnet tool uninstall QuestPDF.Previewer --global +``` \ No newline at end of file diff --git a/QuestPDF.sln b/QuestPDF.sln index 87eff4d..cf35650 100644 --- a/QuestPDF.sln +++ b/QuestPDF.sln @@ -8,8 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.UnitTests", "Quest EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Examples", "QuestPDF.Examples\QuestPDF.Examples.csproj", "{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Previewer", "QuestPDF.Previewer\QuestPDF.Previewer.csproj", "{D63255E7-7043-4AD4-A4C9-7ACFEDBE8225}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Previewer.Examples", "QuestPDF.Previewer.Examples\QuestPDF.Previewer.Examples.csproj", "{CA413A39-038F-4A9F-B56F-0E5413B6B158}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration", "Configuration", "{73123649-216A-47B4-BFB2-DADF13FBE75D}" @@ -17,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration", "Configurat .editorconfig = .editorconfig EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Previewer", "QuestPDF.Previewer\QuestPDF.Previewer.csproj", "{B2FF6003-3A45-4A78-A85D-B86C7F01D054}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,13 +39,13 @@ Global {8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Debug|Any CPU.Build.0 = Debug|Any CPU {8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.ActiveCfg = Release|Any CPU {8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.Build.0 = Release|Any CPU - {D63255E7-7043-4AD4-A4C9-7ACFEDBE8225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D63255E7-7043-4AD4-A4C9-7ACFEDBE8225}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D63255E7-7043-4AD4-A4C9-7ACFEDBE8225}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D63255E7-7043-4AD4-A4C9-7ACFEDBE8225}.Release|Any CPU.Build.0 = Release|Any CPU {CA413A39-038F-4A9F-B56F-0E5413B6B158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CA413A39-038F-4A9F-B56F-0E5413B6B158}.Debug|Any CPU.Build.0 = Debug|Any CPU {CA413A39-038F-4A9F-B56F-0E5413B6B158}.Release|Any CPU.ActiveCfg = Release|Any CPU {CA413A39-038F-4A9F-B56F-0E5413B6B158}.Release|Any CPU.Build.0 = Release|Any CPU + {B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/QuestPDF/Previewer/ExceptionDocument.cs b/QuestPDF/Previewer/ExceptionDocument.cs index 266a02b..f3f025c 100644 --- a/QuestPDF/Previewer/ExceptionDocument.cs +++ b/QuestPDF/Previewer/ExceptionDocument.cs @@ -81,7 +81,7 @@ namespace QuestPDF.Previewer .Text(text => { - text.DefaultTextStyle(x => x.FontSize(18)); + text.DefaultTextStyle(x => x.FontSize(16)); text.Span(currentException.GetType().Name + ": ").Bold(); text.Span(currentException.Message); diff --git a/QuestPDF/Previewer/PreviewerService.cs b/QuestPDF/Previewer/PreviewerService.cs index e2abe06..123b2b0 100644 --- a/QuestPDF/Previewer/PreviewerService.cs +++ b/QuestPDF/Previewer/PreviewerService.cs @@ -63,7 +63,7 @@ namespace QuestPDF.Previewer StartInfo = new() { UseShellExecute = false, - FileName = "questpdf-test", + FileName = "questpdf-previewer", CreateNoWindow = true } };