Handle TrueType case in CidFontFactory where the font is CFF, implement missing members in PdfCidCompactFontFormatFont and fix #554
Some checks failed
Build and test / build (push) Has been cancelled
Build and test [MacOS] / build (push) Has been cancelled
Run Integration Tests / build (push) Has been cancelled
Nightly Release / tests (push) Has been cancelled
Nightly Release / Check latest commit (push) Has been cancelled
Nightly Release / build_and_publish_nightly (push) Has been cancelled

This commit is contained in:
BobLd 2025-05-19 00:04:48 +01:00
parent e4d7805a1f
commit 67d3dde04a
4 changed files with 88 additions and 5 deletions

View File

@ -7,6 +7,26 @@
public class GithubIssuesTests
{
[Fact]
public void Issue554()
{
var path = IntegrationHelpers.GetSpecificTestDocumentPath("2022.pdf");
using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true }))
{
for (int p = 1; p <= document.NumberOfPages; p++)
{
var page = document.GetPage(p);
Assert.NotNull(page.Letters);
if (p < document.NumberOfPages)
{
Assert.NotEmpty(page.Letters);
}
}
}
}
[Fact]
public void Issue822()
{

View File

@ -28,7 +28,8 @@
FontDetails WithWeightValues(bool isBold, int weight) => new FontDetails(null, isBold, weight, font.ItalicAngle != 0);
return (font.Weight?.ToLowerInvariant()) switch {
return (font.Weight?.ToLowerInvariant()) switch
{
"light" => WithWeightValues(false, 300),
"semibold" => WithWeightValues(true, 600),
"bold" => WithWeightValues(true, FontDetails.BoldWeight),
@ -61,17 +62,34 @@
public bool TryGetBoundingBox(int characterIdentifier, Func<int, int?> characterCodeToGlyphId, out PdfRectangle boundingBox)
{
throw new NotImplementedException();
var font = GetFont();
int? glyphId = characterCodeToGlyphId.Invoke(characterIdentifier);
string name = glyphId.HasValue
? GetCharacterName(glyphId.Value)
: GetCharacterName(characterIdentifier);
PdfRectangle? tempBbox = font.GetCharacterBoundingBox(name);
if (tempBbox.HasValue)
{
boundingBox = tempBbox.Value;
return true;
}
boundingBox = default;
return false;
}
public bool TryGetBoundingAdvancedWidth(int characterIdentifier, Func<int, int?> characterCodeToGlyphId, out double width)
{
throw new NotImplementedException();
return TryGetBoundingAdvancedWidth(characterIdentifier, out width);
}
public bool TryGetBoundingAdvancedWidth(int characterIdentifier, out double width)
{
throw new NotImplementedException();
width = double.NaN;
return false;
}
public int GetFontMatrixMultiplier()
@ -136,7 +154,25 @@
public bool TryGetPath(int characterCode, Func<int, int?> characterCodeToGlyphId, out IReadOnlyList<PdfSubpath> path)
{
throw new NotImplementedException();
path = null;
int? glyphId = characterCodeToGlyphId.Invoke(characterCode);
string characterName = glyphId.HasValue
? GetCharacterName(glyphId.Value)
: GetCharacterName(characterCode);
if (string.Equals(characterName, GlyphList.NotDefined, StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (GetFont().TryGetPath(characterName, out path))
{
return true;
}
return false;
}
}
}

View File

@ -109,6 +109,13 @@
{
case DescriptorFontFile.FontFileType.TrueType:
{
if (IsTrueTypeCff(fontFile.Span))
{
logger.Warn("The CID TrueType font has the signature of a CFF font. Using CID CFF instead.");
var font = CompactFontFormatParser.Parse(new CompactFontFormatData(fontFile));
return new PdfCidCompactFontFormatFont(font);
}
var input = new TrueTypeDataBytes(new MemoryInputBytes(fontFile));
var ttf = TrueTypeFontParser.Parse(input);
return new PdfCidTrueTypeFont(ttf);
@ -328,5 +335,25 @@
return string.Empty;
}
private static bool IsTrueTypeCff(ReadOnlySpan<byte> data)
{
if (data.Length < 4)
{
return false;
}
// See https://docs.fileformat.com/font/cff/
// https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
byte major = data[0]; // Major version
byte minor = data[1]; // Minor version
byte hdrSize = data[2]; // Header size
byte offSize = data[3]; // Absolute offset
return major == 0x01 &&
minor == 0x00 &&
hdrSize >= 0x04 &&
offSize >= 0x01 && offSize <= 0x04;
}
}
}