1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:18:11 +00:00

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.
This commit is contained in:
Timothy Flynn 2023-02-22 20:51:26 -05:00 committed by Linus Groh
parent 4212010ebd
commit 8c38d46c1a
3 changed files with 24 additions and 12 deletions

View file

@ -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}") 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_URL "https://www.unicode.org/Public/emoji/${EMOJI_VERSION}/emoji-test.txt")
set(EMOJI_TEST_PATH "${UCD_PATH}/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_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") 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}" "${UCD_VERSION_FILE}"
"${EMOJI_DATA_HEADER}" "${EMOJI_DATA_HEADER}"
"${EMOJI_DATA_IMPLEMENTATION}" "${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, # 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. # which only happens if files within it are added or deleted, but not when a file is modified.

View file

@ -17,7 +17,7 @@
struct Emoji { struct Emoji {
size_t name { 0 }; size_t name { 0 };
Optional<DeprecatedString> image_path; Optional<size_t> image_path;
Unicode::EmojiGroup group; Unicode::EmojiGroup group;
DeprecatedString subgroup; DeprecatedString subgroup;
u32 display_order { 0 }; u32 display_order { 0 };
@ -32,7 +32,7 @@ struct EmojiData {
Vector<Emoji> emojis; Vector<Emoji> 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; 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()); auto path = DeprecatedString::formatted("{}/{}.png", emoji_resource_path, builder.to_deprecated_string());
if (Core::DeprecatedFile::exists(path)) if (!Core::DeprecatedFile::exists(path))
emoji.image_path = move(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<void> parse_emoji_test_data(Core::BufferedFile& file, EmojiData& emoji_data) static ErrorOr<void> parse_emoji_test_data(Core::BufferedFile& file, EmojiData& emoji_data)
@ -216,10 +219,12 @@ static constexpr Array<u32, @total_code_point_count@> s_emoji_code_points { {)~~
generator.append(R"~~~( generator.append(R"~~~(
struct EmojiData { struct EmojiData {
constexpr Emoji to_unicode_emoji() const Emoji to_unicode_emoji() const
{ {
Emoji emoji {}; Emoji emoji {};
emoji.name = decode_string(name); emoji.name = decode_string(name);
if (image_path != 0)
emoji.image_path = decode_string(image_path);
emoji.group = static_cast<EmojiGroup>(group); emoji.group = static_cast<EmojiGroup>(group);
emoji.display_order = display_order; emoji.display_order = display_order;
emoji.code_points = code_points(); emoji.code_points = code_points();
@ -233,6 +238,7 @@ struct EmojiData {
} }
@string_index_type@ name { 0 }; @string_index_type@ name { 0 };
@string_index_type@ image_path { 0 };
u8 group { 0 }; u8 group { 0 };
u32 display_order { 0 }; u32 display_order { 0 };
size_t code_point_start { 0 }; size_t code_point_start { 0 };
@ -246,13 +252,14 @@ static constexpr Array<EmojiData, @emojis_size@> s_emojis { {)~~~");
for (auto const& emoji : emoji_data.emojis) { for (auto const& emoji : emoji_data.emojis) {
generator.set("name"sv, DeprecatedString::number(emoji.name)); 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("group"sv, DeprecatedString::number(to_underlying(emoji.group)));
generator.set("display_order"sv, DeprecatedString::number(emoji.display_order)); 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_start"sv, DeprecatedString::number(emoji.code_point_array_index));
generator.set("code_point_count"sv, DeprecatedString::number(emoji.code_points.size())); generator.set("code_point_count"sv, DeprecatedString::number(emoji.code_points.size()));
generator.append(R"~~~( 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"~~~( generator.append(R"~~~(
@ -327,6 +334,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
StringView generated_installation_path; StringView generated_installation_path;
StringView emoji_test_path; StringView emoji_test_path;
StringView emoji_serenity_path; StringView emoji_serenity_path;
StringView emoji_base_path;
StringView emoji_resource_path; StringView emoji_resource_path;
Core::ArgsParser args_parser; Core::ArgsParser args_parser;
@ -335,12 +343,15 @@ ErrorOr<int> 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(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_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_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.add_option(emoji_resource_path, "Path to the /res/emoji directory", "emoji-resource-path", 'r', "emoji-resource-path");
args_parser.parse(arguments); 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)); 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 {}; EmojiData emoji_data {};
TRY(parse_emoji_test_data(*emoji_test_file, emoji_data)); TRY(parse_emoji_test_data(*emoji_test_file, emoji_data));
@ -353,6 +364,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
for (auto& emoji : emoji_data.emojis) { for (auto& emoji : emoji_data.emojis) {
emoji.code_point_array_index = code_point_array_index; emoji.code_point_array_index = code_point_array_index;
code_point_array_index += emoji.code_points.size(); 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()) { if (!generated_header_path.is_empty()) {
@ -367,9 +380,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!generated_installation_path.is_empty()) { if (!generated_installation_path.is_empty()) {
TRY(Core::Directory::create(LexicalPath { generated_installation_path }.parent(), Core::Directory::CreateDirectories::Yes)); 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)); auto generated_installation_file = TRY(open_file(generated_installation_path, Core::File::OpenMode::Write));
TRY(generate_emoji_installation(*generated_installation_file, emoji_data)); TRY(generate_emoji_installation(*generated_installation_file, emoji_data));
} }

View file

@ -32,6 +32,7 @@ enum class EmojiGroup : u8 {
struct Emoji { struct Emoji {
StringView name; StringView name;
Optional<StringView> image_path;
EmojiGroup group { EmojiGroup::Unknown }; EmojiGroup group { EmojiGroup::Unknown };
u32 display_order { 0 }; u32 display_order { 0 };
ReadonlySpan<u32> code_points; ReadonlySpan<u32> code_points;