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.
This commit is contained in:
@@ -311,20 +311,44 @@ Namespace Jobs.FinalizeDocument
|
|||||||
|
|
||||||
#Region "Helpers"
|
#Region "Helpers"
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' 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.
|
''' Appends TruncationSuffix when the value is cut.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
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 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
|
Dim maxWidthInches As Single = 0
|
||||||
If Not _pdfBurnerParams.TextMaxLengths.TryGetValue(egName, maxLen) Then Return value
|
If Not _pdfBurnerParams.TextMaxWidths.TryGetValue(fieldEgName, maxWidthInches) Then Return value
|
||||||
If maxLen <= 0 OrElse value.Length <= maxLen Then Return value
|
If maxWidthInches <= 0 Then Return value
|
||||||
|
|
||||||
Dim suffix As String = If(_pdfBurnerParams.TruncationSuffix, "")
|
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
|
End Function
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,16 @@ Namespace Jobs.FinalizeDocument
|
|||||||
Public Property TruncationSuffix As String = ".."
|
Public Property TruncationSuffix As String = ".."
|
||||||
|
|
||||||
''' <summary>
|
''' <summary>
|
||||||
''' Per-field maximum character count (including the TruncationSuffix).
|
''' Per-field maximum render width in inches.
|
||||||
''' If a value exceeds the limit it is cut and TruncationSuffix is appended.
|
''' 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").
|
''' 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.
|
''' Set a value to 0 to disable truncation for that field.
|
||||||
''' </summary>
|
''' </summary>
|
||||||
Public Property TextMaxLengths As New Dictionary(Of String, Integer) From {
|
Public Property TextMaxWidths As New Dictionary(Of String, Single) From {
|
||||||
{"position", 20},
|
{"position", 1.25F},
|
||||||
{"city", 20},
|
{"city", 1.25F},
|
||||||
{"date", 28}
|
{"date", 2.0F}
|
||||||
}
|
}
|
||||||
End Class
|
End Class
|
||||||
End Namespace
|
End Namespace
|
||||||
Reference in New Issue
Block a user