From 34f145305c05a09f02fa2ff14fafb5b4f682700c Mon Sep 17 00:00:00 2001 From: TekH Date: Sat, 6 Jun 2026 21:21:12 +0200 Subject: [PATCH] Standardize coordinate system to use INCHES Updated the digital document signing system to use INCHES as the standard unit for annotations and signatures, aligning with GdPicture14's native format. Previously used DevExpress units (1/100 inch) and other formats have been replaced. - Updated `AnnotationDto` to reflect the new coordinate system. - Introduced `SignatureDto` for signature positions, deprecating `AnnotationDto`. - Added conversion formulas for transforming coordinates between INCHES and other systems (DevExpress, PDF Points, PDF.js, etc.). - Added a unit comparison table and A4 page dimensions in various units. - Introduced a new read-only PDF.js viewer for envelopes (`/envelope/{EnvelopeKey}`). These changes improve consistency, simplify conversions, and align with modern tools like PSPDFKit and iText7. --- COPILOT_CONTEXT_EN.md | 58 +++++++++++++++---- .../Common/Dto/AnnotationDto.cs | 23 ++++---- .../Models/AnnotationDto.cs | 18 +++--- .../Models/SignatureDto.cs | 9 +++ 4 files changed, 80 insertions(+), 28 deletions(-) diff --git a/COPILOT_CONTEXT_EN.md b/COPILOT_CONTEXT_EN.md index 86e77b76..8d97a879 100644 --- a/COPILOT_CONTEXT_EN.md +++ b/COPILOT_CONTEXT_EN.md @@ -40,22 +40,60 @@ A digital document signing system. Senders upload PDFs and place signature annot --- -## AnnotationDto — Coordinate System +## SignatureDto / AnnotationDto — Coordinate System + +**Database Storage Format:** INCHES (GdPicture14 native unit) +**Origin:** Top-left corner of page +**Axes:** X increases rightward, Y increases downward + +### Source Evidence (VB.NET Legacy Code) + +```vb +' From: EnvelopeGenerator.Form/frmFieldEditor.vb +' GdPicture14.Annotations.AnnotationStickyNote + +'Breite und Höhe in Inches (4,5*5cm) +Private Const SIGNATURE_WIDTH As Single = 1.77 ' 1.77 inches = 4.5cm +Private Const SIGNATURE_HEIGHT As Single = 1.96 ' 1.96 inches = 5cm + +Sub LoadAnnotation(pElement As Signature, ...) + oAnnotation.Left = CSng(pElement.X) ' Direct assignment ? INCHES + oAnnotation.Top = CSng(pElement.Y) + oAnnotation.Width = CSng(pElement.Width) + oAnnotation.Height = CSng(pElement.Height) +End Sub +``` + +### Conversion Formulas ``` -Unit : 1/100 inch (DX units) — DevExpress XtraReports native -Origin : Top-left corner of page -X : increases rightward -Y : increases downward +Inches ? DevExpress (DX): x_DX = x_inches * 100.0 + y_DX = y_inches * 100.0 -A4 in DX units: Width = 827, Height = 1169 +Inches ? PDF Points: x_pt = x_inches * 72.0 + y_pt = x_inches * 72.0 -Conversions: - PSPDFKit (pt, top-left): xDX = xPsPdf * (100/72) - GDPicture (pt, bottom-left): yDX = (pageHeightPt - yGD - elemHeightPt) * (100/72) - DX ? PDF points: pt = dx * (72/100) +Inches ? PDF.js Canvas: normalize to [0,1], then scale to pixels + x_norm = x_inches / pageWidth_inches + y_norm = y_inches / pageHeight_inches + x_px = x_norm * canvasWidth * scale * dpr + y_px = y_norm * canvasHeight * scale * dpr ``` +### Unit Comparison Table + +| System | Unit | Origin | Conversion from INCHES | +|--------|------|--------|------------------------| +| **GdPicture14** (Source) | **Inches** | Top-left | Database format (no conversion) | +| DevExpress (LEGACY) | 1/100 inch (DX) | Top-left | `x_DX = x_inches * 100` | +| PDF.js (NEW) | Pixels | Top-left | `normalize ? scale` | +| PDF Points (iText7) | Points (1/72") | **Bottom-left** | `x_pt = x_inches * 72` + Y-flip | +| PSPDFKit (Web) | Points (1/72") | Top-left | `x_pt = x_inches * 72` | + +**A4 Page Dimensions:** +- Width: 8.27 inches = 595 points = 827 DX units +- Height: 11.69 inches = 842 points = 1169 DX units + --- ## EnvelopeViewer (NEW) — PDF.js Read-Only Viewer diff --git a/EnvelopeGenerator.Application/Common/Dto/AnnotationDto.cs b/EnvelopeGenerator.Application/Common/Dto/AnnotationDto.cs index 320d1895..14a38a7a 100644 --- a/EnvelopeGenerator.Application/Common/Dto/AnnotationDto.cs +++ b/EnvelopeGenerator.Application/Common/Dto/AnnotationDto.cs @@ -37,26 +37,29 @@ public record AnnotationCreateDto /// /// Horizontal position of the signature field on the page. ///

