diff --git a/src/PdfiumViewer.Demo/FodyWeavers.xml b/src/PdfiumViewer.Demo/FodyWeavers.xml deleted file mode 100644 index d5abfed..0000000 --- a/src/PdfiumViewer.Demo/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/PdfiumViewer.Demo/FodyWeavers.xsd b/src/PdfiumViewer.Demo/FodyWeavers.xsd deleted file mode 100644 index 221aeb8..0000000 --- a/src/PdfiumViewer.Demo/FodyWeavers.xsd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - Used to control if the On_PropertyName_Changed feature is enabled. - - - - - Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. - - - - - Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. - - - - - Used to control if equality checks should use the Equals method resolved from the base class. - - - - - Used to control if equality checks should use the static Equals method resolved from the base class. - - - - - Used to turn off build warnings from this weaver. - - - - - Used to turn off build warnings about mismatched On_PropertyName_Changed methods. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/PdfiumViewer.Demo/PdfiumViewer.Demo.csproj b/src/PdfiumViewer.Demo/PdfiumViewer.Demo.csproj index 66f7605..8891292 100644 --- a/src/PdfiumViewer.Demo/PdfiumViewer.Demo.csproj +++ b/src/PdfiumViewer.Demo/PdfiumViewer.Demo.csproj @@ -1,8 +1,8 @@ - + WinExe - net5.0-windows + net8.0-windows true icon.ico 1.0.5 @@ -47,8 +47,7 @@ - - + diff --git a/src/PdfiumViewer.Demo/Properties/Annotations.cs b/src/PdfiumViewer.Demo/Properties/Annotations.cs index b4446a3..2381a35 100644 --- a/src/PdfiumViewer.Demo/Properties/Annotations.cs +++ b/src/PdfiumViewer.Demo/Properties/Annotations.cs @@ -122,6 +122,9 @@ public sealed class ItemCanBeNullAttribute : Attribute { } AttributeTargets.Property | AttributeTargets.Delegate)] public sealed class StringFormatMethodAttribute : Attribute { + /// + /// Set the format string of an annotated method. + /// /// /// Specifies which parameter of an annotated method should be treated as the format string /// diff --git a/src/PdfiumViewer/Core/NativeMethods.Pdfium.cs b/src/PdfiumViewer/Core/NativeMethods.Pdfium.cs index 09bf130..b5982f8 100644 --- a/src/PdfiumViewer/Core/NativeMethods.Pdfium.cs +++ b/src/PdfiumViewer/Core/NativeMethods.Pdfium.cs @@ -16,19 +16,19 @@ partial class NativeMethods // threads, even when there are multiple AppDomain's in play. private static readonly string LockString = string.Intern("e362349b-001d-4cb2-bf55-a71606a3e36f"); - public static void FPDF_AddRef() + public static void FPDF_InitLibrary() { lock (LockString) { - Imports.FPDF_AddRef(); + Imports.FPDF_InitLibrary(); } } - public static void FPDF_Release() + public static void FPDF_DestroyLibrary() { lock (LockString) { - Imports.FPDF_Release(); + Imports.FPDF_DestroyLibrary(); } } @@ -589,11 +589,22 @@ private static int FPDF_SaveBlock(IntPtr fileWrite, IntPtr data, uint size) private static class Imports { - [DllImport("pdfium.dll")] - public static extern void FPDF_AddRef(); - - [DllImport("pdfium.dll")] - public static extern void FPDF_Release(); + // LibraryImport is not supported by Blazor WebAssembly +#if NET7_0_OR_GREATER && FALSE + [LibraryImport("pdfium")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FPDF_InitLibrary(); + + [LibraryImport("pdfium")] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + public static partial void FPDF_DestroyLibrary(); +#else + [DllImport("pdfium", CallingConvention = CallingConvention.Cdecl)] + public static extern void FPDF_InitLibrary(); + + [DllImport("pdfium", CallingConvention = CallingConvention.Cdecl)] + public static extern void FPDF_DestroyLibrary(); +#endif [DllImport("pdfium.dll", CharSet = CharSet.Ansi)] public static extern IntPtr FPDF_LoadCustomDocument([MarshalAs(UnmanagedType.LPStruct)] FPDF_FILEACCESS access, string password); diff --git a/src/PdfiumViewer/Core/NativeMethods.cs b/src/PdfiumViewer/Core/NativeMethods.cs index 05ef932..9b066e6 100644 --- a/src/PdfiumViewer/Core/NativeMethods.cs +++ b/src/PdfiumViewer/Core/NativeMethods.cs @@ -67,7 +67,14 @@ private static bool TryLoadNativeLibrary(string path) if (path == null) return false; - path = Path.Combine(path, IntPtr.Size == 4 ? "x86" : "x64"); + if(IntPtr.Size == 4) + { + path = Path.Combine(path, "runtimes", "win-x86","native"); + } + else + { + path = Path.Combine(path, "runtimes", "win-x64", "native"); + } path = Path.Combine(path, "Pdfium.dll"); return File.Exists(path) && LoadLibrary(path) != IntPtr.Zero; @@ -119,8 +126,6 @@ public enum FileMapAccess : uint [DllImport("user32.dll")] public static extern int ScrollWindowEx(IntPtr hWnd, int dx, int dy, IntPtr prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, uint flags); - [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)] - [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public class MemoryMappedHandle : SafeHandleZeroOrMinusOneIsInvalid { public MemoryMappedHandle() @@ -128,7 +133,6 @@ public MemoryMappedHandle() { } - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return CloseHandle(handle); diff --git a/src/PdfiumViewer/Core/PdfException.cs b/src/PdfiumViewer/Core/PdfException.cs index 1ce17bc..57cef8c 100644 --- a/src/PdfiumViewer/Core/PdfException.cs +++ b/src/PdfiumViewer/Core/PdfException.cs @@ -1,6 +1,5 @@ -using System; -using System.Runtime.Serialization; -using PdfiumViewer.Enums; +using PdfiumViewer.Enums; +using System; #pragma warning disable 1591 @@ -50,10 +49,5 @@ public PdfException(string message, Exception innerException) : base(message, innerException) { } - - protected PdfException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } } } diff --git a/src/PdfiumViewer/Core/PdfLibrary.cs b/src/PdfiumViewer/Core/PdfLibrary.cs index 22705a3..09a6cd2 100644 --- a/src/PdfiumViewer/Core/PdfLibrary.cs +++ b/src/PdfiumViewer/Core/PdfLibrary.cs @@ -20,7 +20,7 @@ public static void EnsureLoaded() private PdfLibrary() { - NativeMethods.FPDF_AddRef(); + NativeMethods.FPDF_InitLibrary(); } ~PdfLibrary() @@ -39,7 +39,7 @@ private void Dispose(bool disposing) { if (!_disposed) { - NativeMethods.FPDF_Release(); + NativeMethods.FPDF_DestroyLibrary(); _disposed = true; } diff --git a/src/PdfiumViewer/FodyWeavers.xml b/src/PdfiumViewer/FodyWeavers.xml deleted file mode 100644 index d5abfed..0000000 --- a/src/PdfiumViewer/FodyWeavers.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/PdfiumViewer/FodyWeavers.xsd b/src/PdfiumViewer/FodyWeavers.xsd deleted file mode 100644 index 221aeb8..0000000 --- a/src/PdfiumViewer/FodyWeavers.xsd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - Used to control if the On_PropertyName_Changed feature is enabled. - - - - - Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. - - - - - Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. - - - - - Used to control if equality checks should use the Equals method resolved from the base class. - - - - - Used to control if equality checks should use the static Equals method resolved from the base class. - - - - - Used to turn off build warnings from this weaver. - - - - - Used to turn off build warnings about mismatched On_PropertyName_Changed methods. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/PdfiumViewer/PdfiumViewer.csproj b/src/PdfiumViewer/PdfiumViewer.csproj index bdd5615..008e6d6 100644 --- a/src/PdfiumViewer/PdfiumViewer.csproj +++ b/src/PdfiumViewer/PdfiumViewer.csproj @@ -1,7 +1,7 @@ - + - netcoreapp3.1;net5.0-windows + net8.0-windows true 1.0.6 Behzad Khosravifar @@ -18,13 +18,13 @@ .Net 5 Support 1.0.6.0 1.0.6.0 + true - - - - + + + diff --git a/src/PdfiumViewer/ScrollPanel.PdfDocument.cs b/src/PdfiumViewer/ScrollPanel.PdfDocument.cs index 8d213a0..531fe28 100644 --- a/src/PdfiumViewer/ScrollPanel.PdfDocument.cs +++ b/src/PdfiumViewer/ScrollPanel.PdfDocument.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Drawing.Printing; using System.IO; +using CommunityToolkit.Mvvm.ComponentModel; using PdfiumViewer.Core; using PdfiumViewer.Drawing; using PdfiumViewer.Enums; diff --git a/src/PdfiumViewer/ScrollPanel.cs b/src/PdfiumViewer/ScrollPanel.cs index ba333b3..7dac7d6 100644 --- a/src/PdfiumViewer/ScrollPanel.cs +++ b/src/PdfiumViewer/ScrollPanel.cs @@ -1,4 +1,5 @@ -using PdfiumViewer.Core; +using CommunityToolkit.Mvvm.ComponentModel; +using PdfiumViewer.Core; using PdfiumViewer.Enums; using System; using System.Collections.Generic; @@ -11,6 +12,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; using Image = System.Windows.Controls.Image; @@ -19,7 +21,8 @@ namespace PdfiumViewer { // ScrollPanel.Properties - public partial class ScrollPanel : ScrollViewer, IPdfDocument, INotifyPropertyChanged + [ObservableObject] + public partial class ScrollPanel : ScrollViewer, IPdfDocument { public ScrollPanel() { @@ -42,10 +45,10 @@ public ScrollPanel() ZoomMode = PdfViewerZoomMode.FitHeight; Rotate = PdfRotation.Rotate0; - Flags = PdfRenderFlags.None; + Flags = PdfRenderFlags.CorrectFromDpi; PagesDisplayMode = PdfViewerPagesDisplayMode.SinglePageMode; MouseWheelMode = MouseWheelMode.PanAndZoom; - Dpi = 96; + Dpi = (int)VisualTreeHelper.GetDpi(this).PixelsPerInchX; ScrollWidth = 50; Zoom = 1; ZoomMin = DefaultZoomMin; @@ -73,15 +76,23 @@ public ScrollPanel() protected int MouseWheelDelta { get; set; } protected long MouseWheelUpdateTime { get; set; } - public event PropertyChangedEventHandler PropertyChanged; - public PdfDocument Document { get; set; } - public int PageNo { get; protected set; } - public int Dpi { get; set; } - public PdfViewerZoomMode ZoomMode { get; protected set; } - public PdfRenderFlags Flags { get; set; } - public PdfRotation Rotate { get; set; } - public PdfViewerPagesDisplayMode PagesDisplayMode { get; set; } - public MouseWheelMode MouseWheelMode { get; set; } + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(PageCount))] + private PdfDocument document; + [ObservableProperty] + private int pageNo; + [ObservableProperty] + private int dpi; + [ObservableProperty] + private PdfViewerZoomMode zoomMode; + [ObservableProperty] + private PdfRenderFlags flags; + [ObservableProperty] + private PdfRotation rotate; + [ObservableProperty] + private PdfViewerPagesDisplayMode pagesDisplayMode; + [ObservableProperty] + private MouseWheelMode mouseWheelMode; public bool IsRightToLeft { get => Panel.FlowDirection == FlowDirection.RightToLeft; @@ -93,11 +104,14 @@ public bool IsRightToLeft /// Gets or sets the current zoom level. /// [Browsable(false)] - [DefaultValue(1.0)] - public double Zoom { get; set; } - [DefaultValue(DefaultZoomMin)] public double ZoomMin { get; set; } - [DefaultValue(DefaultZoomMax)] public double ZoomMax { get; set; } - [DefaultValue(DefaultZoomFactor)] public double ZoomFactor { get; set; } + [ObservableProperty] + private double zoom = 1.0; + [ObservableProperty] + private double zoomMin = DefaultZoomMin; + [ObservableProperty] + private double zoomMax = DefaultZoomMax; + [ObservableProperty] + private double zoomFactor = DefaultZoomFactor; public PdfBookmarkCollection Bookmarks => Document?.Bookmarks; public IList PageSizes => Document?.PageSizes; @@ -115,14 +129,58 @@ protected void ScrollToPage(int page) Frames?[page].BringIntoView(); } } - protected void OnPageNoChanged() + + partial void OnPageNoChanged(int value) { PageChanged?.Invoke(this, PageNo); } - protected void OnDpiChanged() + + partial void OnDpiChanged(int value) { GotoPage(PageNo); } + + partial void OnPagesDisplayModeChanged(PdfViewerPagesDisplayMode value) + { + if (IsDocumentLoaded) + { + Panel.Children.Clear(); + Frames = null; + + if (PagesDisplayMode == PdfViewerPagesDisplayMode.SinglePageMode) + { + Frames = new Image[1]; + Panel.Orientation = Orientation.Horizontal; + } + else if (PagesDisplayMode == PdfViewerPagesDisplayMode.BookMode) + { + Frames = new Image[2]; + Panel.Orientation = Orientation.Horizontal; + } + else if (PagesDisplayMode == PdfViewerPagesDisplayMode.ContinuousMode) + { + // frames created at scrolling + Frames = new Image[Document.PageCount]; + Panel.Orientation = Orientation.Vertical; + } + + for (var i = 0; i < Frames.Length; i++) + { + Frames[i] ??= new Image { Margin = FrameSpace }; + + var pageSize = CalculatePageSize(i); + Frames[i].Width = pageSize.Width; + Frames[i].Height = pageSize.Height; + + Panel.Children.Add(Frames[i]); + } + + GC.Collect(); + GotoPage(PageNo); + } + } + + //TODO: Figure out how to remove this. protected void OnPagesDisplayModeChanged() { if (IsDocumentLoaded) @@ -168,7 +226,8 @@ protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) base.OnMouseLeftButtonDown(e); MouseClick?.Invoke(this, EventArgs.Empty); } - protected void OnFlagsChanged() + + partial void OnFlagsChanged(PdfRenderFlags value) { GotoPage(PageNo); } @@ -255,7 +314,7 @@ protected override void OnPreviewMouseWheel(MouseWheelEventArgs e) base.OnPreviewMouseWheel(e); SetMouseWheelDelta(e.Delta); - + if (IsDocumentLoaded) { if (MouseWheelMode == MouseWheelMode.Zoom)