From db70bbcebf8ace72477865cc59aec692988503a0 Mon Sep 17 00:00:00 2001 From: TekH Date: Sun, 7 Jun 2026 10:17:42 +0200 Subject: [PATCH] Add UnitOfLength enum and enhance SignatureDto immutability Introduced the `UnitOfLength` enum to represent measurement units (Inch and Point) for signature positioning, with detailed documentation and conversion logic. Updated `SignatureDto` to use `init` accessors for immutability, added backing fields for `X` and `Y` with conversion support, and introduced the `Factor` property to handle unit conversions. Added a `Convert` method to enable switching between units of length and improved extensibility for future `SenderAppType` support. Enhanced code readability and maintainability with detailed comments and remarks. --- .../Models/Constants/UnitOfLength.cs | 65 +++++++++++++++++++ .../Models/SignatureDto.cs | 53 +++++++++++++-- 2 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 EnvelopeGenerator.ReceiverUI/Models/Constants/UnitOfLength.cs diff --git a/EnvelopeGenerator.ReceiverUI/Models/Constants/UnitOfLength.cs b/EnvelopeGenerator.ReceiverUI/Models/Constants/UnitOfLength.cs new file mode 100644 index 00000000..944d88bf --- /dev/null +++ b/EnvelopeGenerator.ReceiverUI/Models/Constants/UnitOfLength.cs @@ -0,0 +1,65 @@ +namespace EnvelopeGenerator.ReceiverUI.Models.Constants; + +/// +/// Represents the unit of measurement for coordinate values in signature positioning. +/// Used for converting coordinates between different systems (GdPicture14, PDF.js, iText7). +/// +public enum UnitOfLength +{ + /// + /// Inch unit (1 inch = 25.4 mm). + /// This is the native unit used by GdPicture14 (EnvelopeGenerator.Form - Legacy VB.NET app). + /// Database stores all coordinates (X, Y, Width, Height) in INCHES. + /// + /// + /// Source: GdPicture14.Annotations.AnnotationStickyNote uses INCHES natively. + ///
+ /// Evidence: VB.NET code directly assigns database values to annotation properties without conversion: + /// + /// oAnnotation.Left = CSng(pElement.X) ' Direct assignment → INCHES + /// oAnnotation.Top = CSng(pElement.Y) + /// + /// Standard Page Dimensions: + /// + /// A4: 8.27" × 11.69" (210mm × 297mm) + /// Letter: 8.5" × 11" + /// + ///
+ Inch = 0, + + /// + /// PDF Point unit (1 point = 1/72 inch). + /// This is the standard unit used by PDF specification and PDF.js viewer. + /// + /// + /// Definition: According to PDF specification and Microsoft documentation: + ///
+ /// "PDF pages are sized in point units. 1 pt == 1/72 inch" + ///

+ /// Conversion Formula: + /// + /// points = inches * 72.0 + /// inches = points / 72.0 + /// + /// Important: Point ≠ Pixel! + /// + /// Point (pt): Device-independent unit (always 1/72 inch) + /// Pixel (px): Device-dependent unit (varies with screen DPI) + /// At 72 DPI: 1 point = 1 pixel (coincidence) + /// At 96 DPI: 1 point ≈ 1.33 pixels + /// At 300 DPI: 1 point ≈ 4.17 pixels + /// + /// Standard Page Dimensions (in points): + /// + /// A4: 595 × 842 points (8.27" × 11.69" × 72) + /// Letter: 612 × 792 points (8.5" × 11" × 72) + /// + /// Usage in EnvelopeGenerator: + /// + /// PDF.js viewer expects coordinates in points + /// iText7 library uses points for PDF manipulation + /// PSPDFKit (Web) uses points for annotation placement + /// + ///
+ Point +} diff --git a/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs b/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs index dc8039b3..07790b5c 100644 --- a/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs +++ b/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs @@ -10,16 +10,59 @@ namespace EnvelopeGenerator.ReceiverUI.Models; public class SignatureDto { /// Unique identifier. - public int Id { get; set; } + public int Id { get; init; } + + private double _x; + private double _y; /// Horizontal position in INCHES from left edge. - public double X { get; set; } + public double X + { + get => _x * Factor; + init => _x = value; + } /// Vertical position in INCHES from top edge. - public double Y { get; set; } + public double Y + { + get => _y * Factor; + init => _y = value; + } /// 1-based page number. - public int Page { get; set; } + public int Page { get; init; } - public SenderAppType SenderAppType { get; set; } + /// Sender application type that created this signature. + public SenderAppType SenderAppType { get; init; } + + private UnitOfLength _unitOfLength; + + public SignatureDto Convert(UnitOfLength unitOfLength) + { + _unitOfLength = unitOfLength; + return this; + } + + public double Factor + { + get + { + if (SenderAppType != SenderAppType.LegacyFormApp) + { + throw new NotImplementedException( + $"SenderAppType '{SenderAppType}' is not yet implemented. " + + $"Currently, only '{nameof(SenderAppType.LegacyFormApp)}' is supported. " + + $"Future implementations will handle '{nameof(SenderAppType.ReceiverUIBlazorApp)}' and other types."); + } + + // LegacyFormApp uses GdPicture14 with INCHES + return _unitOfLength switch + { + UnitOfLength.Inch => 1.0, // No conversion needed: INCHES → INCHES + UnitOfLength.Point => 72.0, // INCHES → PDF Points: 1 inch = 72 points (PDF standard, NOT pixels!) + _ => throw new InvalidOperationException( + $"Unknown UnitOfLength: {_unitOfLength}. Expected '{nameof(UnitOfLength.Inch)}' or '{nameof(UnitOfLength.Point)}'.") + }; + } + } } \ No newline at end of file