From fcd4535a55dcd33f885c7bb900690c86ac937730 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 22 Feb 2023 15:57:31 -0500 Subject: [PATCH] LibGfx: Do not exclude all ASCII code points from emoji lookups Keycap emoji, for example, begin with ASCII digits. Instead, check the first code point for the Emoji Unicode property. On a profile of scrolling around on the welcome page in the Browser, this raises the runtime percentage of Font::glyph_or_emoji_width from about 0.8% to 1.3%. --- Userland/Libraries/LibGfx/Font/Emoji.cpp | 25 ++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibGfx/Font/Emoji.cpp b/Userland/Libraries/LibGfx/Font/Emoji.cpp index de63da0567..a6c4e1ca8d 100644 --- a/Userland/Libraries/LibGfx/Font/Emoji.cpp +++ b/Userland/Libraries/LibGfx/Font/Emoji.cpp @@ -5,7 +5,6 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include @@ -13,6 +12,7 @@ #include #include #include +#include namespace Gfx { @@ -46,6 +46,27 @@ Bitmap const* Emoji::emoji_for_code_points(ReadonlySpan const& code_points) return bitmap.ptr(); } +template +static bool could_be_emoji(CodePointIterator const& it) +{ + if (it.done()) + return false; + + static constexpr u32 supplementary_private_use_area_b_first_code_point = 0x100000; + if (*it >= supplementary_private_use_area_b_first_code_point) { + // We use Supplementary Private Use Area-B for custom Serenity emoji. + return true; + } + + static auto const emoji_property = Unicode::property_from_string("Emoji"sv); + if (!emoji_property.has_value()) { + // This means Unicode data generation is disabled. Always check the disk in that case. + return true; + } + + return Unicode::code_point_has_property(*it, *emoji_property); +} + template static Bitmap const* emoji_for_code_point_iterator_impl(CodePointIterator& it) { @@ -53,7 +74,7 @@ static Bitmap const* emoji_for_code_point_iterator_impl(CodePointIterator& it) // into a certain range in the loop below (emojis, modifiers, variation selectors, ZWJ), // and bailing out early if not. Current worst case is 10 file lookups for any sequence of // code points (if the first glyph isn't part of the font in regular text rendering). - if (is_ascii(*it)) + if (!could_be_emoji(it)) return nullptr; constexpr size_t max_emoji_code_point_sequence_length = 10;