summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF
diff options
context:
space:
mode:
authorJulian Offenhäuser <offenhaeuser@protonmail.com>2022-11-23 11:27:39 +0100
committerAndreas Kling <kling@serenityos.org>2022-11-25 22:44:47 +0100
commite06a0655940fd580ac21a39edf9071f92c06790a (patch)
tree670a73bedbf8ce110966706e3585aea8a2f6f1cd /Userland/Libraries/LibPDF
parent65ff80e8a546fc80a501b1bb53ec36ecd2b6b7f3 (diff)
downloadserenity-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.cpp32
-rw-r--r--Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h2
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1Font.cpp6
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;