mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:37:44 +00:00
LibGfx+LibTTF: Allow Painter to draw TTF glyphs
This commit is contained in:
parent
0f41f5d9ba
commit
85158dc0ad
5 changed files with 66 additions and 14 deletions
|
@ -75,18 +75,27 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Glyph(RefPtr<Bitmap> bitmap)
|
Glyph(RefPtr<Bitmap> bitmap, int left_bearing, int advance, int ascent)
|
||||||
: m_bitmap(bitmap)
|
: m_bitmap(bitmap)
|
||||||
|
, m_left_bearing(left_bearing)
|
||||||
|
, m_advance(advance)
|
||||||
|
, m_ascent(ascent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_glyph_bitmap() const { return !m_bitmap; }
|
bool is_glyph_bitmap() const { return !m_bitmap; }
|
||||||
GlyphBitmap glyph_bitmap() const { return m_glyph_bitmap; }
|
GlyphBitmap glyph_bitmap() const { return m_glyph_bitmap; }
|
||||||
RefPtr<Bitmap> bitmap() const { return m_bitmap; }
|
RefPtr<Bitmap> bitmap() const { return m_bitmap; }
|
||||||
|
int left_bearing() const { return m_left_bearing; }
|
||||||
|
int advance() const { return m_advance; }
|
||||||
|
int ascent() const { return m_ascent; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GlyphBitmap m_glyph_bitmap;
|
GlyphBitmap m_glyph_bitmap;
|
||||||
RefPtr<Bitmap> m_bitmap;
|
RefPtr<Bitmap> m_bitmap;
|
||||||
|
int m_left_bearing;
|
||||||
|
int m_advance;
|
||||||
|
int m_ascent;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Font : public RefCounted<Font> {
|
class Font : public RefCounted<Font> {
|
||||||
|
|
|
@ -900,7 +900,16 @@ FLATTEN void Painter::draw_glyph(const IntPoint& point, u32 code_point, Color co
|
||||||
|
|
||||||
FLATTEN void Painter::draw_glyph(const IntPoint& point, u32 code_point, const Font& font, Color color)
|
FLATTEN void Painter::draw_glyph(const IntPoint& point, u32 code_point, const Font& font, Color color)
|
||||||
{
|
{
|
||||||
draw_bitmap(point, font.glyph(code_point).glyph_bitmap(), color);
|
auto glyph = font.glyph(code_point);
|
||||||
|
if (glyph.is_glyph_bitmap()) {
|
||||||
|
draw_bitmap(point, glyph.glyph_bitmap(), color);
|
||||||
|
} else {
|
||||||
|
auto top_left = point + IntPoint(glyph.left_bearing(), font.x_height() - glyph.ascent());
|
||||||
|
|
||||||
|
blit_filtered(top_left, *glyph.bitmap(), glyph.bitmap()->rect(), [color](Color pixel) -> Color {
|
||||||
|
return pixel.multiply(color);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_emoji(const IntPoint& point, const Gfx::Bitmap& emoji, const Font& font)
|
void Painter::draw_emoji(const IntPoint& point, const Gfx::Bitmap& emoji, const Font& font)
|
||||||
|
|
|
@ -5,4 +5,4 @@ set(SOURCES
|
||||||
)
|
)
|
||||||
|
|
||||||
serenity_lib(LibTTF ttf)
|
serenity_lib(LibTTF ttf)
|
||||||
target_link_libraries(LibGfx LibM LibCore)
|
target_link_libraries(LibTTF LibM LibCore)
|
||||||
|
|
|
@ -481,6 +481,35 @@ String Font::variant() const
|
||||||
return m_name.subfamily_name();
|
return m_name.subfamily_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 Font::weight() const
|
||||||
|
{
|
||||||
|
// FIXME: This is pretty naive, read weight from the actual font table(s)
|
||||||
|
auto variant_name = variant();
|
||||||
|
|
||||||
|
if (variant_name == "Thin")
|
||||||
|
return 100;
|
||||||
|
if (variant_name == "Extra Light")
|
||||||
|
return 200;
|
||||||
|
if (variant_name == "Light")
|
||||||
|
return 300;
|
||||||
|
if (variant_name == "Regular")
|
||||||
|
return 400;
|
||||||
|
if (variant_name == "Medium")
|
||||||
|
return 500;
|
||||||
|
if (variant_name == "Semi Bold")
|
||||||
|
return 600;
|
||||||
|
if (variant_name == "Bold")
|
||||||
|
return 700;
|
||||||
|
if (variant_name == "Extra Bold")
|
||||||
|
return 800;
|
||||||
|
if (variant_name == "Black")
|
||||||
|
return 900;
|
||||||
|
if (variant_name == "Extra Black")
|
||||||
|
return 950;
|
||||||
|
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
|
||||||
int ScaledFont::width(const StringView& string) const
|
int ScaledFont::width(const StringView& string) const
|
||||||
{
|
{
|
||||||
Utf8View utf8 { string };
|
Utf8View utf8 { string };
|
||||||
|
@ -524,7 +553,8 @@ Gfx::Glyph ScaledFont::glyph(u32 code_point) const
|
||||||
{
|
{
|
||||||
auto id = glyph_id_for_codepoint(code_point);
|
auto id = glyph_id_for_codepoint(code_point);
|
||||||
auto bitmap = raster_glyph(id);
|
auto bitmap = raster_glyph(id);
|
||||||
return Gfx::Glyph(bitmap);
|
auto metrics = glyph_metrics(id);
|
||||||
|
return Gfx::Glyph(bitmap, metrics.left_side_bearing, metrics.advance_width, metrics.ascender);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ScaledFont::glyph_width(size_t code_point) const
|
u8 ScaledFont::glyph_width(size_t code_point) const
|
||||||
|
|
|
@ -123,6 +123,8 @@ class ScaledFont : public Gfx::Font {
|
||||||
public:
|
public:
|
||||||
ScaledFont(RefPtr<TTF::Font> font, float point_width, float point_height, unsigned dpi_x = DEFAULT_DPI, unsigned dpi_y = DEFAULT_DPI)
|
ScaledFont(RefPtr<TTF::Font> font, float point_width, float point_height, unsigned dpi_x = DEFAULT_DPI, unsigned dpi_y = DEFAULT_DPI)
|
||||||
: m_font(font)
|
: m_font(font)
|
||||||
|
, m_point_width(point_width)
|
||||||
|
, m_point_height(point_height)
|
||||||
{
|
{
|
||||||
float units_per_em = m_font->units_per_em();
|
float units_per_em = m_font->units_per_em();
|
||||||
m_x_scale = (point_width * dpi_x) / (POINTS_PER_INCH * units_per_em);
|
m_x_scale = (point_width * dpi_x) / (POINTS_PER_INCH * units_per_em);
|
||||||
|
@ -135,18 +137,18 @@ public:
|
||||||
|
|
||||||
// Gfx::Font implementation
|
// Gfx::Font implementation
|
||||||
virtual NonnullRefPtr<Font> clone() const override { return *this; } /* TODO */
|
virtual NonnullRefPtr<Font> clone() const override { return *this; } /* TODO */
|
||||||
virtual u8 presentation_size() const override { return (u8)m_y_scale; }
|
virtual u8 presentation_size() const override { return m_point_height; }
|
||||||
virtual u16 weight() const override { return 400; } /* TODO */
|
virtual u16 weight() const override { return m_font->weight(); }
|
||||||
virtual Gfx::Glyph glyph(u32 code_point) const override;
|
virtual Gfx::Glyph glyph(u32 code_point) const override;
|
||||||
virtual u8 glyph_width(size_t ch) const override;
|
virtual u8 glyph_width(size_t ch) const override;
|
||||||
virtual int glyph_or_emoji_width(u32 code_point) const override;
|
virtual int glyph_or_emoji_width(u32 code_point) const override;
|
||||||
virtual u8 glyph_height() const override { return m_y_scale; } /* TODO */
|
virtual u8 glyph_height() const override { return m_point_height; } /* TODO */
|
||||||
virtual int x_height() const override { return m_y_scale; } /* TODO */
|
virtual int x_height() const override { return m_point_height; } /* TODO */
|
||||||
virtual u8 min_glyph_width() const override { return 1; } /* TODO */
|
virtual u8 min_glyph_width() const override { return 1; } /* TODO */
|
||||||
virtual u8 max_glyph_width() const override { return m_x_scale; } /* TODO */
|
virtual u8 max_glyph_width() const override { return m_point_height; } /* TODO */
|
||||||
virtual u8 glyph_fixed_width() const override;
|
virtual u8 glyph_fixed_width() const override;
|
||||||
virtual u8 baseline() const override { return m_y_scale; } /* TODO */
|
virtual u8 baseline() const override { return m_point_height; } /* TODO */
|
||||||
virtual u8 mean_line() const override { return m_y_scale; } /* TODO */
|
virtual u8 mean_line() const override { return m_point_height; } /* TODO */
|
||||||
virtual int width(const StringView&) const override;
|
virtual int width(const StringView&) const override;
|
||||||
virtual int width(const Utf8View&) const override;
|
virtual int width(const Utf8View&) const override;
|
||||||
virtual int width(const Utf32View&) const override;
|
virtual int width(const Utf32View&) const override;
|
||||||
|
@ -161,8 +163,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<TTF::Font> m_font;
|
RefPtr<TTF::Font> m_font;
|
||||||
float m_x_scale { 0.0 };
|
float m_x_scale { 0.0f };
|
||||||
float m_y_scale { 0.0 };
|
float m_y_scale { 0.0f };
|
||||||
|
float m_point_width { 0.0f };
|
||||||
|
float m_point_height { 0.0f };
|
||||||
mutable AK::HashMap<u32, RefPtr<Gfx::Bitmap>> m_cached_glyph_bitmaps;
|
mutable AK::HashMap<u32, RefPtr<Gfx::Bitmap>> m_cached_glyph_bitmaps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue