mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:12: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/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(); | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
| }; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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; } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling