LibPDF: Make truetype fonts marked as symbol fonts actually work
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.
This commit is contained in:
parent
2e2cae26c6
commit
3a39939995
Notes:
sideshowbarker
2024-07-16 21:42:29 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/3a39939995 Pull-request: https://github.com/SerenityOS/serenity/pull/23498 Reviewed-by: https://github.com/trflynn89
3 changed files with 32 additions and 15 deletions
|
@ -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)); }
|
||||
|
|
|
@ -37,23 +37,26 @@ NonnullOwnPtr<TrueTypePainter> TrueTypePainter::create(Document* document, Nonnu
|
|||
}
|
||||
}
|
||||
|
||||
// See long spec comment in TrueTypeFont::draw_glyp().
|
||||
// See long spec comment in TrueTypeFont::draw_glyph().
|
||||
Optional<u8> 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<u8, 4> prefixes { 0x00, 0xF0, 0xF1, 0xF2 };
|
||||
Array<size_t, prefixes.size()> 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 });
|
||||
|
|
|
@ -54,6 +54,10 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
|||
auto font = TRY(replacement_for(base_font_name().to_lowercase(), font_size));
|
||||
|
||||
auto effective_encoding = encoding();
|
||||
bool is_standard_14_font = base_font_name() == "Helvetica" || base_font_name() == "Helvetica-Bold" || base_font_name() == "Helvetica-Oblique" || base_font_name() == "Helvetica-BoldOblique"
|
||||
|| base_font_name() == "Times-Roman" || base_font_name() == "Times-Bold" || base_font_name() == "Times-Italic" || base_font_name() == "Times-BoldItalic"
|
||||
|| base_font_name() == "Courier" || base_font_name() == "Courier-Bold" || base_font_name() == "Courier-Oblique" || base_font_name() == "Courier-BoldOblique"
|
||||
|| base_font_name() == "Symbol" || base_font_name() == "ZapfDingbats";
|
||||
if (!effective_encoding) {
|
||||
// PDF 1.7 spec, APPENDIX D Character Sets and Encodings
|
||||
// "Sections D.4, “Symbol Set and Encoding,” and D.5, “ZapfDingbats Set and Encoding,”
|
||||
|
@ -73,7 +77,12 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
|||
effective_encoding = Encoding::standard_encoding();
|
||||
}
|
||||
|
||||
// FIXME: For the standard 14 fonts, set some m_flags bits (symbolic/nonsymbolic, italic, bold, fixed pitch, serif).
|
||||
if (is_standard_14_font) {
|
||||
// We use the Liberation fonts as a replacement for the standard 14 fonts, and they're all non-symbolic.
|
||||
m_flags = (m_flags | NonSymbolic) & ~Symbolic;
|
||||
|
||||
// FIXME: Set more m_flags bits (symbolic/nonsymbolic, italic, bold, fixed pitch, serif).
|
||||
}
|
||||
|
||||
m_fallback_font_painter = TrueTypePainter::create(document, dict, *this, *font, *effective_encoding, base_font_name() == "ZapfDingbats"sv);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue