diff --git a/src/Greenshot.Editor/Controls/EmojiControl.cs b/src/Greenshot.Editor/Controls/EmojiControl.cs index d9667a080..7a7989a12 100644 --- a/src/Greenshot.Editor/Controls/EmojiControl.cs +++ b/src/Greenshot.Editor/Controls/EmojiControl.cs @@ -11,7 +11,7 @@ namespace Greenshot.Editor.Controls private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { - ((EmojiControl)d).Source = EmojiRenderer.GetBitmapSource((string)e.NewValue, 48); + ((EmojiControl)d).Source = EmojiRenderer.GetIcon((string)e.NewValue); } public string Emoji diff --git a/src/Greenshot.Editor/Controls/EmojiData.cs b/src/Greenshot.Editor/Controls/EmojiData.cs index e1ae58e4e..f4099c9cc 100644 --- a/src/Greenshot.Editor/Controls/EmojiData.cs +++ b/src/Greenshot.Editor/Controls/EmojiData.cs @@ -17,11 +17,15 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Greenshot.Editor.Drawing; namespace Greenshot.Editor.Controls { public static class EmojiData { + private static Task _init; + public static IEnumerable AllEmoji => from g in AllGroups from e in g.EmojiList @@ -38,13 +42,14 @@ namespace Greenshot.Editor.Controls public static HashSet MatchStart { get; private set; } = new HashSet(); - // FIXME: should we lazy load this? If the user calls Load() later, then - // this first Load() call will have been for nothing. - static EmojiData() => Load(); - public static void Load() { - ParseEmojiList(); + _init = Task.Run(() => + { + ParseEmojiList(); + + EmojiRenderer.FillIconCache(AllEmoji.Select(e => e.Text)); + }); } public class Emoji diff --git a/src/Greenshot.Editor/Controls/EmojiPicker.xaml b/src/Greenshot.Editor/Controls/EmojiPicker.xaml index c24961597..3611c67c0 100644 --- a/src/Greenshot.Editor/Controls/EmojiPicker.xaml +++ b/src/Greenshot.Editor/Controls/EmojiPicker.xaml @@ -35,7 +35,7 @@ @@ -47,7 +47,7 @@ x:Name="VariationButton" Background="Transparent" BorderBrush="Transparent" Click="OnEmojiPicked" Focusable="False" ToolTip="{Binding Path=Name}"> - _iconCache = new ConcurrentDictionary(); + public static Image GetImage(string emoji, int iconSize) { if (_fontFamily == null) @@ -32,12 +39,23 @@ namespace Greenshot.Editor.Drawing } var font = _fontFamily.Value.CreateFont(iconSize, FontStyle.Regular); + var image = new Image(iconSize, iconSize); - var textOptions = new TextOptions(font) { Origin = new SixLabors.ImageSharp.PointF(0, iconSize / 2.0f), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center }; + RenderEmoji(emoji, font, image); + return image; + } + + private static void RenderEmoji(string emoji, Font font, Image image) + { + var verticalOffset = font.Size * 0.045f; + var textOptions = new TextOptions(font) + { + Origin = new SixLabors.ImageSharp.PointF(0, font.Size / 2.0f - verticalOffset), + HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center + }; image.Mutate(x => x.DrawText(textOptions, emoji, SixLabors.ImageSharp.Color.Black)); - return image; } public static Image GetBitmap(string emoji, int iconSize) @@ -82,5 +100,18 @@ namespace Greenshot.Editor.Drawing return bitmap; } + + public static void FillIconCache(IEnumerable emojis) + { + Parallel.ForEach(emojis, emoji => + { + GetIcon(emoji); + }); + } + + public static BitmapSource GetIcon(string emoji) + { + return _iconCache.GetOrAdd(emoji, x => GetBitmapSource(x, 64)); + } } } diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.cs index 318b2a530..51dacea47 100644 --- a/src/Greenshot.Editor/Forms/ImageEditorForm.cs +++ b/src/Greenshot.Editor/Forms/ImageEditorForm.cs @@ -27,6 +27,7 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; using Greenshot.Base; using Greenshot.Base.Controls; @@ -40,6 +41,7 @@ using Greenshot.Base.Interfaces.Forms; using Greenshot.Base.UnmanagedHelpers; using Greenshot.Base.UnmanagedHelpers.Structs; using Greenshot.Editor.Configuration; +using Greenshot.Editor.Controls; using Greenshot.Editor.Destinations; using Greenshot.Editor.Drawing; using Greenshot.Editor.Drawing.Fields; @@ -142,6 +144,9 @@ namespace Greenshot.Editor.Forms private void Initialize(ISurface surface, bool outputMade) { + // Compute emojis in background + EmojiData.Load(); + EditorList.Add(this); // @@ -186,14 +191,6 @@ namespace Greenshot.Editor.Forms // Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it. HideToolstripItems(); - - HideEmojiButtonWhenFontIsNotInstalled(); - } - - private void HideEmojiButtonWhenFontIsNotInstalled() - { - _emojifontInstalled ??= FontFamily.Families.Any(f => string.Equals(f.Name, "Segoe UI Emoji", StringComparison.OrdinalIgnoreCase)); - btnEmoji.Visible = _emojifontInstalled.Value; } ///