diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb index cb6dc3d0..c8042978 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb @@ -119,7 +119,7 @@ Namespace Jobs.FinalizeDocument Dim y = frameY + yOffsetofFF If annot.Type = AnnotationType.FormField Then - AddFormFieldValue(annot.X / inchFactor, y, annot.Width / inchFactor, annot.Height / inchFactor, element.Page, annot.Value) + AddFormFieldValue(annot.X / inchFactor, y, annot.Width / inchFactor, annot.Height / inchFactor, element.Page, annot.Value, annot.Name) ElseIf annot.Type = AnnotationType.Image Then AddImageAnnotation( annot.X / inchFactor, @@ -269,11 +269,14 @@ Namespace Jobs.FinalizeDocument Next End Sub - Private Sub AddFormFieldValue(x As Double, y As Double, width As Double, height As Double, page As Integer, value As String) + Private Sub AddFormFieldValue(x As Double, y As Double, width As Double, height As Double, page As Integer, value As String, Optional egName As String = "") Manager.SelectPage(page) + ' Truncate if needed + Dim displayValue As String = TruncateText(value, egName) + ' Add the text annotation - Dim ant = Manager.AddTextAnnot(x, y, width, height, value) + Dim ant = Manager.AddTextAnnot(x, y, width, height, displayValue) ' Set the font properties ant.FontName = _pdfBurnerParams.FontName @@ -294,8 +297,9 @@ Namespace Jobs.FinalizeDocument Dim oHeight = oBounds.Item(3) Manager.SelectPage(pAnnotation.pageIndex + 1) - ' Add the text annotation - Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value) + ' Add the text annotation (truncate if needed) + Dim displayValue As String = TruncateText(formFieldValue.value, pAnnotation.egName) + Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, displayValue) ' Set the font properties ant.FontName = _pdfBurnerParams.FontName @@ -306,6 +310,24 @@ Namespace Jobs.FinalizeDocument #End Region #Region "Helpers" + ''' + ''' Truncates a field value to the configured max length for that egName. + ''' Appends TruncationSuffix when the value is cut. + ''' + Private Function TruncateText(value As String, egName As String) As String + If String.IsNullOrEmpty(value) Then Return value + If _pdfBurnerParams.TextMaxLengths Is Nothing Then Return value + + Dim maxLen As Integer = 0 + If Not _pdfBurnerParams.TextMaxLengths.TryGetValue(egName, maxLen) Then Return value + If maxLen <= 0 OrElse value.Length <= maxLen Then Return value + + Dim suffix As String = If(_pdfBurnerParams.TruncationSuffix, "") + Dim cutAt As Integer = Math.Max(0, maxLen - suffix.Length) + Return value.Substring(0, cutAt) & suffix + End Function + + Private Function ToPointF(pPoints As List(Of Single)) As PointF Dim oPoints = pPoints.Select(AddressOf ToInches).ToList() Return New PointF(oPoints.Item(0), oPoints.Item(1)) diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb index 019db1fb..f34f5848 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb @@ -12,5 +12,23 @@ Namespace Jobs.FinalizeDocument Public Property FontSize As Integer = 8 Public Property FontStyle As FontStyle = FontStyle.Italic + + ''' + ''' The suffix appended to a truncated field value. Defaults to "..". + ''' Can be changed to any string (e.g. "…", "...", ""). + ''' + Public Property TruncationSuffix As String = ".." + + ''' + ''' Per-field maximum character count (including the TruncationSuffix). + ''' If a value exceeds the limit it is cut and TruncationSuffix is appended. + ''' Keys must match egName values used in PDFBurner (e.g. "name", "position", "city", "date"). + ''' Set a value to 0 to disable truncation for that field. + ''' + Public Property TextMaxLengths As New Dictionary(Of String, Integer) From { + {"position", 20}, + {"city", 20}, + {"date", 28} + } End Class End Namespace \ No newline at end of file diff --git a/EnvelopeGenerator.sln b/EnvelopeGenerator.sln index b30bc02e..f382ca86 100644 --- a/EnvelopeGenerator.sln +++ b/EnvelopeGenerator.sln @@ -23,6 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{134D4164-B29 ProjectSection(SolutionItems) = preProject COPILOT_CONTEXT.md = COPILOT_CONTEXT.md fix-report-label-read-and-confirmed.md = fix-report-label-read-and-confirmed.md + fix-signature-field-formatting.md = fix-signature-field-formatting.md FORM_APPLICATION_CONTEXT.md = FORM_APPLICATION_CONTEXT.md RECEIVER_PDF_VIEWER_CONTEXT.md = RECEIVER_PDF_VIEWER_CONTEXT.md EndProjectSection diff --git a/fix-signature-field-formatting.md b/fix-signature-field-formatting.md new file mode 100644 index 00000000..b411dc22 --- /dev/null +++ b/fix-signature-field-formatting.md @@ -0,0 +1,111 @@ +# Signature Field Formatting — WISAG Feedback + +## Context + +Customer feedback received from the new WISAG signFLOW project lead (email dated 3/7/2026). +The signature stamp rendered inside the finalized PDF has layout issues that need to be addressed. + +### Current State (screenshot from customer email) + +``` +Signiert von ___________ +[ signature image ] +Armin Schneider +C6B85E96A520C60... ← certificate hash, too close to name +Bereichsleiter Kern- ← position text wraps, no spacing to date +Anwendungen +Frankfurt am Main +23.06.2026, 17:13:42 GMT+2 +``` + +### Issues Reported + +1. **Spacing between name and certificate number** is too small — needs more vertical gap. +2. **Spacing between position/title and date/time** is too small — should be dynamic (expand with content). +3. *(Secondary, out of scope here)* Multiple signature fields side-by-side scale individually, causing uneven heights. + +--- + +## Agreed Solution + +> **"Height stays fixed. Text stretches horizontally. Beyond a certain character limit, truncate with '...'"** +> *(Original: "Höhe bleibt fix. Text dehnt sich horizontal aus. Ab einem bestimmten Limit wird mit '...' abgekürzt.")* + +### Rationale + +- The signature field dimensions are **fixed** (`1.77" × 1.96"`). Allowing text to wrap causes position and date rows to collide vertically. +- Truncating long strings with ellipsis (`...`) keeps the layout deterministic and prevents overflow. +- Per-field max-length limits allow tuning each text row independently (name, certificate, position, city, date). + +--- + +## Implementation Plan + +### 1. `PDFBurnerParams.vb` — Add per-field max-length dictionary + +Add a new property `TextMaxLengths` that maps each field name (matching `EGName` keys) to a maximum character count. + +```vbnet +' EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb + +Public Property TextMaxLengths As New Dictionary(Of String, Integer) From { + {"name", 28}, + {"position", 32}, + {"city", 24}, + {"date", 28} +} +``` + +Default values are starting points and should be tuned against real customer data. + +### 2. `PDFBurner.vb` — Add truncation helper and apply in `AddFormFieldValue` + +#### 2a. Add a private helper function + +```vbnet +Private Function TruncateText(value As String, fieldName As String) As String + If String.IsNullOrEmpty(value) Then Return value + + Dim maxLen As Integer = 0 + If _pdfBurnerParams.TextMaxLengths IsNot Nothing AndAlso + _pdfBurnerParams.TextMaxLengths.TryGetValue(fieldName, maxLen) AndAlso + maxLen > 0 AndAlso value.Length > maxLen Then + Return value.Substring(0, maxLen - 3) & "..." + End If + + Return value +End Function +``` + +#### 2b. Apply truncation in the `egName`-aware overload + +In `AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue)`: + +```vbnet +' Before passing value to AddTextAnnot, truncate: +Dim displayValue As String = TruncateText(formFieldValue.value, pAnnotation.egName) + +Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, displayValue) +``` + +#### 2c. Apply truncation in the element-based overload (optional) + +In `AddFormFieldValue(x, y, width, height, page, value)` — if a field name is available in calling context, pass it through; otherwise this path does not use `egName` and truncation can be skipped or applied with a generic fallback key. + +--- + +## Affected Files + +| File | Change | +|------|--------| +| `EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb` | Add `TextMaxLengths As Dictionary(Of String, Integer)` | +| `EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb` | Add `TruncateText()` helper; apply in `AddFormFieldValue` overloads | + +--- + +## Notes + +- Field names (`"name"`, `"position"`, `"city"`, `"date"`) must match the keys used in `EGName.Index` dictionary (`PDFBurner.vb:443–450`). +- The certificate hash field (e.g. `C6B85E96A520C60...`) is already truncated upstream — verify its `egName` mapping if it needs its own limit. +- The `YOffset` / `TopMargin` values in `PDFBurnerParams` may also need adjustment to increase vertical spacing between rows. That is a separate (simpler) change. +- This issue is **not** related to the Blazor WebUI rendering — it is purely in the GdPicture14 PDF burning pipeline.