mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 18:22:45 +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
	
	 Andreas Kling
						Andreas Kling