diff --git a/src/UglyToad.PdfPig.Fonts/TrueType/Parser/TrueTypeFontParser.cs b/src/UglyToad.PdfPig.Fonts/TrueType/Parser/TrueTypeFontParser.cs
index d2e11b344..8f57a032e 100644
--- a/src/UglyToad.PdfPig.Fonts/TrueType/Parser/TrueTypeFontParser.cs
+++ b/src/UglyToad.PdfPig.Fonts/TrueType/Parser/TrueTypeFontParser.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Tables;
+ using UglyToad.PdfPig.Fonts.CompactFontFormat;
///
/// Parses TrueType fonts.
@@ -59,7 +60,36 @@ public static TrueTypeFont Parse(TrueTypeDataBytes data)
private static TrueTypeFont ParseTables(float version, IReadOnlyDictionary tables, TrueTypeDataBytes data)
{
- var isPostScript = tables.ContainsKey(TrueTypeHeaderTable.Cff);
+ bool isPostScript = false;
+ CompactFontFormatFontCollection? cffFontCollection = null;
+
+ if (tables.TryGetValue(TrueTypeHeaderTable.Cff, out var cffTable))
+ {
+ isPostScript = true;
+ try
+ {
+ /*
+ * The presence of a CFF (Compact Font Format) table in a TrueType font creates a hybrid situation where the font
+ * container uses TrueType structure but contains PostScript-based glyph descriptions. According to the OpenType
+ * specification, when a TrueType font contains a CFF table instead of a traditional glyf table, it indicates
+ * "an OpenType font with PostScript outlines". This creates what's known as an OpenType CFF font, which uses
+ * PostScript Type 2 charstrings for glyph descriptions rather than TrueType quadratic curves.
+ *
+ * This is to fix P2P-33713919.pdf
+ * See https://github.com/BobLd/PdfPig.Rendering.Skia/issues/46
+ * TODO - Add test coverage and need to review if the logic belongs here
+ */
+
+ data.Seek(cffTable.Offset);
+ var buffer = data.ReadByteArray((int)cffTable.Length);
+ cffFontCollection = CompactFontFormatParser.Parse(new CompactFontFormatData(buffer));
+ }
+ catch (Exception e)
+ {
+ System.Diagnostics.Debug.WriteLine(e);
+ // Ignore
+ }
+ }
var builder = new TableRegister.Builder();
@@ -102,7 +132,7 @@ private static TrueTypeFont ParseTables(float version, IReadOnlyDictionary(os2Table, data, builder);
}
-
+
if (!isPostScript)
{
if (!tables.TryGetValue(TrueTypeHeaderTable.Loca, out var indexToLocationHeaderTable))
@@ -125,7 +155,7 @@ private static TrueTypeFont ParseTables(float version, IReadOnlyDictionary
/// A TrueType font.
@@ -54,17 +55,33 @@ public sealed class TrueTypeFont
///
public int NumberOfTables { get; }
+ // TODO - It would be better to use 'PdfCidCompactFontFormatFont' but the class is not accessible from here.
+ private readonly CompactFontFormatFontCollection? cffFontCollection;
+
///
/// Create a new .
///
- internal TrueTypeFont(float version, IReadOnlyDictionary tableHeaders, TableRegister tableRegister)
+ internal TrueTypeFont(float version, IReadOnlyDictionary tableHeaders, TableRegister tableRegister, CompactFontFormatFontCollection? cffFontCollection)
{
Version = version;
TableHeaders = tableHeaders ?? throw new ArgumentNullException(nameof(tableHeaders));
TableRegister = tableRegister ?? throw new ArgumentNullException(nameof(tableRegister));
NumberOfTables = tableHeaders.Count;
- if (TableRegister.CMapTable != null)
+ /*
+ * The presence of a CFF (Compact Font Format) table in a TrueType font creates a hybrid situation where the font
+ * container uses TrueType structure but contains PostScript-based glyph descriptions. According to the OpenType
+ * specification, when a TrueType font contains a CFF table instead of a traditional glyf table, it indicates
+ * "an OpenType font with PostScript outlines". This creates what's known as an OpenType CFF font, which uses
+ * PostScript Type 2 charstrings for glyph descriptions rather than TrueType quadratic curves.
+ *
+ * This is to fix P2P-33713919.pdf
+ * See https://github.com/BobLd/PdfPig.Rendering.Skia/issues/46
+ * TODO - Add test coverage and need to review if the logic belongs here
+ */
+ this.cffFontCollection = cffFontCollection;
+
+ if (TableRegister.CMapTable is not null)
{
const int encodingSymbol = 0;
const int encodingUnicode = 1;
@@ -72,19 +89,19 @@ internal TrueTypeFont(float version, IReadOnlyDictionary characterCodeTo
{
boundingBox = default(PdfRectangle);
- if (TableRegister.GlyphTable == null)
+ if (TableRegister.GlyphTable is null)
{
+ if (cffFontCollection is not null)
+ {
+ /*
+ * The presence of a CFF (Compact Font Format) table in a TrueType font creates a hybrid situation where the font
+ * container uses TrueType structure but contains PostScript-based glyph descriptions. According to the OpenType
+ * specification, when a TrueType font contains a CFF table instead of a traditional glyf table, it indicates
+ * "an OpenType font with PostScript outlines". This creates what's known as an OpenType CFF font, which uses
+ * PostScript Type 2 charstrings for glyph descriptions rather than TrueType quadratic curves.
+ *
+ * This is to fix P2P-33713919.pdf
+ * See https://github.com/BobLd/PdfPig.Rendering.Skia/issues/46
+ * TODO - Add test coverage and need to review if the logic belongs here
+ */
+
+ var name = cffFontCollection.FirstFont.GetCharacterName(characterCode, true); // TODO cid?
+ if (string.IsNullOrEmpty(name))
+ {
+ return false;
+ }
+
+ var bbox = cffFontCollection.FirstFont.GetCharacterBoundingBox(name);
+ if (bbox.HasValue)
+ {
+ boundingBox = bbox.Value;
+ return true;
+ }
+ }
+
return false;
}
@@ -143,8 +188,30 @@ public bool TryGetPath(int characterCode, Func characterCodeToGlyphId
{
path = null;
- if (TableRegister.GlyphTable == null)
+ if (TableRegister.GlyphTable is null)
{
+ if (cffFontCollection is not null)
+ {
+ /*
+ * The presence of a CFF (Compact Font Format) table in a TrueType font creates a hybrid situation where the font
+ * container uses TrueType structure but contains PostScript-based glyph descriptions. According to the OpenType
+ * specification, when a TrueType font contains a CFF table instead of a traditional glyf table, it indicates
+ * "an OpenType font with PostScript outlines". This creates what's known as an OpenType CFF font, which uses
+ * PostScript Type 2 charstrings for glyph descriptions rather than TrueType quadratic curves.
+ *
+ * This is to fix P2P-33713919.pdf
+ * See https://github.com/BobLd/PdfPig.Rendering.Skia/issues/46
+ * TODO - Add test coverage and need to review if the logic belongs here
+ */
+
+ var name = cffFontCollection.FirstFont.GetCharacterName(characterCode, true);
+ if (string.IsNullOrEmpty(name))
+ {
+ return false;
+ }
+ return cffFontCollection.FirstFont.TryGetPath(name, out path);
+ }
+
return false;
}
@@ -188,7 +255,7 @@ private bool TryGetBoundingAdvancedWidthByIndex(int index, out double width)
{
width = 0;
- if (TableRegister.HorizontalMetricsTable == null)
+ if (TableRegister.HorizontalMetricsTable is null)
{
return false;
}
@@ -210,7 +277,7 @@ private bool TryGetGlyphIndex(int characterIdentifier, Func character
return true;
}
- if (TableRegister.CMapTable == null)
+ if (TableRegister.CMapTable is null)
{
return false;
}