LibGfx: Remove code responsible for glyph rasterization

No longer needed after switching to Skia.
This commit is contained in:
Aliaksandr Kalenik 2024-07-27 18:23:55 +03:00 committed by Tim Ledbetter
parent a168bec7ef
commit f61e54b10c
Notes: github-actions[bot] 2024-07-27 17:38:31 +00:00
9 changed files with 0 additions and 182 deletions

View file

@ -9,24 +9,6 @@
namespace Gfx {
GlyphRasterPosition GlyphRasterPosition::get_nearest_fit_for(FloatPoint position)
{
constexpr auto subpixel_divisions = GlyphSubpixelOffset::subpixel_divisions();
auto fit = [](float pos, int& blit_pos, u8& subpixel_offset) {
blit_pos = floorf(pos);
subpixel_offset = round_to<u8>((pos - blit_pos) * subpixel_divisions);
if (subpixel_offset >= subpixel_divisions) {
blit_pos += 1;
subpixel_offset = 0;
}
};
int blit_x, blit_y;
u8 subpixel_x, subpixel_y;
fit(position.x(), blit_x, subpixel_x);
fit(position.y(), blit_y, subpixel_y);
return GlyphRasterPosition { { blit_x, blit_y }, { subpixel_x, subpixel_y } };
}
Font const& Font::bold_variant() const
{
if (m_bold_variant)

View file

@ -19,55 +19,6 @@
namespace Gfx {
class Glyph {
public:
Glyph(NonnullRefPtr<Bitmap> bitmap, float left_bearing, float advance, float ascent, bool is_color_bitmap)
: m_bitmap(bitmap)
, m_left_bearing(left_bearing)
, m_advance(advance)
, m_ascent(ascent)
, m_color_bitmap(is_color_bitmap)
{
}
bool is_color_bitmap() const { return m_color_bitmap; }
[[nodiscard]] NonnullRefPtr<Bitmap> bitmap() const { return m_bitmap; }
float left_bearing() const { return m_left_bearing; }
float advance() const { return m_advance; }
float ascent() const { return m_ascent; }
private:
NonnullRefPtr<Bitmap> m_bitmap;
float m_left_bearing;
float m_advance;
float m_ascent;
bool m_color_bitmap { false };
};
struct GlyphSubpixelOffset {
u8 x;
u8 y;
// TODO: Allow setting this at runtime via some config?
static constexpr int subpixel_divisions() { return 3; }
FloatPoint to_float_point() const { return FloatPoint(x / float(subpixel_divisions()), y / float(subpixel_divisions())); }
bool operator==(GlyphSubpixelOffset const&) const = default;
};
struct GlyphRasterPosition {
// Where the glyph bitmap should be drawn/blitted.
IntPoint blit_position;
// A subpixel offset to be used when rendering the glyph.
// This improves kerning and alignment at the expense of caching a few extra bitmaps.
// This is (currently) snapped to thirds of a subpixel (i.e. 0, 0.33, 0.66).
GlyphSubpixelOffset subpixel_offset;
static GlyphRasterPosition get_nearest_fit_for(FloatPoint position);
};
struct FontPixelMetrics {
float size { 0 };
float x_height { 0 };
@ -118,8 +69,6 @@ public:
virtual int pixel_size_rounded_up() const = 0;
virtual u16 weight() const = 0;
virtual Optional<Glyph> glyph(u32 code_point) const = 0;
virtual Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const = 0;
virtual bool contains_glyph(u32 code_point) const = 0;
virtual bool append_glyph_path_to(Gfx::Path&, u32 glyph_id) const = 0;

View file

@ -566,27 +566,6 @@ bool Typeface::append_glyph_path_to(Gfx::Path& path, u32 glyph_id, float x_scale
return extract_and_append_glyph_path_to(path, glyph_id, ascender_and_descender.ascender, ascender_and_descender.descender, x_scale, y_scale).has_value();
}
RefPtr<Gfx::Bitmap> Typeface::rasterize_glyph(u32 glyph_id, float x_scale, float y_scale, Gfx::GlyphSubpixelOffset subpixel_offset) const
{
if (auto bitmap = color_bitmap(glyph_id))
return bitmap;
auto ascender_and_descender = resolve_ascender_and_descender();
Gfx::Path path;
path.move_to(subpixel_offset.to_float_point());
auto glyph = extract_and_append_glyph_path_to(path, glyph_id, ascender_and_descender.ascender, ascender_and_descender.descender, x_scale, y_scale);
if (!glyph.has_value())
return {};
u32 width = (u32)(ceilf((glyph->xmax() - glyph->xmin()) * x_scale)) + 2;
u32 height = (u32)(ceilf((ascender_and_descender.ascender - ascender_and_descender.descender) * y_scale)) + 2;
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { width, height }).release_value_but_fixme_should_propagate_errors();
Gfx::Painter painter { bitmap };
Gfx::AntiAliasingPainter aa_painter(painter);
aa_painter.fill_path(path, Gfx::Color::White);
return bitmap;
}
u32 Typeface::glyph_count() const
{
return m_maxp.num_glyphs();

View file

@ -58,7 +58,6 @@ public:
virtual Gfx::ScaledGlyphMetrics glyph_metrics(u32 glyph_id, float x_scale, float y_scale, float point_width, float point_height) const override;
virtual float glyph_advance(u32 glyph_id, float x_scale, float y_scale, float point_width, float point_height) const override;
virtual float glyphs_horizontal_kerning(u32 left_glyph_id, u32 right_glyph_id, float x_scale) const override;
virtual RefPtr<Gfx::Bitmap> rasterize_glyph(u32 glyph_id, float x_scale, float y_scale, Gfx::GlyphSubpixelOffset) const override;
virtual bool append_glyph_path_to(Gfx::Path&, u32 glyph_id, float x_scale, float y_scale) const override;
virtual u32 glyph_count() const override;
virtual u16 units_per_em() const override;

View file

@ -63,38 +63,11 @@ ALWAYS_INLINE float ScaledFont::unicode_view_width(T const& view) const
return longest_width;
}
RefPtr<Gfx::Bitmap> ScaledFont::rasterize_glyph(u32 glyph_id, GlyphSubpixelOffset subpixel_offset) const
{
GlyphIndexWithSubpixelOffset index { glyph_id, subpixel_offset };
auto glyph_iterator = m_cached_glyph_bitmaps.find(index);
if (glyph_iterator != m_cached_glyph_bitmaps.end())
return glyph_iterator->value;
auto glyph_bitmap = m_typeface->rasterize_glyph(glyph_id, m_x_scale, m_y_scale, subpixel_offset);
m_cached_glyph_bitmaps.set(index, glyph_bitmap);
return glyph_bitmap;
}
bool ScaledFont::append_glyph_path_to(Gfx::Path& path, u32 glyph_id) const
{
return m_typeface->append_glyph_path_to(path, glyph_id, m_x_scale, m_y_scale);
}
Optional<Glyph> ScaledFont::glyph(u32 code_point) const
{
return glyph(code_point, GlyphSubpixelOffset { 0, 0 });
}
Optional<Glyph> ScaledFont::glyph(u32 code_point, GlyphSubpixelOffset subpixel_offset) const
{
auto id = glyph_id_for_code_point(code_point);
auto bitmap = rasterize_glyph(id, subpixel_offset);
if (!bitmap)
return {};
auto metrics = glyph_metrics(id);
return Gfx::Glyph(*bitmap, metrics.left_side_bearing, metrics.advance_width, metrics.ascender, m_typeface->has_color_bitmaps());
}
float ScaledFont::glyph_left_bearing(u32 code_point) const
{
auto id = glyph_id_for_code_point(code_point);

View file

@ -16,19 +16,11 @@ class SkFont;
namespace Gfx {
struct GlyphIndexWithSubpixelOffset {
u32 glyph_id;
GlyphSubpixelOffset subpixel_offset;
bool operator==(GlyphIndexWithSubpixelOffset const&) const = default;
};
class ScaledFont final : public Gfx::Font {
public:
ScaledFont(NonnullRefPtr<Typeface>, float point_width, float point_height, unsigned dpi_x = DEFAULT_DPI, unsigned dpi_y = DEFAULT_DPI);
ScaledFontMetrics metrics() const { return m_typeface->metrics(m_x_scale, m_y_scale); }
ScaledGlyphMetrics glyph_metrics(u32 glyph_id) const { return m_typeface->glyph_metrics(glyph_id, m_x_scale, m_y_scale, m_point_width, m_point_height); }
RefPtr<Gfx::Bitmap> rasterize_glyph(u32 glyph_id, GlyphSubpixelOffset) const;
// ^Gfx::Font
virtual float point_size() const override;
@ -37,9 +29,7 @@ public:
virtual Gfx::FontPixelMetrics pixel_metrics() const override;
virtual u8 slope() const override { return m_typeface->slope(); }
virtual u16 weight() const override { return m_typeface->weight(); }
virtual Optional<Glyph> glyph(u32 code_point) const override;
virtual float glyph_left_bearing(u32 code_point) const override;
virtual Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const override;
virtual bool contains_glyph(u32 code_point) const override { return m_typeface->glyph_id_for_code_point(code_point) > 0; }
virtual float glyph_width(u32 code_point) const override;
virtual float glyph_or_emoji_width(Utf8CodePointIterator&) const override;
@ -69,7 +59,6 @@ private:
float m_y_scale { 0.0f };
float m_point_width { 0.0f };
float m_point_height { 0.0f };
mutable HashMap<GlyphIndexWithSubpixelOffset, RefPtr<Gfx::Bitmap>> m_cached_glyph_bitmaps;
Gfx::FontPixelMetrics m_pixel_metrics;
float m_pixel_size { 0.0f };
@ -80,15 +69,3 @@ private:
};
}
namespace AK {
template<>
struct Traits<Gfx::GlyphIndexWithSubpixelOffset> : public DefaultTraits<Gfx::GlyphIndexWithSubpixelOffset> {
static unsigned hash(Gfx::GlyphIndexWithSubpixelOffset const& index)
{
return pair_int_hash(index.glyph_id, (index.subpixel_offset.x << 8) | index.subpixel_offset.y);
}
};
}

View file

@ -49,7 +49,6 @@ public:
virtual ScaledGlyphMetrics glyph_metrics(u32 glyph_id, float x_scale, float y_scale, float point_width, float point_height) const = 0;
virtual float glyph_advance(u32 glyph_id, float x_scale, float y_scale, float point_width, float point_height) const = 0;
virtual float glyphs_horizontal_kerning(u32 left_glyph_id, u32 right_glyph_id, float x_scale) const = 0;
virtual RefPtr<Gfx::Bitmap> rasterize_glyph(u32 glyph_id, float x_scale, float y_scale, GlyphSubpixelOffset) const = 0;
virtual bool append_glyph_path_to(Gfx::Path&, u32 glyph_id, float x_scale, float y_scale) const = 0;
virtual u32 glyph_count() const = 0;

View file

@ -836,44 +836,6 @@ void Painter::draw_scaled_bitmap(IntRect const& a_dst_rect, Gfx::Bitmap const& s
}
}
FLATTEN void Painter::draw_glyph(FloatPoint point, u32 code_point, Font const& font, Color color)
{
auto top_left = point + FloatPoint(font.glyph_left_bearing(code_point), 0);
auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(top_left);
auto maybe_glyph = font.glyph(code_point, glyph_position.subpixel_offset);
if (!maybe_glyph.has_value())
return;
auto glyph = maybe_glyph.release_value();
if (glyph.is_color_bitmap()) {
float scaled_width = glyph.advance();
float ratio = static_cast<float>(glyph.bitmap()->height()) / static_cast<float>(glyph.bitmap()->width());
float scaled_height = scaled_width * ratio;
FloatRect rect(point.x(), point.y(), scaled_width, scaled_height);
draw_scaled_bitmap(rect.to_rounded<int>(), *glyph.bitmap(), glyph.bitmap()->rect(), 1.0f, ScalingMode::BilinearBlend);
} else if (color.alpha() != 255) {
blit_filtered(glyph_position.blit_position, *glyph.bitmap(), glyph.bitmap()->rect(), [color](Color pixel) -> Color {
return pixel.multiply(color);
});
} else {
blit_filtered(glyph_position.blit_position, *glyph.bitmap(), glyph.bitmap()->rect(), [color](Color pixel) -> Color {
return color.with_alpha(pixel.alpha());
});
}
}
void Painter::draw_emoji(IntPoint point, Gfx::Bitmap const& emoji, Font const& font)
{
IntRect dst_rect {
point.x(),
point.y(),
font.pixel_size_rounded_up() * emoji.width() / emoji.height(),
font.pixel_size_rounded_up(),
};
draw_scaled_bitmap(dst_rect, emoji, emoji.rect());
}
void Painter::set_pixel(IntPoint p, Color color, bool blend)
{
auto point = p;

View file

@ -64,8 +64,6 @@ public:
void draw_triangle_wave(IntPoint, IntPoint, Color color, int amplitude, int thickness = 1);
void blit(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect, float opacity = 1.0f, bool apply_alpha = true);
void blit_filtered(IntPoint, Gfx::Bitmap const&, IntRect const& src_rect, Function<Color(Color)> const&, bool apply_alpha = true);
void draw_emoji(IntPoint, Gfx::Bitmap const&, Font const&);
void draw_glyph(FloatPoint, u32, Font const&, Color);
enum class CornerOrientation {
TopLeft,