From bb7d29d00795c9b2e4ba70032d7c292426a47e06 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 14 Feb 2024 07:58:05 -0500 Subject: [PATCH] LibPDF/CFF: Read font dicts pointed to by the fdarray offset The fdselect array (that we already read) maps eachs glyph ID to an fdarray index. The font dict at that index then stores information for that glyph. In practice, this is used to assign different defaultWidthX / nominalWidthX values to blocks of glyphs in CID-keyed fonts. We don't do anything yet with the data, and we also don't send data of CID-keyed CFFs into this parser either, so no behavior change. --- Userland/Libraries/LibPDF/Fonts/CFF.cpp | 12 +++++++++++- Userland/Libraries/LibPDF/Fonts/CFF.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.cpp b/Userland/Libraries/LibPDF/Fonts/CFF.cpp index 89db34ddb8..54fd327638 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.cpp +++ b/Userland/Libraries/LibPDF/Fonts/CFF.cpp @@ -186,6 +186,13 @@ PDFErrorOr> CFF::create(ReadonlyBytes const& cff_bytes, RefPt } } + // CFF spec, "18 CID-keyed Fonts" + if (top_dict.fdarray_offset != 0) { + Reader fdarray_reader { cff_bytes.slice(top_dict.fdarray_offset) }; + auto font_dicts = TRY(parse_top_dicts(fdarray_reader, cff_bytes)); + dbgln_if(CFF_DEBUG, "CFF has {} FDArray entries", font_dicts.size()); + } + // CFF spec, "19 FDSelect" if (top_dict.fdselect_offset != 0) { auto fdselect = TRY(parse_fdselect(Reader { cff_bytes.slice(top_dict.fdselect_offset) }, glyphs.size())); @@ -347,12 +354,15 @@ PDFErrorOr> CFF::parse_top_dicts(Reader& reader, ReadonlyBy if (!operands.is_empty()) top_dict.fdselect_offset = operands[0].get(); break; + case TopDictOperator::FDArray: + if (!operands.is_empty()) + top_dict.fdarray_offset = operands[0].get(); + break; case TopDictOperator::CIDFontVersion: case TopDictOperator::CIDFontRevision: case TopDictOperator::CIDFontType: case TopDictOperator::CIDCount: case TopDictOperator::UIDBase: - case TopDictOperator::FDArray: case TopDictOperator::FontName: // Keys for CID-keyed fonts that we don't need, at least at the moment. break; diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.h b/Userland/Libraries/LibPDF/Fonts/CFF.h index c884094437..ee3735cffd 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.h +++ b/Userland/Libraries/LibPDF/Fonts/CFF.h @@ -127,6 +127,7 @@ public: float defaultWidthX = 0; float nominalWidthX = 0; int fdselect_offset = 0; + int fdarray_offset = 0; }; static PDFErrorOr> parse_top_dicts(Reader&, ReadonlyBytes const& cff_bytes);