From 35c1374b9c7f6434aaa02258e5f160900b32ea7a Mon Sep 17 00:00:00 2001 From: TekH Date: Tue, 25 Aug 2026 09:47:22 +0200 Subject: [PATCH] Update text truncation logic to use rendered width Replaced character-based truncation with pixel-accurate truncation based on rendered width in inches. Updated `TruncateText` in `PDFBurner.vb` to use `Graphics.MeasureString` for width calculation and introduced a binary search for efficient truncation. Renamed `egName` to `fieldEgName` for clarity. Replaced `TextMaxLengths` with `TextMaxWidths` in `PDFBurnerParams.vb`, specifying maximum render widths in inches. Updated default values for `position`, `city`, and `date`. Revised XML documentation to reflect the new truncation logic. --- .../Jobs/FinalizeDocument/PDFBurner.vb | 40 +++++++++++++++---- .../Jobs/FinalizeDocument/PDFBurnerParams.vb | 13 +++--- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb index c8042978..05a8ee10 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurner.vb @@ -311,20 +311,44 @@ Namespace Jobs.FinalizeDocument #Region "Helpers" ''' - ''' Truncates a field value to the configured max length for that egName. + ''' Truncates a field value so its rendered width fits within the configured max width (inches). + ''' Uses Graphics.MeasureString with the configured font for pixel-accurate measurement. ''' Appends TruncationSuffix when the value is cut. ''' - Private Function TruncateText(value As String, egName As String) As String + Private Function TruncateText(value As String, fieldEgName As String) As String If String.IsNullOrEmpty(value) Then Return value - If _pdfBurnerParams.TextMaxLengths Is Nothing Then Return value + If _pdfBurnerParams.TextMaxWidths 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 maxWidthInches As Single = 0 + If Not _pdfBurnerParams.TextMaxWidths.TryGetValue(fieldEgName, maxWidthInches) Then Return value + If maxWidthInches <= 0 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 + + Using bmp As New Bitmap(1, 1) + Using g As Graphics = Graphics.FromImage(bmp) + Dim font As New Font(_pdfBurnerParams.FontName, _pdfBurnerParams.FontSize, _pdfBurnerParams.FontStyle, GraphicsUnit.Point) + Dim maxWidthPx As Single = maxWidthInches * g.DpiX + + ' Already fits — no truncation needed + If g.MeasureString(value, font).Width <= maxWidthPx Then Return value + + ' Binary search for the longest prefix that fits (with suffix) + Dim lo As Integer = 0 + Dim hi As Integer = value.Length + While lo < hi + Dim mid As Integer = (lo + hi + 1) \ 2 + Dim candidate As String = value.Substring(0, mid) & suffix + If g.MeasureString(candidate, font).Width <= maxWidthPx Then + lo = mid + Else + hi = mid - 1 + End If + End While + + Return value.Substring(0, lo) & suffix + End Using + End Using End Function diff --git a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb index f34f5848..10f85e36 100644 --- a/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb +++ b/EnvelopeGenerator.CommonServices/Jobs/FinalizeDocument/PDFBurnerParams.vb @@ -20,15 +20,16 @@ Namespace Jobs.FinalizeDocument 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. + ''' Per-field maximum render width in inches. + ''' Text is measured using the configured Font/FontSize via Graphics.MeasureString (pixel-accurate). + ''' If the rendered width exceeds the limit, the text 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} + Public Property TextMaxWidths As New Dictionary(Of String, Single) From { + {"position", 1.25F}, + {"city", 1.25F}, + {"date", 2.0F} } End Class End Namespace \ No newline at end of file