diff --git a/cmake/FindICU.cmake b/cmake/FindICU.cmake new file mode 100644 index 00000000..d033d0df --- /dev/null +++ b/cmake/FindICU.cmake @@ -0,0 +1,11 @@ +include(PkgConfigWithFallback) +find_pkg_config_with_fallback(ICU + PKG_CONFIG_NAME icu-uc + LIB_NAMES icuuc icudata + INCLUDE_NAMES unicode/umachine.h +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ICU + REQUIRED_VARS ICU_LIBRARY + VERSION_VAR ICU_VERSION) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index d21d10ed..0a21d1f0 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -9,6 +9,7 @@ find_packages(MAIN_PACKAGES REQUIRED GModule GObject GTK3>=3.22 + ICU>=57 ) set(RESOURCE_LIST @@ -71,6 +72,7 @@ if(GDK3_WITH_X11) set(MAIN_EXTRA_OPTIONS ${MAIN_EXTRA_OPTIONS} -D GDK3_WITH_X11) set(MAIN_EXTRA_PACKAGES ${MAIN_EXTRA_PACKAGES} gdk-x11-3.0) endif(GDK3_WITH_X11) +set(MAIN_EXTRA_OPTIONS ${MAIN_EXTRA_OPTIONS} --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi) vala_precompile(MAIN_VALA_C SOURCES diff --git a/main/src/ui/conversation_summary/content_item_widget_factory.vala b/main/src/ui/conversation_summary/content_item_widget_factory.vala index d8f65b3c..d8d21ebd 100644 --- a/main/src/ui/conversation_summary/content_item_widget_factory.vala +++ b/main/src/ui/conversation_summary/content_item_widget_factory.vala @@ -3,6 +3,7 @@ using Gdk; using Gtk; using Pango; using Xmpp; +using Unicode; using Dino.Entities; @@ -75,6 +76,12 @@ public class MessageItemWidgetGenerator : WidgetGenerator, Object { label.style_updated.connect(() => update_me_style(stream_interactor, message.real_jid ?? message.from, display_name, conversation.account, label, markup_text)); } + int only_emoji_count = Util.get_only_emoji_count(markup_text); + if (only_emoji_count != -1) { + string size_str = only_emoji_count < 5 ? "xx-large" : "large"; + markup_text = @"" + markup_text + ""; + } + label.label = markup_text; return label; } diff --git a/main/src/ui/util/helper.vala b/main/src/ui/util/helper.vala index 049b2d07..2f2bb84d 100644 --- a/main/src/ui/util/helper.vala +++ b/main/src/ui/util/helper.vala @@ -203,4 +203,46 @@ public static string parse_add_markup(string s_, string? highlight_word, bool pa return s; } +public int get_only_emoji_count(string markup_text) { + int emoji_no = 0; + int index_ref = 0; + unichar curchar = 0, altchar = 0; + bool last_was_emoji = false, last_was_modifier_base = false, last_was_keycap = false; + while (markup_text.get_next_char(ref index_ref, out curchar)) { + if (last_was_emoji && last_was_keycap && curchar == 0x20E3) { + // keycap sequence + continue; + } + + last_was_keycap = false; + + if (last_was_emoji && curchar == 0x200D && markup_text.get_next_char(ref index_ref, out curchar)) { + // zero width joiner + last_was_emoji = false; + emoji_no--; + } + + if (last_was_emoji && last_was_modifier_base && Unicode.has_binary_property(curchar, Unicode.EMOJI_MODIFIER)) { + // still an emoji, but no longer a modifier base + last_was_modifier_base = false; + } else if (Unicode.has_binary_property(curchar, Unicode.EMOJI_PRESENTATION)) { + if (Unicode.has_binary_property(curchar, Unicode.EMOJI_MODIFIER_BASE)) { + last_was_modifier_base = true; + } + emoji_no++; + last_was_emoji = true; + } else if (curchar == ' ') { + last_was_emoji = false; + } else if (markup_text.get_next_char(ref index_ref, out altchar) && altchar == 0xFE0F) { + // U+FE0F = VARIATION SELECTOR-16 + emoji_no++; + last_was_emoji = true; + last_was_keycap = (curchar >= 0x30 && curchar <= 0x39) || curchar == 0x23 || curchar == 0x2A; + } else { + return -1; + } + } + return emoji_no; +} + } diff --git a/main/vapi/icu-uc.vapi b/main/vapi/icu-uc.vapi new file mode 100644 index 00000000..12cc0587 --- /dev/null +++ b/main/vapi/icu-uc.vapi @@ -0,0 +1,12 @@ +namespace Unicode { + [CCode (cprefix = "UCHAR_", cheader_filename = "unicode/uchar.h")] + enum Property { + EMOJI, + EMOJI_PRESENTATION, + EMOJI_MODIFIER, + EMOJI_MODIFIER_BASE, + } + + [CCode (cname = "u_hasBinaryProperty", cheader_filename = "unicode/uchar.h")] + bool has_binary_property(unichar c, Property p); +}