mirror of
https://github.com/greenshot/greenshot
synced 2025-08-24 07:06:23 -07:00
Add icon cache
This commit is contained in:
parent
69fcb22df2
commit
9e45eb29d6
5 changed files with 52 additions and 19 deletions
|
@ -11,7 +11,7 @@ namespace Greenshot.Editor.Controls
|
||||||
|
|
||||||
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
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
|
public string Emoji
|
||||||
|
|
|
@ -17,11 +17,15 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Greenshot.Editor.Drawing;
|
||||||
|
|
||||||
namespace Greenshot.Editor.Controls
|
namespace Greenshot.Editor.Controls
|
||||||
{
|
{
|
||||||
public static class EmojiData
|
public static class EmojiData
|
||||||
{
|
{
|
||||||
|
private static Task _init;
|
||||||
|
|
||||||
public static IEnumerable<Emoji> AllEmoji
|
public static IEnumerable<Emoji> AllEmoji
|
||||||
=> from g in AllGroups
|
=> from g in AllGroups
|
||||||
from e in g.EmojiList
|
from e in g.EmojiList
|
||||||
|
@ -38,13 +42,14 @@ namespace Greenshot.Editor.Controls
|
||||||
public static HashSet<char> MatchStart { get; private set; }
|
public static HashSet<char> MatchStart { get; private set; }
|
||||||
= new HashSet<char>();
|
= new HashSet<char>();
|
||||||
|
|
||||||
// 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()
|
public static void Load()
|
||||||
|
{
|
||||||
|
_init = Task.Run(() =>
|
||||||
{
|
{
|
||||||
ParseEmojiList();
|
ParseEmojiList();
|
||||||
|
|
||||||
|
EmojiRenderer.FillIconCache(AllEmoji.Select(e => e.Text));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Emoji
|
public class Emoji
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<Button Background="Transparent" BorderBrush="Transparent"
|
<Button Background="Transparent" BorderBrush="Transparent"
|
||||||
Margin="0" Click="OnEmojiPicked"
|
Margin="0" Click="OnEmojiPicked"
|
||||||
Width="40" Height="40" ToolTip="{Binding Path=Name}">
|
Width="40" Height="40" ToolTip="{Binding Path=Name}">
|
||||||
<controls:EmojiControl Height="24" Emoji="{Binding Path=Text, IsAsync=True}"/>
|
<controls:EmojiControl Height="24" Emoji="{Binding Path=Text}"/>
|
||||||
</Button>
|
</Button>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
x:Name="VariationButton" Background="Transparent" BorderBrush="Transparent"
|
x:Name="VariationButton" Background="Transparent" BorderBrush="Transparent"
|
||||||
Click="OnEmojiPicked" Focusable="False" ToolTip="{Binding Path=Name}">
|
Click="OnEmojiPicked" Focusable="False" ToolTip="{Binding Path=Name}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<controls:EmojiControl Height="24" Margin="4" Emoji="{Binding Path=Text, IsAsync=True}"
|
<controls:EmojiControl Height="24" Margin="4" Emoji="{Binding Path=Text}"
|
||||||
VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
VerticalAlignment="Center" HorizontalAlignment="Center"/>
|
||||||
<Polygon Visibility="{Binding HasVariations, Converter={StaticResource BoolToVis}}"
|
<Polygon Visibility="{Binding HasVariations, Converter={StaticResource BoolToVis}}"
|
||||||
Width="6" Height="6" VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
Width="6" Height="6" VerticalAlignment="Bottom" HorizontalAlignment="Right"
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
using System.Drawing;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using SixLabors.Fonts;
|
using SixLabors.Fonts;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
|
@ -9,8 +12,10 @@ using SixLabors.ImageSharp.Drawing.Processing;
|
||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using Font = SixLabors.Fonts.Font;
|
||||||
using FontStyle = SixLabors.Fonts.FontStyle;
|
using FontStyle = SixLabors.Fonts.FontStyle;
|
||||||
using Image = System.Drawing.Image;
|
using Image = System.Drawing.Image;
|
||||||
|
using TextOptions = SixLabors.Fonts.TextOptions;
|
||||||
|
|
||||||
namespace Greenshot.Editor.Drawing
|
namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
|
@ -18,6 +23,8 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
private static SixLabors.Fonts.FontFamily? _fontFamily;
|
private static SixLabors.Fonts.FontFamily? _fontFamily;
|
||||||
|
|
||||||
|
private static ConcurrentDictionary<string, BitmapSource> _iconCache = new ConcurrentDictionary<string, BitmapSource>();
|
||||||
|
|
||||||
public static Image<Rgba32> GetImage(string emoji, int iconSize)
|
public static Image<Rgba32> GetImage(string emoji, int iconSize)
|
||||||
{
|
{
|
||||||
if (_fontFamily == null)
|
if (_fontFamily == null)
|
||||||
|
@ -32,12 +39,23 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
|
|
||||||
var font = _fontFamily.Value.CreateFont(iconSize, FontStyle.Regular);
|
var font = _fontFamily.Value.CreateFont(iconSize, FontStyle.Regular);
|
||||||
|
|
||||||
var image = new Image<Rgba32>(iconSize, iconSize);
|
var image = new Image<Rgba32>(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<Rgba32> 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));
|
image.Mutate(x => x.DrawText(textOptions, emoji, SixLabors.ImageSharp.Color.Black));
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Image GetBitmap(string emoji, int iconSize)
|
public static Image GetBitmap(string emoji, int iconSize)
|
||||||
|
@ -82,5 +100,18 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void FillIconCache(IEnumerable<string> emojis)
|
||||||
|
{
|
||||||
|
Parallel.ForEach(emojis, emoji =>
|
||||||
|
{
|
||||||
|
GetIcon(emoji);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitmapSource GetIcon(string emoji)
|
||||||
|
{
|
||||||
|
return _iconCache.GetOrAdd(emoji, x => GetBitmapSource(x, 64));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Greenshot.Base;
|
using Greenshot.Base;
|
||||||
using Greenshot.Base.Controls;
|
using Greenshot.Base.Controls;
|
||||||
|
@ -40,6 +41,7 @@ using Greenshot.Base.Interfaces.Forms;
|
||||||
using Greenshot.Base.UnmanagedHelpers;
|
using Greenshot.Base.UnmanagedHelpers;
|
||||||
using Greenshot.Base.UnmanagedHelpers.Structs;
|
using Greenshot.Base.UnmanagedHelpers.Structs;
|
||||||
using Greenshot.Editor.Configuration;
|
using Greenshot.Editor.Configuration;
|
||||||
|
using Greenshot.Editor.Controls;
|
||||||
using Greenshot.Editor.Destinations;
|
using Greenshot.Editor.Destinations;
|
||||||
using Greenshot.Editor.Drawing;
|
using Greenshot.Editor.Drawing;
|
||||||
using Greenshot.Editor.Drawing.Fields;
|
using Greenshot.Editor.Drawing.Fields;
|
||||||
|
@ -142,6 +144,9 @@ namespace Greenshot.Editor.Forms
|
||||||
|
|
||||||
private void Initialize(ISurface surface, bool outputMade)
|
private void Initialize(ISurface surface, bool outputMade)
|
||||||
{
|
{
|
||||||
|
// Compute emojis in background
|
||||||
|
EmojiData.Load();
|
||||||
|
|
||||||
EditorList.Add(this);
|
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.
|
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
|
||||||
HideToolstripItems();
|
HideToolstripItems();
|
||||||
|
|
||||||
HideEmojiButtonWhenFontIsNotInstalled();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HideEmojiButtonWhenFontIsNotInstalled()
|
|
||||||
{
|
|
||||||
_emojifontInstalled ??= FontFamily.Families.Any(f => string.Equals(f.Name, "Segoe UI Emoji", StringComparison.OrdinalIgnoreCase));
|
|
||||||
btnEmoji.Visible = _emojifontInstalled.Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue