mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-21 18:37:58 +03:00
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.
This commit is contained in:
parent
2b3a41be74
commit
fec7ccf020
Notes:
sideshowbarker
2024-07-16 22:19:47 +09:00
Author: https://github.com/janso3 Commit: https://github.com/SerenityOS/serenity/commit/fec7ccf020 Pull-request: https://github.com/SerenityOS/serenity/pull/18031 Reviewed-by: https://github.com/ADKaster ✅
@ -45,17 +45,18 @@ PDFErrorOr<void> SimpleFont::initialize(Document* document, NonnullRefPtr<DictOb
|
|||||||
return {};
|
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)
|
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);
|
auto so = make_object<StringObject>(string, true);
|
||||||
for (auto char_code : string.bytes()) {
|
for (auto char_code : string.bytes()) {
|
||||||
auto char_width = get_char_width(char_code);
|
// Use the width specified in the font's dictionary if available,
|
||||||
auto glyph_width = char_width * font_size;
|
// 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);
|
draw_glyph(painter, glyph_position, glyph_width, char_code, paint_color);
|
||||||
auto tx = glyph_width;
|
auto tx = glyph_width;
|
||||||
tx += character_spacing;
|
tx += character_spacing;
|
||||||
|
@ -17,13 +17,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
PDFErrorOr<void> initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) override;
|
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;
|
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>& encoding() { return m_encoding; }
|
||||||
RefPtr<Encoding> const& encoding() const { return m_encoding; }
|
RefPtr<Encoding> const& encoding() const { return m_encoding; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float get_char_width(u8 char_code) const;
|
|
||||||
|
|
||||||
RefPtr<Encoding> m_encoding;
|
RefPtr<Encoding> m_encoding;
|
||||||
RefPtr<StreamObject> m_to_unicode;
|
RefPtr<StreamObject> m_to_unicode;
|
||||||
HashMap<u8, u16> m_widths;
|
HashMap<u8, u16> m_widths;
|
||||||
|
@ -30,11 +30,13 @@ PDFErrorOr<void> TrueTypeFont::initialize(Document* document, NonnullRefPtr<Dict
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TrueTypeFont::get_glyph_width(u8 char_code) const
|
||||||
|
{
|
||||||
|
return m_font->glyph_width(char_code);
|
||||||
|
}
|
||||||
|
|
||||||
void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u8 char_code, Color color)
|
void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u8 char_code, Color color)
|
||||||
{
|
{
|
||||||
if (!m_font)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Account for the reversed font baseline
|
// Account for the reversed font baseline
|
||||||
auto position = point.translated(0, -m_font->baseline());
|
auto position = point.translated(0, -m_font->baseline());
|
||||||
painter.draw_glyph(position, char_code, *m_font, color);
|
painter.draw_glyph(position, char_code, *m_font, color);
|
||||||
|
@ -14,6 +14,7 @@ namespace PDF {
|
|||||||
|
|
||||||
class TrueTypeFont : public SimpleFont {
|
class TrueTypeFont : public SimpleFont {
|
||||||
public:
|
public:
|
||||||
|
float get_glyph_width(u8 char_code) const override;
|
||||||
void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u8, Color) override;
|
void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u8, Color) override;
|
||||||
Type type() const override { return PDFFont::Type::TrueType; }
|
Type type() const override { return PDFFont::Type::TrueType; }
|
||||||
|
|
||||||
|
@ -49,6 +49,11 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
|||||||
return {};
|
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)
|
void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u8 char_code, Color color)
|
||||||
{
|
{
|
||||||
if (!m_font_program) {
|
if (!m_font_program) {
|
||||||
|
@ -14,6 +14,7 @@ namespace PDF {
|
|||||||
|
|
||||||
class Type1Font : public SimpleFont {
|
class Type1Font : public SimpleFont {
|
||||||
public:
|
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;
|
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; }
|
Type type() const override { return PDFFont::Type::Type1; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user