From 8c38d46c1ae4b2fddbef3e89802c43474126d9dd Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 22 Feb 2023 20:51:26 -0500 Subject: [PATCH] LibUnicode: Generate the path to emoji images alongside emoji data This will provide for quicker emoji lookups, rather than having to discover and allocate these paths at runtime before we find out if they even exist. --- Meta/CMake/unicode_data.cmake | 5 ++-- .../LibUnicode/GenerateEmojiData.cpp | 30 ++++++++++++------- Userland/Libraries/LibUnicode/Emoji.h | 1 + 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Meta/CMake/unicode_data.cmake b/Meta/CMake/unicode_data.cmake index dc97c6362b..680ebdaa4b 100644 --- a/Meta/CMake/unicode_data.cmake +++ b/Meta/CMake/unicode_data.cmake @@ -64,7 +64,8 @@ set(SENTENCE_BREAK_PROP_PATH "${UCD_PATH}/${SENTENCE_BREAK_PROP_SOURCE}") string(REGEX REPLACE "([0-9]+\\.[0-9]+)\\.[0-9]+" "\\1" EMOJI_VERSION "${UCD_VERSION}") set(EMOJI_TEST_URL "https://www.unicode.org/Public/emoji/${EMOJI_VERSION}/emoji-test.txt") set(EMOJI_TEST_PATH "${UCD_PATH}/emoji-test.txt") -set(EMOJI_RES_PATH "${SerenityOS_SOURCE_DIR}/Base/res/emoji") +set(EMOJI_BASE_PATH "${SerenityOS_SOURCE_DIR}/Base") +set(EMOJI_RES_PATH "${EMOJI_BASE_PATH}/res/emoji") set(EMOJI_SERENITY_PATH "${SerenityOS_SOURCE_DIR}/Base/home/anon/Documents/emoji-serenity.txt") set(EMOJI_INSTALL_PATH "${CMAKE_BINARY_DIR}/Root/home/anon/Documents/emoji.txt") @@ -117,7 +118,7 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) "${UCD_VERSION_FILE}" "${EMOJI_DATA_HEADER}" "${EMOJI_DATA_IMPLEMENTATION}" - arguments "${EMOJI_INSTALL_ARG}" -e "${EMOJI_TEST_PATH}" -s "${EMOJI_SERENITY_PATH}" -r "${EMOJI_RES_PATH}" + arguments "${EMOJI_INSTALL_ARG}" -e "${EMOJI_TEST_PATH}" -s "${EMOJI_SERENITY_PATH}" -b "${EMOJI_BASE_PATH}" -r "${EMOJI_RES_PATH}" # This will make this command only run when the modified time of the directory changes, # which only happens if files within it are added or deleted, but not when a file is modified. diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp index a03051551f..4bdcdd3059 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp @@ -17,7 +17,7 @@ struct Emoji { size_t name { 0 }; - Optional image_path; + Optional image_path; Unicode::EmojiGroup group; DeprecatedString subgroup; u32 display_order { 0 }; @@ -32,7 +32,7 @@ struct EmojiData { Vector emojis; }; -static void set_image_path_for_emoji(StringView emoji_resource_path, Emoji& emoji) +static void set_image_path_for_emoji(StringView emoji_base_path, StringView emoji_resource_path, EmojiData& emoji_data, Emoji& emoji) { StringBuilder builder; @@ -45,8 +45,11 @@ static void set_image_path_for_emoji(StringView emoji_resource_path, Emoji& emoj } auto path = DeprecatedString::formatted("{}/{}.png", emoji_resource_path, builder.to_deprecated_string()); - if (Core::DeprecatedFile::exists(path)) - emoji.image_path = move(path); + if (!Core::DeprecatedFile::exists(path)) + return; + + auto installed_image_path = path.replace(emoji_base_path, {}, ReplaceMode::FirstOnly); + emoji.image_path = emoji_data.unique_strings.ensure(move(installed_image_path)); } static ErrorOr parse_emoji_test_data(Core::BufferedFile& file, EmojiData& emoji_data) @@ -216,10 +219,12 @@ static constexpr Array s_emoji_code_points { {)~~ generator.append(R"~~~( struct EmojiData { - constexpr Emoji to_unicode_emoji() const + Emoji to_unicode_emoji() const { Emoji emoji {}; emoji.name = decode_string(name); + if (image_path != 0) + emoji.image_path = decode_string(image_path); emoji.group = static_cast(group); emoji.display_order = display_order; emoji.code_points = code_points(); @@ -233,6 +238,7 @@ struct EmojiData { } @string_index_type@ name { 0 }; + @string_index_type@ image_path { 0 }; u8 group { 0 }; u32 display_order { 0 }; size_t code_point_start { 0 }; @@ -246,13 +252,14 @@ static constexpr Array s_emojis { {)~~~"); for (auto const& emoji : emoji_data.emojis) { generator.set("name"sv, DeprecatedString::number(emoji.name)); + generator.set("image_path"sv, DeprecatedString::number(emoji.image_path.value_or(0))); generator.set("group"sv, DeprecatedString::number(to_underlying(emoji.group))); generator.set("display_order"sv, DeprecatedString::number(emoji.display_order)); generator.set("code_point_start"sv, DeprecatedString::number(emoji.code_point_array_index)); generator.set("code_point_count"sv, DeprecatedString::number(emoji.code_points.size())); generator.append(R"~~~( - { @name@, @group@, @display_order@, @code_point_start@, @code_point_count@ },)~~~"); + { @name@, @image_path@, @group@, @display_order@, @code_point_start@, @code_point_count@ },)~~~"); } generator.append(R"~~~( @@ -327,6 +334,7 @@ ErrorOr serenity_main(Main::Arguments arguments) StringView generated_installation_path; StringView emoji_test_path; StringView emoji_serenity_path; + StringView emoji_base_path; StringView emoji_resource_path; Core::ArgsParser args_parser; @@ -335,12 +343,15 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(generated_installation_path, "Path to the emoji.txt file to generate", "generated-installation-path", 'i', "generated-installation-path"); args_parser.add_option(emoji_test_path, "Path to emoji-test.txt file", "emoji-test-path", 'e', "emoji-test-path"); args_parser.add_option(emoji_serenity_path, "Path to emoji-serenity.txt file", "emoji-serenity-path", 's', "emoji-serenity-path"); + args_parser.add_option(emoji_base_path, "Path to the Base directory", "emoji-base-path", 'b', "emoji-base-path"); args_parser.add_option(emoji_resource_path, "Path to the /res/emoji directory", "emoji-resource-path", 'r', "emoji-resource-path"); args_parser.parse(arguments); - auto emoji_test_file = TRY(open_file(emoji_test_path, Core::File::OpenMode::Read)); + VERIFY(!emoji_base_path.is_empty() && Core::DeprecatedFile::exists(emoji_base_path)); VERIFY(!emoji_resource_path.is_empty() && Core::DeprecatedFile::exists(emoji_resource_path)); + auto emoji_test_file = TRY(open_file(emoji_test_path, Core::File::OpenMode::Read)); + EmojiData emoji_data {}; TRY(parse_emoji_test_data(*emoji_test_file, emoji_data)); @@ -353,6 +364,8 @@ ErrorOr serenity_main(Main::Arguments arguments) for (auto& emoji : emoji_data.emojis) { emoji.code_point_array_index = code_point_array_index; code_point_array_index += emoji.code_points.size(); + + set_image_path_for_emoji(emoji_base_path, emoji_resource_path, emoji_data, emoji); } if (!generated_header_path.is_empty()) { @@ -367,9 +380,6 @@ ErrorOr serenity_main(Main::Arguments arguments) if (!generated_installation_path.is_empty()) { TRY(Core::Directory::create(LexicalPath { generated_installation_path }.parent(), Core::Directory::CreateDirectories::Yes)); - for (auto& emoji : emoji_data.emojis) - set_image_path_for_emoji(emoji_resource_path, emoji); - auto generated_installation_file = TRY(open_file(generated_installation_path, Core::File::OpenMode::Write)); TRY(generate_emoji_installation(*generated_installation_file, emoji_data)); } diff --git a/Userland/Libraries/LibUnicode/Emoji.h b/Userland/Libraries/LibUnicode/Emoji.h index b36655d28a..dcb137ba0a 100644 --- a/Userland/Libraries/LibUnicode/Emoji.h +++ b/Userland/Libraries/LibUnicode/Emoji.h @@ -32,6 +32,7 @@ enum class EmojiGroup : u8 { struct Emoji { StringView name; + Optional image_path; EmojiGroup group { EmojiGroup::Unknown }; u32 display_order { 0 }; ReadonlySpan code_points;