From dbeab70d247ed63b3adc73a83309174bb1da8fc6 Mon Sep 17 00:00:00 2001 From: swmal <897655+swmal@users.noreply.github.com> Date: Wed, 30 Sep 2026 16:27:00 +0200 Subject: [PATCH] Fixed ligature bug in PdfToUnicodeCMap --- .../DocumentObjects/Fonts/PdfToUnicodeCMap.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/EPPlus.Export.Pdf/DocumentObjects/Fonts/PdfToUnicodeCMap.cs b/src/EPPlus.Export.Pdf/DocumentObjects/Fonts/PdfToUnicodeCMap.cs index f69f5635c..b751bb2af 100644 --- a/src/EPPlus.Export.Pdf/DocumentObjects/Fonts/PdfToUnicodeCMap.cs +++ b/src/EPPlus.Export.Pdf/DocumentObjects/Fonts/PdfToUnicodeCMap.cs @@ -93,7 +93,10 @@ private string GenerateCMapContent() private void GenerateCharacterMappings(StringBuilder sb) { - var sortedMappings = CharacterMappings.OrderBy(kvp => kvp.Key).ToList(); + var sortedMappings = CharacterMappings + .Where(kvp => !string.IsNullOrEmpty(kvp.Value)) + .OrderBy(kvp => kvp.Key) + .ToList(); var ranges = new List(); var individualMappings = new List(); for (int i = 0; i < sortedMappings.Count; i++) @@ -143,7 +146,7 @@ private void GenerateCharacterMappings(StringBuilder sb) // Output ranges if (ranges.Count > 0) { - sb.AppendFormat($"{ranges.Count} beginbfrange"); + sb.AppendFormat($"{ranges.Count} beginbfrange\n"); foreach (var range in ranges) { sb.AppendFormat($"<{FormatCode(range.Start)}> <{FormatCode(range.End)}> <{FormatUnicode(range.UnicodeStart)}>\n"); @@ -160,14 +163,25 @@ private void GenerateCharacterMappings(StringBuilder sb) sb.AppendFormat($"{batch.Count} beginbfchar\n"); foreach (var mapping in batch) { - string hex = ((int)mapping.Unicode[0]).ToString("X4"); - sb.AppendFormat($"<{FormatCode(mapping.Code)}> <{hex}>\n"); + sb.AppendFormat($"<{FormatCode(mapping.Code)}> <{ToUtf16BeHex(mapping.Unicode)}>\n"); } sb.Append("endbfchar\n"); } } } + private static string ToUtf16BeHex(string text) + { + // .NET strings are already UTF-16, so every char is one UTF-16BE code unit + // and surrogate pairs come out correctly without any special handling. + var sb = new StringBuilder(text.Length * 4); + foreach (char c in text) + { + sb.Append(((int)c).ToString("X4")); + } + return sb.ToString(); + } + private bool TryParseSimpleUnicode(string hexString, out int unicodeValue) { unicodeValue = 0;