mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:07:34 +00:00
LibPDF/CFF: Implement some special handling for CID-keyed fonts
* FDArray, FDSelect must be present * Encoding must not be present * Charset maps from GID (Glyph ID) to CID (Character ID), instead of to character name
This commit is contained in:
parent
7494f24430
commit
1d1e406b3a
1 changed files with 61 additions and 39 deletions
|
@ -128,6 +128,21 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
|
||||
if (top_dict.is_cid_keyed) {
|
||||
// CFF spec, "18 CID-keyed Fonts"
|
||||
// "* The FDArray operator is expected to be present"
|
||||
if (top_dict.fdarray_offset == 0)
|
||||
return error("CID-keyed CFFs must have an FDArray");
|
||||
|
||||
// "* The charset data, although in the same format as non-CIDFonts, will represent CIDs rather than SIDs"
|
||||
// (Done below.)
|
||||
|
||||
// "* The Top DICT will include an FDSelect operator"
|
||||
if (top_dict.fdselect_offset == 0)
|
||||
return error("CID-keyed CFFs must have FDSelect");
|
||||
|
||||
// "* no Encoding operator will be present and the default StandardEncoding should not be applied"
|
||||
if (top_dict.encoding_offset != 0)
|
||||
return error("CID-keyed CFFs must not have Encoding");
|
||||
|
||||
cff->set_kind(CFF::Kind::CIDKeyed);
|
||||
}
|
||||
|
||||
|
@ -148,6 +163,7 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
// 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.
|
||||
if (!top_dict.is_cid_keyed) {
|
||||
switch (top_dict.encoding_offset) {
|
||||
case 0:
|
||||
dbgln_if(CFF_DEBUG, "CFF predefined encoding Standard");
|
||||
|
@ -163,9 +179,14 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
encoding_codes = TRY(parse_encoding(Reader(cff_bytes.slice(top_dict.encoding_offset)), encoding_supplemental));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CFF spec, "Table 22 Charset ID"
|
||||
Vector<DeprecatedFlyString> charset_names;
|
||||
Vector<SID> charset; // Maps GID to CIDs for CID-keyed, to SIDs otherwise.
|
||||
Vector<DeprecatedFlyString> charset_names; // Only valid for non-CID-keyed fonts.
|
||||
if (top_dict.is_cid_keyed) {
|
||||
charset = TRY(parse_charset(Reader { cff_bytes.slice(top_dict.charset_offset) }, glyphs.size()));
|
||||
} else {
|
||||
switch (top_dict.charset_offset) {
|
||||
case 0:
|
||||
dbgln_if(CFF_DEBUG, "CFF predefined charset ISOAdobe");
|
||||
|
@ -184,12 +205,13 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
TRY(charset_names.try_append(resolve_sid(sid, strings)));
|
||||
break;
|
||||
default: {
|
||||
auto charset = TRY(parse_charset(Reader { cff_bytes.slice(top_dict.charset_offset) }, glyphs.size()));
|
||||
charset = TRY(parse_charset(Reader { cff_bytes.slice(top_dict.charset_offset) }, glyphs.size()));
|
||||
for (SID sid : charset)
|
||||
TRY(charset_names.try_append(resolve_sid(sid, strings)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CFF spec, "18 CID-keyed Fonts"
|
||||
if (top_dict.fdarray_offset != 0) {
|
||||
|
@ -226,7 +248,7 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
if (encoding) {
|
||||
dbgln_if(CFF_DEBUG, "CFF using external encoding");
|
||||
cff->set_encoding(move(encoding));
|
||||
} else {
|
||||
} else if (!top_dict.is_cid_keyed) {
|
||||
dbgln_if(CFF_DEBUG, "CFF using embedded encoding");
|
||||
auto encoding = Encoding::create();
|
||||
for (size_t i = 0; i < glyphs.size(); i++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue