private void AddAnnotation(object sender, RoutedEventArgs e) { // add annotation based on button's tag value. Button button = (Button)sender; string actionName = button.Tag as string; if (this.document != null && this.document.NativePage != null && this.document.Page != null) { if (actionName == "star") { Annotation starAnnotation = new RubberStampAnnotation(new Boundary(10, 400, 50, 440), AnnotationFlags.Default); FixedContent fixedContent = new FixedContent("ap01", new Boundary(0, 0, 40, 40)); fixedContent.Content.AppendImage("star", 0, 0, 40, 40); starAnnotation.Appearance.Normal = fixedContent; this.document.NativePage.Annotations.Add(starAnnotation); this.document.PageViewModel.Annotations.Add(new StarAnnotationViewModel(starAnnotation, this.document.Page)); } else if (actionName == "smile") { Annotation starAnnotation = new RubberStampAnnotation(new Boundary(60, 400, 100, 440), AnnotationFlags.Default); FixedContent fixedContent = new FixedContent("ap01", new Boundary(0, 0, 40, 40)); fixedContent.Content.AppendImage("smile", 0, 0, 40, 40); starAnnotation.Appearance.Normal = fixedContent; this.document.NativePage.Annotations.Add(starAnnotation); this.document.PageViewModel.Annotations.Add(new SmileAnnotationViewModel(starAnnotation, this.document.Page)); } else if (actionName == "text") { FreeTextAnnotation textAnnotation = new FreeTextAnnotation(new Boundary(60, 400, 260, 500)); string sampleText = "sample text"; textAnnotation.Appearance.Normal = AnnotationsHelper.CreateNormalAppearance(sampleText, 200, 100); // set properties affecting default appearance to be used as fallback textAnnotation.FontSize = 12; textAnnotation.BorderEffect = new AnnotationBorderEffect(AnnotationBorderEffectStyle.NoEffect, 0); textAnnotation.Contents = sampleText; // text and border color textAnnotation.TextColor = RgbColors.White.Components; // set background here if needed textAnnotation.Color = RgbColors.Green.Components; this.document.NativePage.Annotations.Add(textAnnotation); this.document.PageViewModel.Annotations.Add(new TextAnnotationViewModel(textAnnotation, this.document.Page)); } } }
/// <summary> /// Adds a watermark on all pages of the specified document. /// </summary> /// <param name="doc">Document to process.</param> /// <param name="imageDataStream">Stream containing image data to be used as watermark. Caller is reposible for closing it.</param> /// <param name="outputStream">Output stream, optional. If not set, incremental save will be performed. Caller is responsible for closing it.</param> public static void Watermark(this FixedDocument doc, Stream imageDataStream, Stream outputStream = null) { if (doc == null) { throw new ArgumentNullException(nameof(doc)); } if (imageDataStream == null) { throw new ArgumentNullException(nameof(imageDataStream)); } // create and register image resource string imageResourceId = Guid.NewGuid().ToString("N"); Image imageResource = new Image(imageResourceId, imageDataStream); doc.ResourceManager.RegisterResource(imageResource); // register watermark XObject it will be referenced in all watermark annotations FixedContent watermarkContent = new FixedContent(Guid.NewGuid().ToString("N"), new Boundary(imageResource.Width, imageResource.Height)); watermarkContent.Content.AppendImage(imageResourceId, 0, 0, imageResource.Width, imageResource.Height); doc.ResourceManager.RegisterResource(watermarkContent); // add annotations to every page foreach (Page page in doc.Pages) { WatermarkAnnotation watermarkAnnotation = CreateWatermarkAnnotation(page.Boundary.MediaBox, watermarkContent); doc.ResourceManager.RegisterResource(watermarkAnnotation.Watermark); page.Annotations.Add(watermarkAnnotation); } // save to specified file or do an incremental update if (outputStream != null) { doc.Save(outputStream); } else { doc.Save(); } }
/// <summary> /// Creates a fixed content object that contains /// drawing instructions for normal annotation state. /// </summary> public static FixedContent CreateNormalAppearance(string text, double width, double height) { // create fixed content object, set its unique ID using guid. // this object will be implicitly added to page resources using this ID. FixedContent fixedContent = new FixedContent(Guid.NewGuid().ToString("N"), new Boundary(0, 0, width, height)); // use text block from flow layout API subset, // to quickly draw text in a fixed content container. Apitron.PDF.Kit.FlowLayout.Content.TextBlock textBlock = new Apitron.PDF.Kit.FlowLayout.Content.TextBlock(text); textBlock.Font = new Font(StandardFonts.Helvetica, 12); textBlock.Display = Display.Block; textBlock.Color = RgbColors.White; textBlock.Width = width; textBlock.Height = height; textBlock.Background = RgbColors.Green; fixedContent.Content.AppendContentElement(textBlock, width, height); return(fixedContent); }
/// <summary> /// Creates watermark annotations object referencing specified XObject. /// </summary> /// <param name="pageBoundary">Targer page boundary.</param> /// <param name="watermarkXobject">XObject containing visual content for the watermark.</param> /// <param name="rotated">Indicates that watermark object should be rotated and aligned between the lower left and upper right corners.</param> /// <returns>Initialized watermarp annotation.</returns> private static WatermarkAnnotation CreateWatermarkAnnotation(Boundary pageBoundary, FixedContent watermarkXobject, bool rotated = false) { // create watermark content XObject and reference existing "real" watermark XObject containing content FixedContent watermarkStub = new FixedContent(Guid.NewGuid().ToString("N"), pageBoundary); if (rotated) { // calculate rotation angle double alpha = Math.Atan(watermarkStub.Boundary.Height / watermarkStub.Boundary.Width); double beta = Math.PI / 2.0 - alpha; double centeringDelta = watermarkXobject.Boundary.Height * Math.Cos(beta); double rotatedWidth = watermarkXobject.Boundary.Width * Math.Cos(alpha) + centeringDelta; double rotatedHeight = watermarkXobject.Boundary.Width * Math.Sin(alpha) + watermarkXobject.Boundary.Height * Math.Sin(beta); watermarkStub.Content.SaveGraphicsState(); watermarkStub.Content.Translate(centeringDelta + (watermarkStub.Boundary.Width - rotatedWidth) / 2.0, (watermarkStub.Boundary.Height - rotatedHeight) / 2.0); watermarkStub.Content.SetRotate(alpha); watermarkStub.Content.AppendXObject(watermarkXobject.ID, 0, 0); watermarkStub.Content.RestoreGraphicsState(); } else { watermarkStub.Content.AppendXObject(watermarkXobject.ID, (watermarkStub.Boundary.Width - watermarkXobject.Boundary.Width) / 2.0, (watermarkStub.Boundary.Height - watermarkXobject.Boundary.Height) / 2.0); watermarkStub.Content.RestoreGraphicsState(); } // create annotation and wire its visual part WatermarkAnnotation annotation = new WatermarkAnnotation(pageBoundary); annotation.Watermark = watermarkStub; return(annotation); }
/// <summary> /// Adds a watermark to all pages of the specified document. /// </summary> /// <param name="doc">Document to process.</param> /// <param name="watermarkText">Watermark text.</param> /// <param name="outputStream">Output stream, optional. If not set, incremental save will be performed.</param> public static void WatermarkText(this FixedDocument doc, string watermarkText, Stream outputStream = null) { if (doc == null) { throw new ArgumentNullException(nameof(doc)); } if (string.IsNullOrEmpty(watermarkText)) { throw new ArgumentException("Value cannot be null or empty.", nameof(watermarkText)); } // register graphics state that sets transparency level for content GraphicsState gsTransparency = new GraphicsState("gsTransparency"); gsTransparency.CurrentNonStrokingAlpha = 0.3; gsTransparency.CurrentStrokingAlpha = 0.3; doc.ResourceManager.RegisterResource(gsTransparency); // create watermark content template using given text double fontSizeInPoints = 20; double padding = 10; double borderThickness = 2; double totalAddedSpace = (padding + borderThickness) * 2; TextBlock watermarkTextBlock = new TextBlock(watermarkText) { Font = new Font("Times New Roman", fontSizeInPoints), Color = RgbColors.Red, Padding = new Thickness(padding), BorderColor = RgbColors.Red, Border = new Border(borderThickness), BorderRadius = 5, Background = RgbColors.Pink }; double textBlockWidth = watermarkTextBlock.Measure(doc.ResourceManager) + totalAddedSpace; double textBlockHeight = fontSizeInPoints + totalAddedSpace + 10; FixedContent watermarkContent = new FixedContent(Guid.NewGuid().ToString("N"), new Boundary(textBlockWidth, textBlockHeight)); watermarkContent.Content.SetGraphicsState(gsTransparency.ID); watermarkContent.Content.AppendContentElement(watermarkTextBlock, textBlockWidth, textBlockHeight); // register watermark XObject it will be referenced in all watermark annotations doc.ResourceManager.RegisterResource(watermarkContent); // add annotations to every page foreach (Page page in doc.Pages) { WatermarkAnnotation watermarkAnnotation = CreateWatermarkAnnotation(page.Boundary.MediaBox, watermarkContent, true); doc.ResourceManager.RegisterResource(watermarkAnnotation.Watermark); page.Annotations.Add(watermarkAnnotation); } // save to specified file or do an incremental update if (outputStream != null) { doc.Save(outputStream); } else { doc.Save(); } }
/// <summary> /// Signs the range of document pages using given certificate and signature image. /// </summary> /// <param name="doc">Document to sign.</param> /// <param name="signingCertificate">Signing certificate's data stream.</param> /// <param name="certPassword">Certificate's password.</param> /// <param name="signatureText">The text of the signature.</param> /// <param name="signatureBoundary">Visual signature boundaries.</param> /// <param name="signaturePageIndexStart">The index of the first page to sign.</param> /// <param name="signaturePageIndexEnd">The index of the last page to sign.</param> /// <param name="outputStream">Output stream, optional. If not set, incremental save will be performed.</param> /// <returns>Identifier assigned to the created signature field. Using this id you can find this field in doc's AcroForm dictionary.</returns> public static string Sign(this FixedDocument doc, Stream signingCertificate, string certPassword, string signatureText, Boundary signatureBoundary, int signaturePageIndexStart = 0, int signaturePageIndexEnd = 0, Stream outputStream = null) { if (doc == null) { throw new ArgumentNullException(nameof(doc)); } if (signingCertificate == null) { throw new ArgumentNullException(nameof(signingCertificate)); } if (certPassword == null) { throw new ArgumentNullException(nameof(certPassword)); } if (signatureBoundary == null) { throw new ArgumentNullException(nameof(signatureBoundary)); } if (signaturePageIndexStart < 0 || signaturePageIndexStart > doc.Pages.Count - 1) { throw new ArgumentOutOfRangeException(nameof(signaturePageIndexStart)); } if (signaturePageIndexEnd < signaturePageIndexStart || signaturePageIndexEnd > doc.Pages.Count - 1) { throw new ArgumentOutOfRangeException(nameof(signaturePageIndexEnd)); } // create textual resource FixedContent signatureTextXObject = new FixedContent(Guid.NewGuid().ToString("N"), new Boundary(0, 0, signatureBoundary.Width, signatureBoundary.Height)); Section section = new Section(); if (!string.IsNullOrEmpty(signatureText)) { var newLineString = "<br/>"; signatureText = signatureText.Replace("\r\n", newLineString) .Replace("\n", newLineString) .Replace("\r", newLineString); foreach (ContentElement contentElement in ContentElement.FromMarkup(signatureText)) { contentElement.Font = new Font("TimesNewRoman", 12); section.Add(contentElement); } signatureTextXObject.Content.AppendContentElement(section, signatureBoundary.Width, signatureBoundary.Height); } doc.ResourceManager.RegisterResource(signatureTextXObject); string signatureFieldId = Guid.NewGuid().ToString("N"); // create signature field and initialize it using a stored // password protected certificate SignatureField signatureField = new SignatureField(signatureFieldId); signatureField.Signature = Signature.Create(new Pkcs12Store(signingCertificate, certPassword)); // add signature field to a document doc.AcroForm.Fields.Add(signatureField); // create signature view using the image resource SignatureFieldView signatureView = new SignatureFieldView(signatureField, signatureBoundary); signatureView.ViewSettings.Graphic = Graphic.XObject; signatureView.ViewSettings.GraphicResourceID = signatureTextXObject.ID; signatureView.ViewSettings.Description = Description.None; // add view to pages' annotations for (int i = signaturePageIndexStart; i <= signaturePageIndexEnd; ++i) { doc.Pages[i].Annotations.Add(signatureView); } // save to specified file or do an incremental update if (outputStream != null) { doc.Save(outputStream); } else { doc.Save(); } return(signatureFieldId); }