summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Offenhäuser <offenhaeuser@protonmail.com>2023-03-24 22:22:33 +0100
committerAndrew Kaster <andrewdkaster@gmail.com>2023-03-25 16:27:30 -0600
commitfec7ccf020785f05d62e28d5ca609b04a1893c5b (patch)
treea4928ed5aeb7de2467ae9053461ca345e75c200f
parent2b3a41be74a3e80929c538ad2cd669171e9c1435 (diff)
downloadserenity-fec7ccf020785f05d62e28d5ca609b04a1893c5b.zip
LibPDF: Ask OpenType font programs for glyph widths if needed
If the font dictionary didn't specify custom glyph widths, we would fall back to the specified "missing width" (or 0 in most cases!), which meant that we would draw glyphs on top of each other in a lot of cases, namely for TrueTypeFonts or standard Type1Fonts with an OpenType fallback. What we actually want to do in this case is ask the OpenType font for the correct width.
-rw-r--r--Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp15
-rw-r--r--Userland/Libraries/LibPDF/Fonts/SimpleFont.h3
-rw-r--r--Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp8
-rw-r--r--Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h1
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1Font.cpp5
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1Font.h1
6 files changed, 21 insertions, 12 deletions
diff --git a/Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp b/Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp
index 358e22024a..303aef9d08 100644
--- a/Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/SimpleFont.cpp
@@ -45,17 +45,18 @@ PDFErrorOr<void> SimpleFont::initialize(Document* document, NonnullRefPtr<DictOb
return {};
}
-float SimpleFont::get_char_width(u8 char_code) const
-{
- return static_cast<float>(m_widths.get(char_code).value_or(m_missing_width)) / 1000.0f;
-}
-
PDFErrorOr<Gfx::FloatPoint> SimpleFont::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Color const& paint_color, float font_size, float character_spacing, float horizontal_scaling)
{
auto so = make_object<StringObject>(string, true);
for (auto char_code : string.bytes()) {
- auto char_width = get_char_width(char_code);
- auto glyph_width = char_width * font_size;
+ // Use the width specified in the font's dictionary if available,
+ // and use the default width for the given font otherwise.
+ float glyph_width;
+ if (auto width = m_widths.get(char_code); width.has_value())
+ glyph_width = font_size * width.value() / 1000.0f;
+ else
+ glyph_width = get_glyph_width(char_code);
+
draw_glyph(painter, glyph_position, glyph_width, char_code, paint_color);
auto tx = glyph_width;
tx += character_spacing;
diff --git a/Userland/Libraries/LibPDF/Fonts/SimpleFont.h b/Userland/Libraries/LibPDF/Fonts/SimpleFont.h
index 61bc7b2eed..8137a2ef46 100644
--- a/Userland/Libraries/LibPDF/Fonts/SimpleFont.h
+++ b/Userland/Libraries/LibPDF/Fonts/SimpleFont.h
@@ -17,13 +17,12 @@ public:
protected:
PDFErrorOr<void> initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) override;
+ virtual float get_glyph_width(u8 char_code) const = 0;
virtual void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u8 char_code, Color color) = 0;
RefPtr<Encoding>& encoding() { return m_encoding; }
RefPtr<Encoding> const& encoding() const { return m_encoding; }
private:
- float get_char_width(u8 char_code) const;
-
RefPtr<Encoding> m_encoding;
RefPtr<StreamObject> m_to_unicode;
HashMap<u8, u16> m_widths;
diff --git a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp
index 6a943a08c4..a35680bd51 100644
--- a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.cpp
@@ -30,11 +30,13 @@ PDFErrorOr<void> TrueTypeFont::initialize(Document* document, NonnullRefPtr<Dict
return {};
}
-void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u8 char_code, Color color)
+float TrueTypeFont::get_glyph_width(u8 char_code) const
{
- if (!m_font)
- return;
+ return m_font->glyph_width(char_code);
+}
+void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u8 char_code, Color color)
+{
// Account for the reversed font baseline
auto position = point.translated(0, -m_font->baseline());
painter.draw_glyph(position, char_code, *m_font, color);
diff --git a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h
index 02fba97f5b..240b7da4fe 100644
--- a/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h
+++ b/Userland/Libraries/LibPDF/Fonts/TrueTypeFont.h
@@ -14,6 +14,7 @@ namespace PDF {
class TrueTypeFont : public SimpleFont {
public:
+ float get_glyph_width(u8 char_code) const override;
void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u8, Color) override;
Type type() const override { return PDFFont::Type::TrueType; }
diff --git a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp
index 49a828e3d8..c9cf6c2e05 100644
--- a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp
@@ -49,6 +49,11 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
return {};
}
+float Type1Font::get_glyph_width(u8 char_code) const
+{
+ return m_font->glyph_width(char_code);
+}
+
void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u8 char_code, Color color)
{
if (!m_font_program) {
diff --git a/Userland/Libraries/LibPDF/Fonts/Type1Font.h b/Userland/Libraries/LibPDF/Fonts/Type1Font.h
index c85df6d7b0..c780804323 100644
--- a/Userland/Libraries/LibPDF/Fonts/Type1Font.h
+++ b/Userland/Libraries/LibPDF/Fonts/Type1Font.h
@@ -14,6 +14,7 @@ namespace PDF {
class Type1Font : public SimpleFont {
public:
+ float get_glyph_width(u8 char_code) const override;
void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u8 char_code, Color color) override;
Type type() const override { return PDFFont::Type::Type1; }