diff --git a/src/foundation/src/PDFsharp/src/PdfSharp-gdi/PdfSharp-gdi.csproj b/src/foundation/src/PDFsharp/src/PdfSharp-gdi/PdfSharp-gdi.csproj index c71a220d..6809025b 100644 --- a/src/foundation/src/PDFsharp/src/PdfSharp-gdi/PdfSharp-gdi.csproj +++ b/src/foundation/src/PDFsharp/src/PdfSharp-gdi/PdfSharp-gdi.csproj @@ -1,4 +1,4 @@ - + library @@ -256,6 +256,8 @@ + + diff --git a/src/foundation/src/PDFsharp/src/PdfSharp-wpf/PdfSharp-wpf.csproj b/src/foundation/src/PDFsharp/src/PdfSharp-wpf/PdfSharp-wpf.csproj index 9fc703b1..5376b3cf 100644 --- a/src/foundation/src/PDFsharp/src/PdfSharp-wpf/PdfSharp-wpf.csproj +++ b/src/foundation/src/PDFsharp/src/PdfSharp-wpf/PdfSharp-wpf.csproj @@ -1,4 +1,4 @@ - + library @@ -253,6 +253,8 @@ + + diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/IAnnotationAppearanceHandler.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/IAnnotationAppearanceHandler.cs index e74aac4a..62f7f4f7 100644 --- a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/IAnnotationAppearanceHandler.cs +++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/IAnnotationAppearanceHandler.cs @@ -1,4 +1,4 @@ -// PDFsharp - A .NET library for processing PDF +// PDFsharp - A .NET library for processing PDF // See the LICENSE file in the solution root for more information. using PdfSharp.Drawing; diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/PdfFileAttachmentAnnotation.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/PdfFileAttachmentAnnotation.cs new file mode 100644 index 00000000..96d33fd5 --- /dev/null +++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/PdfFileAttachmentAnnotation.cs @@ -0,0 +1,148 @@ +// PDFsharp - A .NET library for processing PDF +// See the LICENSE file in the solution root for more information. + +using PdfSharp.Drawing; +using PdfSharp.Pdf.Advanced; + +namespace PdfSharp.Pdf.Annotations +{ + /// + /// Represents a file attachment annotation. + /// + public sealed class PdfFileAttachmentAnnotation : PdfAnnotation + { + /// + /// Initializes a new instance of the class. + /// + public PdfFileAttachmentAnnotation() + { + Initialize(); + } + + /// + /// Initializes a new instance of the class. + /// + public PdfFileAttachmentAnnotation(PdfDocument document) + : base(document) + { + Initialize(); + } + + void Initialize() + { + Elements.SetName(Keys.Subtype, "/FileAttachment"); + Icon = PdfFileAttachmentAnnotationIcon.PushPin; + Flags = PdfAnnotationFlags.Locked; + } + + /// + /// Creates a file attachment annotation. + /// + public static PdfFileAttachmentAnnotation CreateFileAttachmentAnnotation(PdfRectangle rectangle) + { + var annot = new PdfFileAttachmentAnnotation + { + Rectangle = rectangle, + }; + return annot; + } + + /// + /// Gets or sets an icon to be used in displaying the annotation. + /// + public PdfFileAttachmentAnnotationIcon Icon + { + get + { + string value = Elements.GetName(Keys.Name); + if (value == "") + return PdfFileAttachmentAnnotationIcon.NoIcon; + + value = value.Substring(1); + if (!Enum.IsDefined(typeof(PdfFileAttachmentAnnotationIcon), value)) + return PdfFileAttachmentAnnotationIcon.NoIcon; + + return (PdfFileAttachmentAnnotationIcon)Enum.Parse(typeof(PdfFileAttachmentAnnotationIcon), value, false); + } + set + { + if (value != PdfFileAttachmentAnnotationIcon.NoIcon && + Enum.IsDefined(typeof(PdfFileAttachmentAnnotationIcon), value)) + { + Elements.SetName(Keys.Name, "/" + value.ToString()); + } + else + Elements.Remove(Keys.Name); + } + } + + public IAnnotationAppearanceHandler? CustomAppearanceHandler { get; set; } + + /// + /// Creates the custom appearance form X object for this annotation + /// + public void RenderCustomAppearance() + { + var visible = (Rectangle.X1 + Rectangle.X2 + Rectangle.Y1 + Rectangle.Y2) != 0; + + if (!visible) + return; + + if (CustomAppearanceHandler == null) + throw new Exception("AppearanceHandler is null"); + + XForm form = new(_document, Rectangle.Size); + XGraphics gfx = XGraphics.FromForm(form); + + CustomAppearanceHandler.DrawAppearance(gfx, Rectangle.ToXRect()); + + form.DrawingFinished(); + + // Get existing or create new appearance dictionary + if (Elements[PdfAnnotation.Keys.AP] is not PdfDictionary ap) + { + ap = new PdfDictionary(_document); + Elements[PdfAnnotation.Keys.AP] = ap; + } + + // Set XRef to normal state + ap.Elements["/N"] = form.PdfForm.Reference; + + form.PdfRenderer.Close(); + + Icon = PdfFileAttachmentAnnotationIcon.NoIcon; + } + + /// + /// Predefined keys of this dictionary. + /// + internal new class Keys : PdfAnnotation.Keys + { + /// + /// (Required) The file associated with this annotation. + /// + [KeyInfo(KeyType.FileSpecification | KeyType.Required)] + public const string FS = "/FS"; + + /// + /// (Optional) The name of an icon that shall be used in displaying the annotation. + /// Conforming readers shall provide predefined icon appearances for at least the following names: + /// Graph + /// PushPin + /// Paperclip + /// Tag + /// + [KeyInfo(KeyType.Name | KeyType.Optional)] + public const string Name = "/Name"; + + public static DictionaryMeta Meta => _meta ??= CreateMeta(typeof(Keys)); + + static DictionaryMeta? _meta; + } + + /// + /// Gets the KeysMeta of this dictionary type. + /// + internal override DictionaryMeta Meta => Keys.Meta; + } +} diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/enums/PdfFileAttachmentAnnotationIcon.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/enums/PdfFileAttachmentAnnotationIcon.cs new file mode 100644 index 00000000..b9b78042 --- /dev/null +++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf.Annotations/enums/PdfFileAttachmentAnnotationIcon.cs @@ -0,0 +1,36 @@ +// PDFsharp - A .NET library for processing PDF +// See the LICENSE file in the solution root for more information. + +namespace PdfSharp.Pdf.Annotations +{ + /// + /// Specifies the pre-defined icon names of file attachment annotations. + /// + public enum PdfFileAttachmentAnnotationIcon + { + /// + /// A pre-defined annotation icon. + /// + NoIcon, + + /// + /// A pre-defined annotation icon. + /// + Graph, + + /// + /// A pre-defined annotation icon. + /// + PushPin, + + /// + /// A pre-defined annotation icon. + /// + Paperclip, + + /// + /// A pre-defined annotation icon. + /// + Tag, + } +} diff --git a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf/PdfPage.cs b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf/PdfPage.cs index 9d451f45..646c296a 100644 --- a/src/foundation/src/PDFsharp/src/PdfSharp/Pdf/PdfPage.cs +++ b/src/foundation/src/PDFsharp/src/PdfSharp/Pdf/PdfPage.cs @@ -1,4 +1,4 @@ -// PDFsharp - A .NET library for processing PDF +// PDFsharp - A .NET library for processing PDF // See the LICENSE file in the solution root for more information. using System.ComponentModel; @@ -9,6 +9,7 @@ using PdfSharp.Pdf.Advanced; using PdfSharp.Pdf.Annotations; using InvalidOperationException = System.InvalidOperationException; +using System.IO; namespace PdfSharp.Pdf { @@ -683,6 +684,39 @@ public PdfLinkAnnotation AddFileLink(PdfRectangle rect, string fileName) return annotation; } + /// + /// Adds a file attachment annotation. + /// + /// The rect. + /// The file specification + public PdfFileAttachmentAnnotation AddFileAttachmentAnnotation(PdfRectangle rect, PdfFileSpecification fileSpecification) + { + if (fileSpecification.Reference == null) + Owner.Internals.AddObject(fileSpecification); + + var annotation = PdfFileAttachmentAnnotation.CreateFileAttachmentAnnotation(rect); + Annotations.Add(annotation); + annotation.Elements.SetReference(PdfFileAttachmentAnnotation.Keys.FS, fileSpecification.ReferenceNotNull); + return annotation; + } + + /// + /// Adds a file attachment annotation. + /// + /// The rect. + /// The file stream + /// The file name + public PdfFileAttachmentAnnotation AddFileAttachmentAnnotation(PdfRectangle rect, PdfEmbeddedFileStream fileStream, string fileName) + { + var fileSpecification = new PdfFileSpecification(Owner, fileStream, fileName); + Owner.Internals.AddObject(fileSpecification); + + var annotation = PdfFileAttachmentAnnotation.CreateFileAttachmentAnnotation(rect); + Annotations.Add(annotation); + annotation.Elements.SetReference(PdfFileAttachmentAnnotation.Keys.FS, fileSpecification.ReferenceNotNull); + return annotation; + } + #endregion // TODO_OLD: PdfActions