mirror of
https://github.com/RGBCube/serenity
synced 2025-05-26 01:45:06 +00:00
LibDraw: Store emojis in a HashMap<u32, RefPtr<GraphicsBitmap>>
Get rid of the dedicated Emoji class to make it easier to store a null value signifying a failed lookup. This allows us to remember failed lookups, making subsequent failures for the same codepoint much faster. :^)
This commit is contained in:
parent
b3a63e1d50
commit
0d8aaaaa44
5 changed files with 19 additions and 29 deletions
|
@ -3,25 +3,22 @@
|
||||||
#include <LibDraw/Emoji.h>
|
#include <LibDraw/Emoji.h>
|
||||||
#include <LibDraw/GraphicsBitmap.h>
|
#include <LibDraw/GraphicsBitmap.h>
|
||||||
|
|
||||||
static HashMap<u32, Emoji> s_emojis;
|
static HashMap<u32, RefPtr<GraphicsBitmap>> s_emojis;
|
||||||
|
|
||||||
Emoji::Emoji(NonnullRefPtr<GraphicsBitmap> bitmap)
|
const GraphicsBitmap* Emoji::emoji_for_codepoint(u32 codepoint)
|
||||||
: m_bitmap(move(bitmap))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const Emoji* Emoji::emoji_for_codepoint(u32 codepoint)
|
|
||||||
{
|
{
|
||||||
auto it = s_emojis.find(codepoint);
|
auto it = s_emojis.find(codepoint);
|
||||||
if (it != s_emojis.end())
|
if (it != s_emojis.end())
|
||||||
return &(*it).value;
|
return (*it).value.ptr();
|
||||||
|
|
||||||
String path = String::format("/res/emoji/U+%X.png", codepoint);
|
String path = String::format("/res/emoji/U+%X.png", codepoint);
|
||||||
|
|
||||||
auto bitmap = GraphicsBitmap::load_from_file(path);
|
auto bitmap = GraphicsBitmap::load_from_file(path);
|
||||||
if (!bitmap)
|
if (!bitmap) {
|
||||||
|
s_emojis.set(codepoint, nullptr);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
s_emojis.set(codepoint, Emoji { bitmap.release_nonnull() });
|
s_emojis.set(codepoint, bitmap);
|
||||||
return &(*s_emojis.find(codepoint)).value;
|
return bitmap.ptr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <AK/NonnullRefPtr.h>
|
|
||||||
|
|
||||||
class GraphicsBitmap;
|
class GraphicsBitmap;
|
||||||
|
|
||||||
class Emoji {
|
class Emoji {
|
||||||
public:
|
public:
|
||||||
~Emoji() {}
|
static const GraphicsBitmap* emoji_for_codepoint(u32 codepoint);
|
||||||
|
|
||||||
static const Emoji* emoji_for_codepoint(u32 codepoint);
|
|
||||||
const GraphicsBitmap& bitmap() const { return m_bitmap; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Emoji(NonnullRefPtr<GraphicsBitmap>);
|
|
||||||
|
|
||||||
NonnullRefPtr<GraphicsBitmap> m_bitmap;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -181,10 +181,10 @@ int Font::glyph_or_emoji_width(u32 codepoint) const
|
||||||
if (m_fixed_width)
|
if (m_fixed_width)
|
||||||
return m_glyph_width;
|
return m_glyph_width;
|
||||||
|
|
||||||
auto emoji = Emoji::emoji_for_codepoint(codepoint);
|
auto* emoji = Emoji::emoji_for_codepoint(codepoint);
|
||||||
if (emoji == nullptr)
|
if (emoji == nullptr)
|
||||||
return glyph_width('?');
|
return glyph_width('?');
|
||||||
return emoji->bitmap().size().width();
|
return emoji->size().width();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Font::width(const StringView& string) const
|
int Font::width(const StringView& string) const
|
||||||
|
|
|
@ -556,10 +556,10 @@ void Painter::draw_scaled_bitmap(const Rect& a_dst_rect, const GraphicsBitmap& s
|
||||||
draw_bitmap(point, font.glyph_bitmap(ch), color);
|
draw_bitmap(point, font.glyph_bitmap(ch), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_emoji(const Point& point, const Emoji& emoji, const Font& font)
|
void Painter::draw_emoji(const Point& point, const GraphicsBitmap& emoji, const Font& font)
|
||||||
{
|
{
|
||||||
if (!font.is_fixed_width())
|
if (!font.is_fixed_width())
|
||||||
blit(point, emoji.bitmap(), emoji.bitmap().rect());
|
blit(point, emoji, emoji.rect());
|
||||||
else {
|
else {
|
||||||
Rect dst_rect {
|
Rect dst_rect {
|
||||||
point.x(),
|
point.x(),
|
||||||
|
@ -567,7 +567,7 @@ void Painter::draw_emoji(const Point& point, const Emoji& emoji, const Font& fon
|
||||||
font.glyph_width('x'),
|
font.glyph_width('x'),
|
||||||
font.glyph_height()
|
font.glyph_height()
|
||||||
};
|
};
|
||||||
draw_scaled_bitmap(dst_rect, emoji.bitmap(), emoji.bitmap().rect());
|
draw_scaled_bitmap(dst_rect, emoji, emoji.rect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,9 +580,11 @@ void Painter::draw_glyph_or_emoji(const Point& point, u32 codepoint, const Font&
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perhaps it's an emoji?
|
// Perhaps it's an emoji?
|
||||||
const Emoji* emoji = Emoji::emoji_for_codepoint(codepoint);
|
auto* emoji = Emoji::emoji_for_codepoint(codepoint);
|
||||||
if (emoji == nullptr) {
|
if (emoji == nullptr) {
|
||||||
|
#ifdef EMOJI_DEBUG
|
||||||
dbg() << "Failed to find an emoji for codepoint " << codepoint;
|
dbg() << "Failed to find an emoji for codepoint " << codepoint;
|
||||||
|
#endif
|
||||||
draw_glyph(point, '?', font, color);
|
draw_glyph(point, '?', font, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
void draw_text(const Rect&, const StringView&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
void draw_text(const Rect&, const StringView&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
||||||
void draw_glyph(const Point&, char, Color);
|
void draw_glyph(const Point&, char, Color);
|
||||||
void draw_glyph(const Point&, char, const Font&, Color);
|
void draw_glyph(const Point&, char, const Font&, Color);
|
||||||
void draw_emoji(const Point&, const Emoji&, const Font&);
|
void draw_emoji(const Point&, const GraphicsBitmap&, const Font&);
|
||||||
void draw_glyph_or_emoji(const Point&, u32 codepoint, const Font&, Color);
|
void draw_glyph_or_emoji(const Point&, u32 codepoint, const Font&, Color);
|
||||||
|
|
||||||
const Font& font() const { return *state().font; }
|
const Font& font() const { return *state().font; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue