diff options
author | Julian Offenhäuser <offenhaeuser@protonmail.com> | 2022-11-23 11:27:39 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-11-25 22:44:47 +0100 |
commit | e06a0655940fd580ac21a39edf9071f92c06790a (patch) | |
tree | 670a73bedbf8ce110966706e3585aea8a2f6f1cd /Userland/Libraries/LibPDF | |
parent | 65ff80e8a546fc80a501b1bb53ec36ecd2b6b7f3 (diff) | |
download | serenity-e06a0655940fd580ac21a39edf9071f92c06790a.zip |
LibPDF: Override Type 1 character mappings by encoding in font dict
If the font dictionary includes an "Encoding" entry, it will be used
instead of the PS1FontProgram's built-in encoding.
Diffstat (limited to 'Userland/Libraries/LibPDF')
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp | 32 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/Type1Font.cpp | 6 |
3 files changed, 24 insertions, 16 deletions
diff --git a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp index b91158e4cc..ef328d9a2c 100644 --- a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp +++ b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp @@ -44,7 +44,7 @@ enum ExtendedCommand { SetCurrentPoint = 33, }; -PDFErrorOr<void> PS1FontProgram::parse(ReadonlyBytes const& bytes, size_t cleartext_length, size_t encrypted_length) +PDFErrorOr<void> PS1FontProgram::create(ReadonlyBytes const& bytes, RefPtr<Encoding> encoding, size_t cleartext_length, size_t encrypted_length) { Reader reader(bytes); if (reader.remaining() == 0) @@ -57,22 +57,28 @@ PDFErrorOr<void> PS1FontProgram::parse(ReadonlyBytes const& bytes, size_t cleart if (!seek_name(reader, CommonNames::Encoding)) return error("Missing encoding array"); - if (TRY(parse_word(reader)) == "StandardEncoding") { - m_encoding = Encoding::standard_encoding(); + if (encoding) { + // 9.6.6.2 Encodings for Type 1 Fonts: + // An Encoding entry may override a Type 1 font’s mapping from character codes to character names. + m_encoding = encoding; } else { - HashMap<u16, CharDescriptor> descriptors; + if (TRY(parse_word(reader)) == "StandardEncoding") { + m_encoding = Encoding::standard_encoding(); + } else { + HashMap<u16, CharDescriptor> descriptors; - while (reader.remaining()) { - auto word = TRY(parse_word(reader)); - if (word == "readonly") { - break; - } else if (word == "dup") { - u32 char_code = TRY(parse_int(reader)); - auto name = TRY(parse_word(reader)); - descriptors.set(char_code, { name.starts_with('/') ? name.substring_view(1) : name.view(), char_code }); + while (reader.remaining()) { + auto word = TRY(parse_word(reader)); + if (word == "readonly") { + break; + } else if (word == "dup") { + u32 char_code = TRY(parse_int(reader)); + auto name = TRY(parse_word(reader)); + descriptors.set(char_code, { name.starts_with('/') ? name.substring_view(1) : name.view(), char_code }); + } } + m_encoding = TRY(Encoding::create(descriptors)); } - m_encoding = TRY(Encoding::create(descriptors)); } bool found_font_matrix = seek_name(reader, "FontMatrix"); diff --git a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h index 91291473fa..b576bdc31c 100644 --- a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h +++ b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h @@ -18,7 +18,7 @@ class Encoding; class PS1FontProgram : public RefCounted<PS1FontProgram> { public: - PDFErrorOr<void> parse(ReadonlyBytes const&, size_t cleartext_length, size_t encrypted_length); + PDFErrorOr<void> create(ReadonlyBytes const&, RefPtr<Encoding>, size_t cleartext_length, size_t encrypted_length); RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width); Gfx::Path build_char(u32 char_code, float width); diff --git a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp index bc4533bcc1..a49fac75e3 100644 --- a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp +++ b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp @@ -31,8 +31,10 @@ PDFErrorOr<Type1Font::Data> Type1Font::parse_data(Document* document, NonnullRef auto length2 = font_file_dict->get_value(CommonNames::Length2).get<int>(); data.font_program = adopt_ref(*new PS1FontProgram()); - TRY(data.font_program->parse(font_file_stream->bytes(), length1, length2)); - data.encoding = data.font_program->encoding(); + TRY(data.font_program->create(font_file_stream->bytes(), data.encoding, length1, length2)); + + if (!data.encoding) + data.encoding = data.font_program->encoding(); } return data; |