1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:07:36 +00:00

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.
This commit is contained in:
Nico Weber 2024-02-14 07:58:05 -05:00 committed by Andreas Kling
parent 524a4f6256
commit bb7d29d007
2 changed files with 12 additions and 1 deletions

View file

@ -186,6 +186,13 @@ PDFErrorOr<NonnullRefPtr<CFF>> 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<Vector<CFF::TopDict>> CFF::parse_top_dicts(Reader& reader, ReadonlyBy
if (!operands.is_empty())
top_dict.fdselect_offset = operands[0].get<int>();
break;
case TopDictOperator::FDArray:
if (!operands.is_empty())
top_dict.fdarray_offset = operands[0].get<int>();
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;

View file

@ -127,6 +127,7 @@ public:
float defaultWidthX = 0;
float nominalWidthX = 0;
int fdselect_offset = 0;
int fdarray_offset = 0;
};
static PDFErrorOr<Vector<TopDict>> parse_top_dicts(Reader&, ReadonlyBytes const& cff_bytes);