1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 09:07:44 +00:00

LibGfx+LibPDF: Apply subpixel offset in affine transformation

This commit is contained in:
MacDue 2023-01-05 11:17:47 +00:00 committed by Andreas Kling
parent 6c85088952
commit eeb6072f15
6 changed files with 15 additions and 15 deletions

View file

@ -351,8 +351,10 @@ RefPtr<Gfx::Bitmap> Glyf::Glyph::rasterize_simple(i16 font_ascender, i16 font_de
u32 width = (u32)(ceilf((m_xmax - m_xmin) * x_scale)) + 2; u32 width = (u32)(ceilf((m_xmax - m_xmin) * x_scale)) + 2;
u32 height = (u32)(ceilf((font_ascender - font_descender) * y_scale)) + 2; u32 height = (u32)(ceilf((font_ascender - font_descender) * y_scale)) + 2;
Gfx::PathRasterizer rasterizer(Gfx::IntSize(width, height)); Gfx::PathRasterizer rasterizer(Gfx::IntSize(width, height));
rasterizer.translate(subpixel_offset.to_float_point()); auto affine = Gfx::AffineTransform()
auto affine = Gfx::AffineTransform().scale(x_scale, -y_scale).translate(-m_xmin, -font_ascender); .translate(subpixel_offset.to_float_point())
.scale(x_scale, -y_scale)
.translate(-m_xmin, -font_ascender);
rasterize_impl(rasterizer, affine); rasterize_impl(rasterizer, affine);
return rasterizer.accumulate(); return rasterizer.accumulate();
} }

View file

@ -126,8 +126,10 @@ public:
u32 width = (u32)(ceilf((m_xmax - m_xmin) * x_scale)) + 1; u32 width = (u32)(ceilf((m_xmax - m_xmin) * x_scale)) + 1;
u32 height = (u32)(ceilf((font_ascender - font_descender) * y_scale)) + 1; u32 height = (u32)(ceilf((font_ascender - font_descender) * y_scale)) + 1;
Gfx::PathRasterizer rasterizer(Gfx::IntSize(width, height)); Gfx::PathRasterizer rasterizer(Gfx::IntSize(width, height));
rasterizer.translate(subpixel_offset.to_float_point()); auto affine = Gfx::AffineTransform()
auto affine = Gfx::AffineTransform().scale(x_scale, -y_scale).translate(-m_xmin, -font_ascender); .translate(subpixel_offset.to_float_point())
.scale(x_scale, -y_scale)
.translate(-m_xmin, -font_ascender);
rasterize_composite_loop(rasterizer, affine, glyph_callback); rasterize_composite_loop(rasterizer, affine, glyph_callback);

View file

@ -20,7 +20,7 @@ PathRasterizer::PathRasterizer(Gfx::IntSize size)
void PathRasterizer::draw_path(Gfx::Path& path) void PathRasterizer::draw_path(Gfx::Path& path)
{ {
for (auto& line : path.split_lines()) for (auto& line : path.split_lines())
draw_line(line.from.translated(translation()), line.to.translated(translation())); draw_line(line.from, line.to);
} }
RefPtr<Gfx::Bitmap> PathRasterizer::accumulate() RefPtr<Gfx::Bitmap> PathRasterizer::accumulate()

View file

@ -18,15 +18,10 @@ public:
void draw_path(Gfx::Path&); void draw_path(Gfx::Path&);
RefPtr<Gfx::Bitmap> accumulate(); RefPtr<Gfx::Bitmap> accumulate();
void translate(Gfx::FloatPoint delta) { m_translation.translate_by(delta); }
Gfx::FloatPoint translation() const { return m_translation; }
private: private:
void draw_line(Gfx::FloatPoint, Gfx::FloatPoint); void draw_line(Gfx::FloatPoint, Gfx::FloatPoint);
Gfx::IntSize m_size; Gfx::IntSize m_size;
Gfx::FloatPoint m_translation;
Vector<float> m_data; Vector<float> m_data;
}; };

View file

@ -96,26 +96,27 @@ PDFErrorOr<void> PS1FontProgram::create(ReadonlyBytes const& bytes, RefPtr<Encod
RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset) RefPtr<Gfx::Bitmap> PS1FontProgram::rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset)
{ {
auto path = build_char(char_code, width); auto path = build_char(char_code, width, subpixel_offset);
auto bounding_box = path.bounding_box().size(); auto bounding_box = path.bounding_box().size();
u32 w = (u32)ceilf(bounding_box.width()) + 2; u32 w = (u32)ceilf(bounding_box.width()) + 2;
u32 h = (u32)ceilf(bounding_box.height()) + 2; u32 h = (u32)ceilf(bounding_box.height()) + 2;
Gfx::PathRasterizer rasterizer(Gfx::IntSize(w, h)); Gfx::PathRasterizer rasterizer(Gfx::IntSize(w, h));
rasterizer.translate(subpixel_offset.to_float_point());
rasterizer.draw_path(path); rasterizer.draw_path(path);
return rasterizer.accumulate(); return rasterizer.accumulate();
} }
Gfx::Path PS1FontProgram::build_char(u32 char_code, float width) Gfx::Path PS1FontProgram::build_char(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset)
{ {
auto maybe_glyph = m_glyph_map.get(char_code); auto maybe_glyph = m_glyph_map.get(char_code);
if (!maybe_glyph.has_value()) if (!maybe_glyph.has_value())
return {}; return {};
auto& glyph = maybe_glyph.value(); auto& glyph = maybe_glyph.value();
auto transform = glyph_transform_to_device_space(glyph, width); auto transform = Gfx::AffineTransform()
.translate(subpixel_offset.to_float_point())
.multiply(glyph_transform_to_device_space(glyph, width));
// Translate such that the top-left point is at [0, 0]. // Translate such that the top-left point is at [0, 0].
auto bounding_box = glyph.path.bounding_box(); auto bounding_box = glyph.path.bounding_box();

View file

@ -22,7 +22,7 @@ public:
PDFErrorOr<void> create(ReadonlyBytes const&, RefPtr<Encoding>, size_t cleartext_length, size_t encrypted_length); 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, Gfx::GlyphSubpixelOffset); RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset);
Gfx::Path build_char(u32 char_code, float width); Gfx::Path build_char(u32 char_code, float width, Gfx::GlyphSubpixelOffset);
RefPtr<Encoding> encoding() const { return m_encoding; } RefPtr<Encoding> encoding() const { return m_encoding; }
Gfx::FloatPoint glyph_translation(u32 char_code, float width) const; Gfx::FloatPoint glyph_translation(u32 char_code, float width) const;