From 6134b58a4c0c69b4a8f093c2023b918fb74432d6 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 7 Nov 2025 14:46:55 +0100 Subject: [PATCH] refactor(BurnPdfCommand): extract GdPicture and math helpers into extension classes and simplify BurnPdfCommandHandler - Refactored BurnPdfCommandHandler to use new extension methods for cleaner annotation handling. - Introduced ITextStyle interface to generalize font styling for text annotations. - Updated PDFBurnerParams to implement ITextStyle for consistent font settings reuse. - Added MathematExtensions for coordinate and unit conversion (ToInches, ToPointF). - Added GdPictureExtensions to encapsulate annotation-related logic (form fields, images, ink). - Improved readability and maintainability by removing redundant helper methods. --- .../Common/Configurations/PDFBurnerParams.cs | 5 +- .../Common/Extensions/GdPictureExtensions.cs | 176 ++++++++++++++++++ .../Common/Extensions/MathematExtensions.cs | 40 ++++ .../Common/Interfaces/Model/ITextStyle.cs | 27 +++ .../Pdf/BurnPdfCommand.cs | 173 ++--------------- 5 files changed, 260 insertions(+), 161 deletions(-) create mode 100644 EnvelopeGenerator.Application/Common/Extensions/GdPictureExtensions.cs create mode 100644 EnvelopeGenerator.Application/Common/Extensions/MathematExtensions.cs create mode 100644 EnvelopeGenerator.Application/Common/Interfaces/Model/ITextStyle.cs diff --git a/EnvelopeGenerator.Application/Common/Configurations/PDFBurnerParams.cs b/EnvelopeGenerator.Application/Common/Configurations/PDFBurnerParams.cs index d0d090af..ab41c0a6 100644 --- a/EnvelopeGenerator.Application/Common/Configurations/PDFBurnerParams.cs +++ b/EnvelopeGenerator.Application/Common/Configurations/PDFBurnerParams.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.CodeAnalysis; +using EnvelopeGenerator.Application.Common.Interfaces.Model; +using System.Diagnostics.CodeAnalysis; using System.Drawing; namespace EnvelopeGenerator.Application.Common.Configurations; @@ -6,7 +7,7 @@ namespace EnvelopeGenerator.Application.Common.Configurations; /// /// /// -public class PDFBurnerParams +public class PDFBurnerParams : ITextStyle { /// /// diff --git a/EnvelopeGenerator.Application/Common/Extensions/GdPictureExtensions.cs b/EnvelopeGenerator.Application/Common/Extensions/GdPictureExtensions.cs new file mode 100644 index 00000000..188137d5 --- /dev/null +++ b/EnvelopeGenerator.Application/Common/Extensions/GdPictureExtensions.cs @@ -0,0 +1,176 @@ +using EnvelopeGenerator.Application.Common.Dto.PSPDFKitInstant; +using EnvelopeGenerator.Domain.Constants; +using GdPicture14; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using SixLabors.ImageSharp; +using System.Drawing; +using EnvelopeGenerator.Application.Common.Extensions; +using EnvelopeGenerator.Application.Common.Interfaces.Model; +using EnvelopeGenerator.Application.Common.Configurations; + +namespace EnvelopeGenerator.Application.Common.Extensions; + +/// +/// +/// +public static class GdPictureExtensions +{ + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void AddFormFieldValue(this AnnotationManager manager, double x, double y, double width, double height, int page, string value, ITextStyle textStyle) + { + manager.SelectPage(page); + + // Add the text annotation + var ant = manager.AddTextAnnot((float)x, (float)y, (float)width, (float)height, value); + + // Set the font properties + ant.FontName = textStyle.FontName; + ant.FontSize = textStyle.FontSize; + ant.FontStyle = textStyle.FontStyle; + + manager.SaveAnnotationsToPage(); + } + + /// + /// + /// + /// + /// + /// + /// + public static void AddFormFieldValue(this AnnotationManager manager, Annotation pAnnotation, FormFieldValue formFieldValue, PDFBurnerParams options) + { + var ffIndex = options.GetAnnotationIndex(pAnnotation.EgName); + + // Convert pixels to Inches + var oBounds = pAnnotation.Bbox?.Select(points => points.ToInches()).ToList(); + + if (oBounds is null || oBounds.Count < 4) + return; + + double oX = oBounds[0]; + double oY = oBounds[1] + options.YOffset * ffIndex + options.TopMargin; + double oWidth = oBounds[2]; + double oHeight = oBounds[3]; + + manager.SelectPage(pAnnotation.PageIndex + 1); + + // Add the text annotation + var ant = manager.AddTextAnnot((float)oX, (float)oY, (float)oWidth, (float)oHeight, formFieldValue.Value); + + // Set the font properties + ant.FontName = options.FontName; + ant.FontSize = options.FontSize; + ant.FontStyle = options.FontStyle; + + manager.SaveAnnotationsToPage(); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void AddImageAnnotation(this AnnotationManager manager, double x, double y, double width, double height, int page, string base64) + { + manager.SelectPage(page); + manager.AddEmbeddedImageAnnotFromBase64(base64, (float)x, (float)y, (float)width, (float)height); + } + + /// + /// + /// + /// + /// + /// + public static void AddImageAnnotation(this AnnotationManager manager, Annotation pAnnotation, Dictionary pAttachments) + { + var oAttachment = pAttachments + .Where(a => a.Key == pAnnotation.ImageAttachmentId) + .SingleOrDefault(); + + if (oAttachment.Value == null) + return; + + // Convert pixels to Inches + var oBounds = pAnnotation.Bbox?.Select(post => post.ToInches()).ToList(); + + if (oBounds is null || oBounds.Count < 4) + return; + + var oX = oBounds[0]; + var oY = oBounds[1]; + var oWidth = oBounds[2]; + var oHeight = oBounds[3]; + + manager.SelectPage(pAnnotation.PageIndex + 1); + manager.AddEmbeddedImageAnnotFromBase64(oAttachment.Value.Binary, (float)oX, (float)oY, (float)oWidth, (float)oHeight); + } + + /// + /// + /// + /// + /// + /// + public static void AddInkAnnotation(this AnnotationManager manager, int page, string value) + { + var ink = JsonConvert.DeserializeObject(value); + + var oSegments = ink?.Lines.Points; + var oColor = ColorTranslator.FromHtml(ink?.StrokeColor ?? "#000000"); + manager.SelectPage(page); + + if (oSegments is null) + return; + + foreach (var oSegment in oSegments) + { + var oPoints = oSegment + .Select(points => points.ToPointF()) + .ToArray(); + + manager.AddFreeHandAnnot(oColor, oPoints); + } + } + + /// + /// + /// + /// + /// + public static void AddInkAnnotation(this AnnotationManager manager, Annotation pAnnotation) + { + var oSegments = pAnnotation.Lines?.Points; + var oColor = ColorTranslator.FromHtml(pAnnotation.StrokeColor ?? "#000000"); + manager.SelectPage(pAnnotation.PageIndex + 1); + + if (oSegments is null) + return; + + foreach (var oSegment in oSegments) + { + var oPoints = oSegment + .Select(points => points.ToPointF()) + .ToArray(); + + manager.AddFreeHandAnnot(oColor, oPoints); + } + } +} diff --git a/EnvelopeGenerator.Application/Common/Extensions/MathematExtensions.cs b/EnvelopeGenerator.Application/Common/Extensions/MathematExtensions.cs new file mode 100644 index 00000000..e1641cfd --- /dev/null +++ b/EnvelopeGenerator.Application/Common/Extensions/MathematExtensions.cs @@ -0,0 +1,40 @@ +using System.Drawing; + +namespace EnvelopeGenerator.Application.Common.Extensions; + +/// +/// +/// +public static class MathematExtensions +{ + /// + /// + /// + /// + /// + public static PointF ToPointF(this List points) + { + var pointsInch = points.Select(ToInches).ToList(); + return new PointF(pointsInch[0], pointsInch[1]); + } + + /// + /// + /// + /// + /// + public static double ToInches(this double value) + { + return value / 72.0; + } + + /// + /// + /// + /// + /// + public static float ToInches(this float value) + { + return value / 72f; + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Common/Interfaces/Model/ITextStyle.cs b/EnvelopeGenerator.Application/Common/Interfaces/Model/ITextStyle.cs new file mode 100644 index 00000000..38f784c1 --- /dev/null +++ b/EnvelopeGenerator.Application/Common/Interfaces/Model/ITextStyle.cs @@ -0,0 +1,27 @@ +using System.Diagnostics.CodeAnalysis; +using System.Drawing; + +namespace EnvelopeGenerator.Application.Common.Interfaces.Model; + +/// +/// +/// +public interface ITextStyle +{ + /// + /// + /// + public string FontName { get; set; } + + + /// + /// + /// + public int FontSize { get; set; } + + /// + /// + /// + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "")] + public FontStyle FontStyle { get; set; } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Pdf/BurnPdfCommand.cs b/EnvelopeGenerator.Application/Pdf/BurnPdfCommand.cs index eac6bc1b..53a269d3 100644 --- a/EnvelopeGenerator.Application/Pdf/BurnPdfCommand.cs +++ b/EnvelopeGenerator.Application/Pdf/BurnPdfCommand.cs @@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json; -using System.Drawing; +using EnvelopeGenerator.Application.Common.Extensions; namespace EnvelopeGenerator.Application.Pdf; @@ -24,10 +24,7 @@ public record BurnPdfCommand(byte[] SourceBuffer, List InstantJSONList, /// public class BurnPdfCommandHandler : IRequestHandler { - /// - /// - /// - private readonly PDFBurnerParams _pdfBurnerParams; + private readonly PDFBurnerParams _options; private readonly AnnotationManager _manager; @@ -44,19 +41,13 @@ public class BurnPdfCommandHandler : IRequestHandler /// public BurnPdfCommandHandler(IOptions pdfBurnerParams, AnnotationManager manager, IRepository signRepo, ILogger logger) { - _pdfBurnerParams = pdfBurnerParams.Value; + _options = pdfBurnerParams.Value; _manager = manager; _signRepo = signRepo; _logger = logger; } - /// - /// - /// - /// - /// - /// - public byte[] BurnElementAnnotsToPDF(byte[] pSourceBuffer, List elements) + private byte[] BurnElementAnnotsToPDF(byte[] pSourceBuffer, List elements) { // Add background using var doc = PdfEditor.Pdf.FromMemory(pSourceBuffer); @@ -103,18 +94,19 @@ public class BurnPdfCommandHandler : IRequestHandler if (annot.Type == AnnotationType.PSPDFKit.FormField) { - AddFormFieldValue( + _manager.AddFormFieldValue( (annot.X ?? default) / inchFactor, y, (annot.Width ?? default) / inchFactor, (annot.Height ?? default) / inchFactor, element.Page, - annot.Value + annot.Value, + _options ); } else if (annot.Type == AnnotationType.PSPDFKit.Image) { - AddImageAnnotation( + _manager.AddImageAnnotation( (annot.X ?? default) / inchFactor, annot.Name == "signature" ? ((annot.Y ?? default) - frameYShift) / inchFactor : y, (annot.Width ?? default) / inchFactor, @@ -125,7 +117,7 @@ public class BurnPdfCommandHandler : IRequestHandler } else if (annot.Type == AnnotationType.PSPDFKit.Ink) { - AddInkAnnotation(element.Page, annot.Value); + _manager.AddInkAnnotation(element.Page, annot.Value); } } } @@ -141,13 +133,7 @@ public class BurnPdfCommandHandler : IRequestHandler return oNewStream.ToArray(); } - /// - /// - /// - /// - /// - /// - public byte[] BurnInstantJSONAnnotsToPDF(byte[] pSourceBuffer, List pInstantJSONList) + private byte[] BurnInstantJSONAnnotsToPDF(byte[] pSourceBuffer, List pInstantJSONList) { GdPictureStatus oResult; @@ -211,11 +197,11 @@ public class BurnPdfCommandHandler : IRequestHandler { case AnnotationType.PSPDFKit.Image: if (annotationData?.Attachments is not null) - AddImageAnnotation(annotation, annotationData.Attachments); + _manager.AddImageAnnotation(annotation, annotationData.Attachments); break; case AnnotationType.PSPDFKit.Ink: - AddInkAnnotation(annotation); + _manager.AddInkAnnotation(annotation); break; case AnnotationType.PSPDFKit.Widget: @@ -223,146 +209,15 @@ public class BurnPdfCommandHandler : IRequestHandler var formFieldValue = annotationData?.FormFieldValues? .FirstOrDefault(fv => fv.Name == annotation.Id); - if (formFieldValue != null && !_pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.Value)) + if (formFieldValue != null && !_options.IgnoredLabels.Contains(formFieldValue.Value)) { - AddFormFieldValue(annotation, formFieldValue); + _manager.AddFormFieldValue(annotation, formFieldValue, _options); } break; } } } - private void AddFormFieldValue(double x, double y, double width, double height, int page, string value) - { - _manager.SelectPage(page); - - // Add the text annotation - var ant = _manager.AddTextAnnot((float)x, (float)y, (float)width, (float)height, value); - - // Set the font properties - ant.FontName = _pdfBurnerParams.FontName; - ant.FontSize = _pdfBurnerParams.FontSize; - ant.FontStyle = _pdfBurnerParams.FontStyle; - - _manager.SaveAnnotationsToPage(); - } - - private void AddFormFieldValue(Annotation pAnnotation, FormFieldValue formFieldValue) - { - var ffIndex = _pdfBurnerParams.GetAnnotationIndex(pAnnotation.EgName); - - // Convert pixels to Inches - var oBounds = pAnnotation.Bbox?.Select(ToInches).ToList(); - - if (oBounds is null || oBounds.Count < 4) - return; - - double oX = oBounds[0]; - double oY = oBounds[1] + _pdfBurnerParams.YOffset * ffIndex + _pdfBurnerParams.TopMargin; - double oWidth = oBounds[2]; - double oHeight = oBounds[3]; - - _manager.SelectPage(pAnnotation.PageIndex + 1); - - // Add the text annotation - var ant = _manager.AddTextAnnot((float)oX, (float)oY, (float)oWidth, (float)oHeight, formFieldValue.Value); - - // Set the font properties - ant.FontName = _pdfBurnerParams.FontName; - ant.FontSize = _pdfBurnerParams.FontSize; - ant.FontStyle = _pdfBurnerParams.FontStyle; - - _manager.SaveAnnotationsToPage(); - } - - private void AddImageAnnotation(double x, double y, double width, double height, int page, string base64) - { - _manager.SelectPage(page); - _manager.AddEmbeddedImageAnnotFromBase64(base64, (float)x, (float)y, (float)width, (float)height); - } - - private void AddImageAnnotation(Annotation pAnnotation, Dictionary pAttachments) - { - var oAttachment = pAttachments - .Where(a => a.Key == pAnnotation.ImageAttachmentId) - .SingleOrDefault(); - - if (oAttachment.Value == null) - return; - - // Convert pixels to Inches - var oBounds = pAnnotation.Bbox?.Select(ToInches).ToList(); - - if (oBounds is null || oBounds.Count < 4) - return; - - var oX = oBounds[0]; - var oY = oBounds[1]; - var oWidth = oBounds[2]; - var oHeight = oBounds[3]; - - _manager.SelectPage(pAnnotation.PageIndex + 1); - _manager.AddEmbeddedImageAnnotFromBase64(oAttachment.Value.Binary, (float)oX, (float)oY, (float)oWidth, (float)oHeight); - } - - private void AddInkAnnotation(int page, string value) - { - var ink = JsonConvert.DeserializeObject(value); - - var oSegments = ink?.Lines.Points; - var oColor = ColorTranslator.FromHtml(ink?.StrokeColor ?? "#000000"); - _manager.SelectPage(page); - - if (oSegments is null) - return; - - foreach (var oSegment in oSegments) - { - var oPoints = oSegment - .Select(ToPointF) - .ToArray(); - - _manager.AddFreeHandAnnot(oColor, oPoints); - } - } - - private void AddInkAnnotation(Annotation pAnnotation) - { - var oSegments = pAnnotation.Lines?.Points; - var oColor = ColorTranslator.FromHtml(pAnnotation.StrokeColor ?? "#000000"); - _manager.SelectPage(pAnnotation.PageIndex + 1); - - if (oSegments is null) - return; - - foreach (var oSegment in oSegments) - { - var oPoints = oSegment - .Select(ToPointF) - .ToArray(); - - _manager.AddFreeHandAnnot(oColor, oPoints); - } - } - - #region Helpers - private PointF ToPointF(List pPoints) - { - var oPoints = pPoints.Select(ToInches).ToList(); - return new PointF(oPoints[0], oPoints[1]); - } - - private double ToInches(double pValue) - { - return pValue / 72.0; - } - - private float ToInches(float pValue) - { - return pValue / 72f; - } - #endregion - /// /// ///