- /// DevExpress unit: Hundredths of an inch (1/100 inch ≈ 2.83 PDF points), origin at the top-left corner of the page, X increases to the right. + /// Unit: INCHES (GdPicture14 native), origin at the top-left corner of the page, X increases to the right. ///
- /// Difference from PSPDFKit: PSPDFKit also uses top-left origin but measures in PDF points (1/72 inch). - /// To convert: xDevExpress = xPsPdfKit * (100.0 / 72.0) + /// Conversion to DevExpress: Multiply by 100 (DX uses 1/100 inch). + /// Convert: xDX = xInches * 100.0 ///
- /// Difference from GDPicture: GDPicture uses PDF points with bottom-left origin (standard PDF coordinate system). - /// The X axis is the same direction, only unit conversion is needed: xDevExpress = xGdPicture * (100.0 / 72.0) + /// Conversion to PDF Points: Multiply by 72 (PSPDFKit, iText7 use 1/72 inch). + /// Convert: xPt = xInches * 72.0 ///
public double? X { get; init; } /// /// Vertical position of the signature field on the page. ///

- /// DevExpress unit: Hundredths of an inch (1/100 inch ≈ 2.83 PDF points), origin at the top-left corner of the page, Y increases downward. + /// Unit: INCHES (GdPicture14 native), origin at the top-left corner of the page, Y increases downward. ///
- /// Difference from PSPDFKit: PSPDFKit also uses top-left origin and Y increases downward, but measures in PDF points (1/72 inch). - /// To convert: yDevExpress = yPsPdfKit * (100.0 / 72.0) + /// Conversion to DevExpress: Multiply by 100 (DX uses 1/100 inch). + /// Convert: yDX = yInches * 100.0 ///
- /// Difference from GDPicture: GDPicture uses PDF points with bottom-left origin, so Y increases upward (PDF standard). - /// To convert: yDevExpress = (pageHeightInPt - yGdPicture - elementHeightInPt) * (100.0 / 72.0) + /// Conversion to PDF Points (top-left origin): Multiply by 72. + /// Convert: yPt = yInches * 72.0 + ///
+ /// Conversion to PDF Points (bottom-left origin - iText7): Y-flip required. + /// Convert: yPt = (pageHeightInches - yInches - elemHeightInches) * 72.0 ///
public double? Y { get; init; } diff --git a/EnvelopeGenerator.ReceiverUI/Models/AnnotationDto.cs b/EnvelopeGenerator.ReceiverUI/Models/AnnotationDto.cs index f0172832..ced9c039 100644 --- a/EnvelopeGenerator.ReceiverUI/Models/AnnotationDto.cs +++ b/EnvelopeGenerator.ReceiverUI/Models/AnnotationDto.cs @@ -3,15 +3,17 @@ namespace EnvelopeGenerator.ReceiverUI.Models; /// /// Represents a pre-assigned signature annotation position on a specific page. ///

-/// Coordinate unit (X, Y): Hundredths of an inch (1/100 inch ? 2.83 PDF points), +/// Coordinate unit (X, Y): Inches (GdPicture14 native unit), /// origin at the top-left corner of the page, both axes increase downward/rightward. -/// This matches the DevExpress XtraReports coordinate system (). ///

-/// Difference from PSPDFKit: Same origin (top-left) and direction, but PSPDFKit uses PDF points (1/72 inch). -/// Convert: xDX = xPsPdf * (100.0 / 72.0) +/// Conversion to DevExpress: Multiply by 100 (DX uses 1/100 inch). +/// Convert: xDX = xInches * 100.0 ///
-/// Difference from GDPicture: GDPicture uses PDF points with bottom-left origin (PDF standard); Y is flipped. -/// Convert: yDX = (pageHeightPt - yGD - elemHeightPt) * (100.0 / 72.0) +/// Conversion to PDF Points: Multiply by 72 (1 inch = 72 points). +/// Convert: xPt = xInches * 72.0 +///
+/// Y-axis for PDF (bottom-left origin): Flip required for iText7. +/// Convert: yPt = (pageHeightInches - yInches - elemHeightInches) * 72.0 ///
[Obsolete("Use SignatureDto with SignatureService.")] public record AnnotationDto @@ -22,9 +24,9 @@ public record AnnotationDto /// 1-based page number within the document. public int Page { get; init; } - /// Horizontal position in hundredths of an inch from the left edge of the page. + /// Horizontal position in INCHES from the left edge of the page. public double X { get; init; } - /// Vertical position in hundredths of an inch from the top edge of the page. + /// Vertical position in INCHES from the top edge of the page. public double Y { get; init; } } diff --git a/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs b/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs index 8c5acc35..2d90ebc3 100644 --- a/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs +++ b/EnvelopeGenerator.ReceiverUI/Models/SignatureDto.cs @@ -1,13 +1,22 @@ namespace EnvelopeGenerator.ReceiverUI.Models; +/// +/// Represents a signature position on a PDF page. +/// Coordinates stored in INCHES (GdPicture14 native unit). +/// Origin: Top-left corner, X increases right, Y increases down. +/// public class SignatureDto { + /// Unique identifier. public int Id { get; set; } + /// Horizontal position in INCHES from left edge. public double X { get; set; } + /// Vertical position in INCHES from top edge. public double Y { get; set; } + /// 1-based page number. public int Page { get; set; } } \ No newline at end of file