Procházet zdrojové kódy

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. :^)
Andreas Kling před 5 roky
rodič
revize
0d8aaaaa44

+ 8 - 11
Libraries/LibDraw/Emoji.cpp

@@ -3,25 +3,22 @@
 #include <LibDraw/Emoji.h>
 #include <LibDraw/GraphicsBitmap.h>
 
-static HashMap<u32, Emoji> s_emojis;
+static HashMap<u32, RefPtr<GraphicsBitmap>> s_emojis;
 
-Emoji::Emoji(NonnullRefPtr<GraphicsBitmap> bitmap)
-    : m_bitmap(move(bitmap))
-{
-}
-
-const Emoji* Emoji::emoji_for_codepoint(u32 codepoint)
+const GraphicsBitmap* Emoji::emoji_for_codepoint(u32 codepoint)
 {
     auto it = s_emojis.find(codepoint);
     if (it != s_emojis.end())
-        return &(*it).value;
+        return (*it).value.ptr();
 
     String path = String::format("/res/emoji/U+%X.png", codepoint);
 
     auto bitmap = GraphicsBitmap::load_from_file(path);
-    if (!bitmap)
+    if (!bitmap) {
+        s_emojis.set(codepoint, nullptr);
         return nullptr;
+    }
 
-    s_emojis.set(codepoint, Emoji { bitmap.release_nonnull() });
-    return &(*s_emojis.find(codepoint)).value;
+    s_emojis.set(codepoint, bitmap);
+    return bitmap.ptr();
 }

+ 2 - 11
Libraries/LibDraw/Emoji.h

@@ -1,19 +1,10 @@
 #pragma once
 
 #include <AK/Types.h>
-#include <AK/NonnullRefPtr.h>
 
 class GraphicsBitmap;
 
 class Emoji {
- public:
-    ~Emoji() {}
-
-    static const Emoji* emoji_for_codepoint(u32 codepoint);
-    const GraphicsBitmap& bitmap() const { return m_bitmap; }
-
-private:
-    explicit Emoji(NonnullRefPtr<GraphicsBitmap>);
-
-    NonnullRefPtr<GraphicsBitmap> m_bitmap;
+public:
+    static const GraphicsBitmap* emoji_for_codepoint(u32 codepoint);
 };

+ 2 - 2
Libraries/LibDraw/Font.cpp

@@ -181,10 +181,10 @@ int Font::glyph_or_emoji_width(u32 codepoint) const
     if (m_fixed_width)
         return m_glyph_width;
 
-    auto emoji = Emoji::emoji_for_codepoint(codepoint);
+    auto* emoji = Emoji::emoji_for_codepoint(codepoint);
     if (emoji == nullptr)
         return glyph_width('?');
-    return emoji->bitmap().size().width();
+    return emoji->size().width();
 }
 
 int Font::width(const StringView& string) const

+ 6 - 4
Libraries/LibDraw/Painter.cpp

@@ -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);
 }
 
-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())
-        blit(point, emoji.bitmap(), emoji.bitmap().rect());
+        blit(point, emoji, emoji.rect());
     else {
         Rect dst_rect {
             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_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?
-    const Emoji* emoji = Emoji::emoji_for_codepoint(codepoint);
+    auto* emoji = Emoji::emoji_for_codepoint(codepoint);
     if (emoji == nullptr) {
+#ifdef EMOJI_DEBUG
         dbg() << "Failed to find an emoji for codepoint " << codepoint;
+#endif
         draw_glyph(point, '?', font, color);
         return;
     }

+ 1 - 1
Libraries/LibDraw/Painter.h

@@ -36,7 +36,7 @@ public:
     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, 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);
 
     const Font& font() const { return *state().font; }