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