From 3a3993999504cf2f234625ab7e04267800f63dae Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 6 Mar 2024 18:40:19 -0500 Subject: [PATCH] LibPDF: Make truetype fonts marked as symbol fonts actually work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out the spec didn't mean that the whole range is populated, but that one of these ranges is populated. So take the argmax. As fallout, explicitly mark the Liberation fonts as nonsymbolic when we use them for the 14 standard fonts. Else, we'd regress "PostScrõpt", since the Liberation fonts would otherwise go down the "is symbolic or doesn't have explicit encoding" codepath, since the standard fonts usually don't have an explicit encoding. As a fallout from _that_, since the 14 standard fonts now go down the regular truetype rendering path, and since we don't implement lookup by postscript name yet, glyphs not present in Liberation now cause text to stop rendering with a diag, instead of rendering a "glyph not found" symbol. That isn't super common, only an additional 4 files appear for the "'post' table not yet implemented" diag. Since we'll implement that soon, this seems fine until then. --- Userland/Libraries/LibPDF/Fonts/PDFFont.h | 9 +++++-- .../Libraries/LibPDF/Fonts/TrueTypeFont.cpp | 27 ++++++++++--------- Userland/Libraries/LibPDF/Fonts/Type1Font.cpp | 11 +++++++- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Userland/Libraries/LibPDF/Fonts/PDFFont.h b/Userland/Libraries/LibPDF/Fonts/PDFFont.h index 07c29b75cc7..9ad1b524ad0 100644 --- a/Userland/Libraries/LibPDF/Fonts/PDFFont.h +++ b/Userland/Libraries/LibPDF/Fonts/PDFFont.h @@ -39,10 +39,15 @@ public: // TABLE 5.20 Font flags bool is_fixed_pitch() const { return m_flags & (1 << (1 - 1)); } bool is_serif() const { return m_flags & (1 << (2 - 1)); } - bool is_symbolic() const { return m_flags & (1 << (3 - 1)); } + + static constexpr unsigned Symbolic = 1 << (3 - 1); + bool is_symbolic() const { return m_flags & Symbolic; } + bool is_script() const { return m_flags & (1 << (4 - 1)); } + // Note: No bit position 5. - bool is_nonsymbolic() const { return m_flags & (1 << (6 - 1)); } + static constexpr unsigned NonSymbolic = 1 << (6 - 1); + bool is_nonsymbolic() const { return m_flags & NonSymbolic; } bool is_italic() const { return m_flags & (1 << (7 - 1)); } // Note: Big jump in bit positions. bool is_all_cap() const { return m_flags & (1 << (17 - 1)); } diff --git a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp index 8a13a7afc55..ecb5828ffab 100644 --- a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp +++ b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp @@ -37,23 +37,26 @@ NonnullOwnPtr TrueTypePainter::create(Document* document, Nonnu } } - // See long spec comment in TrueTypeFont::draw_glyp(). + // See long spec comment in TrueTypeFont::draw_glyph(). Optional high_byte; if (!dict->contains(CommonNames::Encoding) || containing_pdf_font.is_symbolic()) { - // FIXME: Looks like this is never hit in the test set (?). - for (u8 prefix : { 0x00, 0xF0, 0xF1, 0xF2 }) { - bool has_all = true; + Array prefixes { 0x00, 0xF0, 0xF1, 0xF2 }; + Array counts { 0, 0, 0, 0 }; + for (size_t i = 0; i < prefixes.size(); ++i) { for (unsigned suffix = 0x00; suffix <= 0xFF; ++suffix) { - if (!font->contains_glyph((prefix << 8) | suffix)) { - has_all = false; - break; - } - } - if (has_all) { - high_byte = prefix; - break; + if (font->contains_glyph((prefixes[i] << 8) | suffix)) + counts[i] += 1; } } + size_t max = 0, max_index = -1; + for (size_t i = 0; i < counts.size(); ++i) { + if (counts[i] > max) { + max = counts[i]; + max_index = i; + } + } + if (max > 0) + high_byte = max_index; } return adopt_own(*new TrueTypePainter { move(font), move(encoding), encoding_is_mac_roman_or_win_ansi, containing_pdf_font.is_nonsymbolic(), high_byte, is_zapf_dingbats }); diff --git a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp index 8f290c65d75..35d32dcc321 100644 --- a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp +++ b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp @@ -54,6 +54,10 @@ PDFErrorOr Type1Font::initialize(Document* document, NonnullRefPtr Type1Font::initialize(Document* document, NonnullRefPtr