mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:17:36 +00:00
LibPDF: Use subpixel accurate text rendering
This just enables the new tricks from LibGfx with the same nice improvements :^)
This commit is contained in:
parent
6632023498
commit
91db49f7b3
9 changed files with 24 additions and 18 deletions
|
@ -41,7 +41,7 @@ public:
|
|||
virtual u32 char_code_to_code_point(u16 char_code) const = 0;
|
||||
virtual float get_char_width(u16 char_code) const = 0;
|
||||
|
||||
virtual void draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color) = 0;
|
||||
virtual void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color) = 0;
|
||||
|
||||
virtual bool is_standard_font() const { return m_is_standard_font; }
|
||||
virtual Type type() const = 0;
|
||||
|
|
|
@ -94,15 +94,16 @@ PDFErrorOr<void> PS1FontProgram::create(ReadonlyBytes const& bytes, RefPtr<Encod
|
|||
return parse_encrypted_portion(decrypted);
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width)
|
||||
RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset)
|
||||
{
|
||||
auto path = build_char(char_code, width);
|
||||
auto bounding_box = path.bounding_box().size();
|
||||
|
||||
u32 w = (u32)ceilf(bounding_box.width()) + 1;
|
||||
u32 h = (u32)ceilf(bounding_box.height()) + 1;
|
||||
u32 w = (u32)ceilf(bounding_box.width()) + 2;
|
||||
u32 h = (u32)ceilf(bounding_box.height()) + 2;
|
||||
|
||||
Gfx::PathRasterizer rasterizer(Gfx::IntSize(w, h));
|
||||
rasterizer.translate(subpixel_offset.to_float_point());
|
||||
rasterizer.draw_path(path);
|
||||
return rasterizer.accumulate();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <AK/Forward.h>
|
||||
#include <LibGfx/AffineTransform.h>
|
||||
#include <LibGfx/Font/Font.h>
|
||||
#include <LibGfx/Path.h>
|
||||
#include <LibPDF/Error.h>
|
||||
|
||||
|
@ -20,7 +21,7 @@ class PS1FontProgram : public RefCounted<PS1FontProgram> {
|
|||
public:
|
||||
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);
|
||||
RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset);
|
||||
Gfx::Path build_char(u32 char_code, float width);
|
||||
|
||||
RefPtr<Encoding> encoding() const { return m_encoding; }
|
||||
|
|
|
@ -68,7 +68,7 @@ float TrueTypeFont::get_char_width(u16 char_code) const
|
|||
return static_cast<float>(width) / 1000.0f;
|
||||
}
|
||||
|
||||
void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float, u32 char_code, Color color)
|
||||
void TrueTypeFont::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float, u32 char_code, Color color)
|
||||
{
|
||||
if (!m_data.font)
|
||||
return;
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
u32 char_code_to_code_point(u16 char_code) const override;
|
||||
float get_char_width(u16 char_code) const override;
|
||||
|
||||
void draw_glyph(Gfx::Painter&, Gfx::IntPoint, float, u32, Color) override;
|
||||
void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u32, Color) override;
|
||||
|
||||
Type type() const override { return PDFFont::Type::TrueType; }
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
u32 char_code_to_code_point(u16 char_code) const override;
|
||||
float get_char_width(u16 char_code) const override;
|
||||
|
||||
void draw_glyph(Gfx::Painter&, Gfx::IntPoint, float, u32, Color) override {};
|
||||
void draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u32, Color) override {};
|
||||
|
||||
Type type() const override { return PDFFont::Type::Type0; }
|
||||
|
||||
|
|
|
@ -76,23 +76,26 @@ float Type1Font::get_char_width(u16 char_code) const
|
|||
return static_cast<float>(width) / 1000.0f;
|
||||
}
|
||||
|
||||
void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color)
|
||||
void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color)
|
||||
{
|
||||
if (!m_data.font_program)
|
||||
return;
|
||||
auto translation = m_data.font_program->glyph_translation(char_code, width);
|
||||
point = point.translated(translation);
|
||||
|
||||
auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(point);
|
||||
Gfx::GlyphIndexWithSubpixelOffset index { char_code, glyph_position.subpixel_offset };
|
||||
|
||||
RefPtr<Gfx::Bitmap> bitmap;
|
||||
|
||||
auto maybe_bitmap = m_glyph_cache.get(char_code);
|
||||
auto maybe_bitmap = m_glyph_cache.get(index);
|
||||
if (maybe_bitmap.has_value()) {
|
||||
bitmap = maybe_bitmap.value();
|
||||
} else {
|
||||
bitmap = m_data.font_program->rasterize_glyph(char_code, width);
|
||||
m_glyph_cache.set(char_code, bitmap);
|
||||
bitmap = m_data.font_program->rasterize_glyph(char_code, width, glyph_position.subpixel_offset);
|
||||
m_glyph_cache.set(index, bitmap);
|
||||
}
|
||||
|
||||
auto translation = m_data.font_program->glyph_translation(char_code, width);
|
||||
painter.blit_filtered(point.translated(translation.to_rounded<int>()), *bitmap, bitmap->rect(), [color](Color pixel) -> Color {
|
||||
painter.blit_filtered(glyph_position.blit_position, *bitmap, bitmap->rect(), [color](Color pixel) -> Color {
|
||||
return pixel.multiply(color);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/Font/ScaledFont.h>
|
||||
#include <LibPDF/Fonts/PDFFont.h>
|
||||
#include <LibPDF/Fonts/PS1FontProgram.h>
|
||||
|
||||
|
@ -27,13 +28,13 @@ public:
|
|||
u32 char_code_to_code_point(u16 char_code) const override;
|
||||
float get_char_width(u16 char_code) const override;
|
||||
|
||||
void draw_glyph(Gfx::Painter& painter, Gfx::IntPoint point, float width, u32 char_code, Color color) override;
|
||||
void draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color) override;
|
||||
|
||||
Type type() const override { return PDFFont::Type::Type1; }
|
||||
|
||||
private:
|
||||
Data m_data;
|
||||
HashMap<u32, RefPtr<Gfx::Bitmap>> m_glyph_cache;
|
||||
HashMap<Gfx::GlyphIndexWithSubpixelOffset, RefPtr<Gfx::Bitmap>> m_glyph_cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -747,7 +747,7 @@ void Renderer::show_text(DeprecatedString const& string)
|
|||
auto glyph_width = char_width * font_size;
|
||||
|
||||
if (code_point != 0x20)
|
||||
text_state().font->draw_glyph(m_painter, glyph_position.to_type<int>(), glyph_width, char_code, state().paint_color);
|
||||
text_state().font->draw_glyph(m_painter, glyph_position, glyph_width, char_code, state().paint_color);
|
||||
|
||||
auto tx = glyph_width;
|
||||
tx += text_state().character_spacing;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue