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

LibPDF: Postpone CFF encoding processing after Top DICT has been read

The encoding offset defaults to 0, i.e. the Standard Encoding.
That means reading the encoding only if the tag is present causes
us to not read it if a font uses the Standard Encoding.

Now, we always read an encoding, even if it's the (implicit) default
one.
This commit is contained in:
Nico Weber 2023-10-16 16:28:13 -04:00 committed by Andreas Kling
parent 1cfe639b6c
commit eeada4678c

View file

@ -72,8 +72,7 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
// CFF spec, "8 Top DICT INDEX" // CFF spec, "8 Top DICT INDEX"
int charset_offset = 0; int charset_offset = 0;
Vector<u8> encoding_codes; // Maps GID to its codepoint. int encoding_offset = 0;
HashMap<Card8, SID> encoding_supplemental; // Maps codepoint to SID.
auto charstrings_offset = 0; auto charstrings_offset = 0;
Vector<ByteBuffer> subroutines; Vector<ByteBuffer> subroutines;
float defaultWidthX = 0; float defaultWidthX = 0;
@ -113,22 +112,8 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
dbgln("CFF: has unimplemented SyntheticBase, might not look right"); dbgln("CFF: has unimplemented SyntheticBase, might not look right");
break; break;
case TopDictOperator::Encoding: { case TopDictOperator::Encoding: {
auto encoding_offset = 0;
if (!operands.is_empty()) if (!operands.is_empty())
encoding_offset = operands[0].get<int>(); encoding_offset = operands[0].get<int>();
// CFF spec, "Table 16 Encoding ID"
switch (encoding_offset) {
case 0:
dbgln("CFF: Built-in Standard Encoding not yet implemented");
break;
case 1:
dbgln("CFF: Built-in Expert Encoding not yet implemented");
break;
default:
encoding_codes = TRY(parse_encoding(Reader(cff_bytes.slice(encoding_offset)), encoding_supplemental));
break;
}
break; break;
} }
case TopDictOperator::Charset: { case TopDictOperator::Charset: {
@ -186,6 +171,22 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
// Create glyphs (now that we have the subroutines) and associate missing information to store them and their encoding // Create glyphs (now that we have the subroutines) and associate missing information to store them and their encoding
auto glyphs = TRY(parse_charstrings(Reader(cff_bytes.slice(charstrings_offset)), subroutines)); auto glyphs = TRY(parse_charstrings(Reader(cff_bytes.slice(charstrings_offset)), subroutines));
// CFF spec, "Table 16 Encoding ID"
// FIXME: Only read this if the built-in encoding is actually needed? (ie. `if (!encoding)`)
Vector<u8> encoding_codes; // Maps GID to its codepoint.
HashMap<Card8, SID> encoding_supplemental; // Maps codepoint to SID.
switch (encoding_offset) {
case 0:
dbgln("CFF: Built-in Standard Encoding not yet implemented");
break;
case 1:
dbgln("CFF: Built-in Expert Encoding not yet implemented");
break;
default:
encoding_codes = TRY(parse_encoding(Reader(cff_bytes.slice(encoding_offset)), encoding_supplemental));
break;
}
// CFF spec, "Table 22 Charset ID" // CFF spec, "Table 22 Charset ID"
Vector<DeprecatedFlyString> charset; Vector<DeprecatedFlyString> charset;
switch (charset_offset) { switch (charset_offset) {