mirror of
https://github.com/greenshot/greenshot
synced 2025-08-22 06:23:24 -07:00
Resources as files + "use system font" bool
This commit is contained in:
parent
9757829abe
commit
870af8bd33
8 changed files with 153 additions and 91 deletions
|
@ -1,17 +1,17 @@
|
||||||
using System;
|
using System.Windows;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
using Greenshot.Editor.Drawing;
|
using Greenshot.Editor.Drawing;
|
||||||
|
|
||||||
namespace Greenshot.Editor.Controls
|
namespace Greenshot.Editor.Controls
|
||||||
{
|
{
|
||||||
internal class EmojiControl : Image
|
internal class EmojiControl : Image
|
||||||
{
|
{
|
||||||
public static readonly DependencyProperty EmojiProperty = DependencyProperty.Register("Emoji", typeof(string), typeof(EmojiControl), new PropertyMetadata(default(string), PropertyChangedCallback));
|
public static readonly DependencyProperty EmojiProperty = DependencyProperty.Register("Emoji", typeof(string), typeof(EmojiControl), new PropertyMetadata(default(string), OnEmojiPropertyChanged));
|
||||||
|
|
||||||
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
private static void OnEmojiPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
((EmojiControl)d).Source = EmojiRenderer.GetBitmapSource((string)e.NewValue, iconSize: 48);
|
((EmojiControl)d).Source = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Emoji
|
public string Emoji
|
||||||
|
@ -19,5 +19,28 @@ namespace Greenshot.Editor.Controls
|
||||||
get { return (string)GetValue(EmojiProperty); }
|
get { return (string)GetValue(EmojiProperty); }
|
||||||
set { SetValue(EmojiProperty, value); }
|
set { SetValue(EmojiProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty UseSystemFontProperty = DependencyProperty.Register("UseSystemFont", typeof(bool), typeof(EmojiControl), new PropertyMetadata(default(bool), OnUseSystemFontPropertyChanged));
|
||||||
|
|
||||||
|
private static void OnUseSystemFontPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
((EmojiControl)d).Source = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnRender(DrawingContext dc)
|
||||||
|
{
|
||||||
|
if (Source == null && !string.IsNullOrEmpty(Emoji))
|
||||||
|
{
|
||||||
|
Source = EmojiRenderer.GetBitmapSource(Emoji, iconSize: 48, useSystemFont: UseSystemFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRender(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UseSystemFont
|
||||||
|
{
|
||||||
|
get { return (bool)GetValue(UseSystemFontProperty); }
|
||||||
|
set { SetValue(UseSystemFontProperty, value); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Greenshot.Editor.Drawing;
|
|
||||||
using SixLabors.Fonts.Unicode;
|
using SixLabors.Fonts.Unicode;
|
||||||
|
|
||||||
namespace Greenshot.Editor.Controls
|
namespace Greenshot.Editor.Controls
|
||||||
|
@ -87,7 +86,7 @@ namespace Greenshot.Editor.Controls
|
||||||
select e;
|
select e;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string m_match_one_string;
|
private static string m_match_one_string;
|
||||||
|
|
||||||
// FIXME: this could be read directly from emoji-test.txt.gz
|
// FIXME: this could be read directly from emoji-test.txt.gz
|
||||||
private static List<string> SkinToneComponents = new List<string>
|
private static List<string> SkinToneComponents = new List<string>
|
||||||
|
@ -190,7 +189,7 @@ namespace Greenshot.Editor.Controls
|
||||||
var unqualified = text.Replace("\ufe0f", "");
|
var unqualified = text.Replace("\ufe0f", "");
|
||||||
if (qualified_lut.ContainsKey(unqualified))
|
if (qualified_lut.ContainsKey(unqualified))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Fix simple fully-qualified emojis
|
// Fix simple fully-qualified emojis
|
||||||
if (CodePoint.GetCodePointCount(text.AsSpan()) == 2)
|
if (CodePoint.GetCodePointCount(text.AsSpan()) == 2)
|
||||||
{
|
{
|
||||||
|
@ -242,8 +241,8 @@ namespace Greenshot.Editor.Controls
|
||||||
|
|
||||||
private static IEnumerable<string> EmojiDescriptionLines()
|
private static IEnumerable<string> EmojiDescriptionLines()
|
||||||
{
|
{
|
||||||
using var stream = Assembly.GetCallingAssembly().GetManifestResourceStream("Greenshot.Editor.Resources.emoji-test.txt");
|
using var fileStream = new FileStream(Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), @"Resources\emoji-test.txt"), FileMode.Open, FileAccess.Read);
|
||||||
using var streamReader = new StreamReader(stream);
|
using var streamReader = new StreamReader(fileStream);
|
||||||
return streamReader.ReadToEnd().Split('\r', '\n');
|
return streamReader.ReadToEnd().Split('\r', '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
BorderThickness="1" Height="Auto" Padding="0" Margin="1"
|
BorderThickness="1" Height="Auto" Padding="0" Margin="1"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
MaxWidth="280"> <!-- 6 columns -->
|
MaxWidth="280">
|
||||||
|
<!-- 6 columns -->
|
||||||
<ListView.ItemsPanel>
|
<ListView.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<WrapPanel/>
|
<WrapPanel/>
|
||||||
|
@ -35,7 +36,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}"/>
|
<controls:EmojiControl Height="24" UseSystemFont="{Binding UseSystemFont, ElementName=StackPanel_INTERNAL, Mode=OneWay}" Emoji="{Binding Path=Text}" />
|
||||||
</Button>
|
</Button>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
|
@ -47,7 +48,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}"
|
<controls:EmojiControl Height="24" Margin="4" UseSystemFont="{Binding UseSystemFont, ElementName=StackPanel_INTERNAL, Mode=OneWay}" 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"
|
||||||
|
@ -70,67 +71,73 @@
|
||||||
StaysOpen="False"
|
StaysOpen="False"
|
||||||
KeyDown="OnPopupKeyDown" Loaded="OnPopupLoaded"
|
KeyDown="OnPopupKeyDown" Loaded="OnPopupLoaded"
|
||||||
AllowsTransparency="True" Margin="0">
|
AllowsTransparency="True" Margin="0">
|
||||||
|
<Border>
|
||||||
<TabControl ItemsSource="{Binding EmojiGroups, ElementName=StackPanel_INTERNAL}" Padding="0">
|
<StackPanel Orientation="Vertical">
|
||||||
<TabControl.ItemTemplate>
|
<TabControl ItemsSource="{Binding EmojiGroups, ElementName=StackPanel_INTERNAL}" Padding="0">
|
||||||
<DataTemplate>
|
<TabControl.ItemTemplate>
|
||||||
<Grid>
|
<DataTemplate>
|
||||||
<controls:EmojiControl Height="24" Emoji="{Binding Icon}">
|
<Grid>
|
||||||
<Image.ToolTip>
|
<controls:EmojiControl Height="24" UseSystemFont="{Binding UseSystemFont, ElementName=StackPanel_INTERNAL, Mode=OneWay}" Emoji="{Binding Icon}" >
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<Image.ToolTip>
|
||||||
</Image.ToolTip>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
</controls:EmojiControl>
|
</Image.ToolTip>
|
||||||
</Grid>
|
</controls:EmojiControl>
|
||||||
</DataTemplate>
|
</Grid>
|
||||||
</TabControl.ItemTemplate>
|
</DataTemplate>
|
||||||
<TabControl.ContentTemplate>
|
</TabControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<TabControl.ContentTemplate>
|
||||||
<StackPanel Orientation="Vertical">
|
<DataTemplate>
|
||||||
<ListView Name="EmojiListView" ItemsSource="{Binding EmojiChunkList}"
|
<StackPanel Orientation="Vertical">
|
||||||
|
<ListView Name="EmojiListView" ItemsSource="{Binding EmojiChunkList}"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
MaxHeight="320" Height="Auto" Padding="0" Margin="1"
|
MaxHeight="320" Height="Auto" Padding="0" Margin="1"
|
||||||
VirtualizingStackPanel.IsVirtualizing="True"
|
VirtualizingStackPanel.IsVirtualizing="True"
|
||||||
VirtualizingStackPanel.VirtualizationMode="Recycling"
|
VirtualizingStackPanel.VirtualizationMode="Recycling"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||||
<ListView.ItemsPanel>
|
<ListView.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<VirtualizingStackPanel />
|
<VirtualizingStackPanel />
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ListView.ItemsPanel>
|
</ListView.ItemsPanel>
|
||||||
<ListView.ItemContainerStyle>
|
<ListView.ItemContainerStyle>
|
||||||
<Style TargetType="{x:Type ListViewItem}">
|
<Style TargetType="{x:Type ListViewItem}">
|
||||||
<!-- Get rid of the ugly padding and margin in default ListViewItem -->
|
<!-- Get rid of the ugly padding and margin in default ListViewItem -->
|
||||||
<Setter Property="Padding" Value="0"/>
|
<Setter Property="Padding" Value="0"/>
|
||||||
<Setter Property="Margin" Value="0"/>
|
<Setter Property="Margin" Value="0"/>
|
||||||
<Setter Property="BorderThickness" Value="0"/>
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
<!-- Remove the mouse over highlight -->
|
<!-- Remove the mouse over highlight -->
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type ListViewItem}">
|
<ControlTemplate TargetType="{x:Type ListViewItem}">
|
||||||
<ContentPresenter/>
|
<ContentPresenter/>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ListView.ItemContainerStyle>
|
</ListView.ItemContainerStyle>
|
||||||
<!-- Now for our actual content -->
|
<!-- Now for our actual content -->
|
||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<ItemsControl ItemsSource="{Binding}"
|
<ItemsControl ItemsSource="{Binding}"
|
||||||
ItemTemplate="{StaticResource ResourceKey=CellTemplate}">
|
ItemTemplate="{StaticResource ResourceKey=CellTemplate}">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<StackPanel Orientation="Horizontal"/>
|
<StackPanel Orientation="Horizontal"/>
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
</ListView>
|
</ListView>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</TabControl.ContentTemplate>
|
</TabControl.ContentTemplate>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
<CheckBox VerticalContentAlignment="Center" IsChecked="{Binding UseSystemFont, ElementName=StackPanel_INTERNAL}" >
|
||||||
|
Use system font
|
||||||
|
</CheckBox>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
|
@ -42,6 +42,14 @@ namespace Greenshot.Editor.Controls
|
||||||
|
|
||||||
public IList<EmojiData.Group> EmojiGroups => EmojiData.AllGroups;
|
public IList<EmojiData.Group> EmojiGroups => EmojiData.AllGroups;
|
||||||
|
|
||||||
|
public static readonly DependencyProperty UseSystemFontProperty = DependencyProperty.Register("UseSystemFont", typeof(bool), typeof(EmojiPicker), new PropertyMetadata(default(bool)));
|
||||||
|
|
||||||
|
public bool UseSystemFont
|
||||||
|
{
|
||||||
|
get { return (bool)GetValue(UseSystemFontProperty); }
|
||||||
|
set { SetValue(UseSystemFontProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
// Backwards compatibility for when the backend was a TextBlock.
|
// Backwards compatibility for when the backend was a TextBlock.
|
||||||
public double FontSize
|
public double FontSize
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,12 +24,9 @@ using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Forms.Integration;
|
using System.Windows.Forms.Integration;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using Greenshot.Base.Core;
|
using Greenshot.Base.Core;
|
||||||
using Greenshot.Base.Interfaces.Drawing;
|
using Greenshot.Base.Interfaces.Drawing;
|
||||||
using Greenshot.Editor.Controls;
|
using Greenshot.Editor.Controls;
|
||||||
|
@ -37,7 +34,6 @@ using Greenshot.Editor.Drawing.Adorners;
|
||||||
using Greenshot.Editor.Helpers;
|
using Greenshot.Editor.Helpers;
|
||||||
using Image = System.Drawing.Image;
|
using Image = System.Drawing.Image;
|
||||||
using Matrix = System.Drawing.Drawing2D.Matrix;
|
using Matrix = System.Drawing.Drawing2D.Matrix;
|
||||||
using Size = System.Windows.Size;
|
|
||||||
|
|
||||||
namespace Greenshot.Editor.Drawing
|
namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
|
@ -56,6 +52,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private string _emoji;
|
private string _emoji;
|
||||||
private int _rotationAngle;
|
private int _rotationAngle;
|
||||||
|
private bool _useSystemFont;
|
||||||
|
|
||||||
public string Emoji
|
public string Emoji
|
||||||
{
|
{
|
||||||
|
@ -67,6 +64,16 @@ namespace Greenshot.Editor.Drawing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool UseSystemFont
|
||||||
|
{
|
||||||
|
get => _useSystemFont;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_useSystemFont = value;
|
||||||
|
ResetCachedBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EmojiContainer(Surface parent) : this(parent, "🙂", size: 64)
|
public EmojiContainer(Surface parent) : this(parent, "🙂", size: 64)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -111,6 +118,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
_emojiPicker.Picked += (_, args) =>
|
_emojiPicker.Picked += (_, args) =>
|
||||||
{
|
{
|
||||||
_currentContainer.Emoji = args.Emoji;
|
_currentContainer.Emoji = args.Emoji;
|
||||||
|
_currentContainer.UseSystemFont = _emojiPicker.UseSystemFont;
|
||||||
_currentContainer.Invalidate();
|
_currentContainer.Invalidate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -211,7 +219,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
private Image ComputeBitmap(int iconSize)
|
private Image ComputeBitmap(int iconSize)
|
||||||
{
|
{
|
||||||
var image = EmojiRenderer.GetBitmap(Emoji, iconSize);
|
var image = EmojiRenderer.GetBitmap(Emoji, iconSize, useSystemFont: _useSystemFont);
|
||||||
if (_rotationAngle != 0)
|
if (_rotationAngle != 0)
|
||||||
{
|
{
|
||||||
var newImage = image.Rotate(_rotationAngle);
|
var newImage = image.Rotate(_rotationAngle);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
@ -19,28 +20,37 @@ namespace Greenshot.Editor.Drawing
|
||||||
{
|
{
|
||||||
internal static class EmojiRenderer
|
internal static class EmojiRenderer
|
||||||
{
|
{
|
||||||
private static Lazy<FontFamily> _fontFamily = new Lazy<FontFamily>(() =>
|
static FontCollection _fontCollection = new FontCollection();
|
||||||
|
|
||||||
|
private static Lazy<FontFamily> _twemoji = new Lazy<FontFamily>(() =>
|
||||||
{
|
{
|
||||||
using var stream = Assembly.GetCallingAssembly().GetManifestResourceStream("Greenshot.Editor.Resources.TwemojiMozilla.ttf");
|
using var fileStream = new FileStream(Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), @"Resources\TwemojiMozilla.ttf"), FileMode.Open, FileAccess.Read);
|
||||||
var fontCollection = new FontCollection();
|
_fontCollection.Add(fileStream);
|
||||||
fontCollection.Add(stream);
|
_fontCollection.TryGet("Twemoji Mozilla", out var fontFamily);
|
||||||
fontCollection.TryGet("Twemoji Mozilla", out var fontFamily);
|
|
||||||
return fontFamily;
|
return fontFamily;
|
||||||
});
|
});
|
||||||
|
|
||||||
public static Image<Rgba32> GetImage(string emoji, int iconSize)
|
private static Lazy<FontFamily> _segoeUI = new Lazy<FontFamily>(() =>
|
||||||
|
{
|
||||||
|
using var fileStream = new FileStream(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), @"Fonts\seguiemj.ttf"), FileMode.Open, FileAccess.Read);
|
||||||
|
_fontCollection.Add(fileStream);
|
||||||
|
_fontCollection.TryGet("Segoe UI Emoji", out var fontFamily);
|
||||||
|
return fontFamily;
|
||||||
|
});
|
||||||
|
|
||||||
|
public static Image<Rgba32> GetImage(string emoji, int iconSize, bool useSystemFont)
|
||||||
{
|
{
|
||||||
var image = new Image<Rgba32>(iconSize, iconSize);
|
var image = new Image<Rgba32>(iconSize, iconSize);
|
||||||
|
|
||||||
RenderEmoji(emoji, iconSize, image);
|
RenderEmoji(emoji, iconSize, image, useSystemFont);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RenderEmoji(string emoji, int iconSize, SixLabors.ImageSharp.Image image)
|
private static void RenderEmoji(string emoji, int iconSize, SixLabors.ImageSharp.Image image, bool useSystemFont)
|
||||||
{
|
{
|
||||||
var font = _fontFamily.Value.CreateFont(iconSize, FontStyle.Regular);
|
var fontFamily = useSystemFont ? _segoeUI.Value : _twemoji.Value;
|
||||||
|
var font = fontFamily.CreateFont(useSystemFont ? iconSize * 0.95f : iconSize, FontStyle.Regular);
|
||||||
var verticalOffset = font.Size * 0.045f;
|
var verticalOffset = useSystemFont ? -font.Size * 0.050f : font.Size * 0.045f;
|
||||||
var textOptions = new TextOptions(font)
|
var textOptions = new TextOptions(font)
|
||||||
{
|
{
|
||||||
Origin = new SixLabors.ImageSharp.PointF(font.Size / 2.0f, font.Size / 2.0f - verticalOffset),
|
Origin = new SixLabors.ImageSharp.PointF(font.Size / 2.0f, font.Size / 2.0f - verticalOffset),
|
||||||
|
@ -51,7 +61,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
image.Mutate(x => x.DrawText(textOptions, emoji, SixLabors.ImageSharp.Color.Black));
|
image.Mutate(x => x.DrawText(textOptions, emoji, SixLabors.ImageSharp.Color.Black));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Image GetBitmap(string emoji, int iconSize)
|
public static Image GetBitmap(string emoji, int iconSize, bool useSystemFont)
|
||||||
{
|
{
|
||||||
int width = iconSize;
|
int width = iconSize;
|
||||||
int height = iconSize;
|
int height = iconSize;
|
||||||
|
@ -64,7 +74,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
var image = SixLabors.ImageSharp.Image.WrapMemory<Bgra32>((void*)bitmapData.Scan0, width: width, height: height);
|
var image = SixLabors.ImageSharp.Image.WrapMemory<Bgra32>((void*)bitmapData.Scan0, width: width, height: height);
|
||||||
RenderEmoji(emoji, iconSize, image);
|
RenderEmoji(emoji, iconSize, image, useSystemFont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -75,7 +85,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BitmapSource GetBitmapSource(string emoji, int iconSize)
|
public static BitmapSource GetBitmapSource(string emoji, int iconSize, bool useSystemFont)
|
||||||
{
|
{
|
||||||
var pixelFormat = PixelFormats.Bgra32;
|
var pixelFormat = PixelFormats.Bgra32;
|
||||||
int width = iconSize;
|
int width = iconSize;
|
||||||
|
@ -85,7 +95,7 @@ namespace Greenshot.Editor.Drawing
|
||||||
|
|
||||||
var image = SixLabors.ImageSharp.Image.WrapMemory<Bgra32>(byteMemory: pixels, width: width, height: height);
|
var image = SixLabors.ImageSharp.Image.WrapMemory<Bgra32>(byteMemory: pixels, width: width, height: height);
|
||||||
|
|
||||||
RenderEmoji(emoji, iconSize, image);
|
RenderEmoji(emoji, iconSize, image, useSystemFont);
|
||||||
|
|
||||||
var source = BitmapSource.Create(pixelWidth: width, pixelHeight: height, dpiX: 96, dpiY: 96, pixelFormat: pixelFormat, palette: null, pixels: pixels, stride: stride);
|
var source = BitmapSource.Create(pixelWidth: width, pixelHeight: height, dpiX: 96, dpiY: 96, pixelFormat: pixelFormat, palette: null, pixels: pixels, stride: stride);
|
||||||
source.Freeze();
|
source.Freeze();
|
||||||
|
|
|
@ -450,7 +450,7 @@ namespace Greenshot.Editor.Forms {
|
||||||
//
|
//
|
||||||
this.btnEmoji.CheckOnClick = true;
|
this.btnEmoji.CheckOnClick = true;
|
||||||
this.btnEmoji.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
this.btnEmoji.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||||
this.btnEmoji.Image = EmojiRenderer.GetBitmap("🙂", 32);
|
this.btnEmoji.Image = EmojiRenderer.GetBitmap("🙂", 32, useSystemFont: false);
|
||||||
this.btnEmoji.ImageTransparentColor = System.Drawing.Color.Magenta;
|
this.btnEmoji.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||||
this.btnEmoji.Text = "Emoji (M)";
|
this.btnEmoji.Text = "Emoji (M)";
|
||||||
this.btnEmoji.Name = "btnEmoji";
|
this.btnEmoji.Name = "btnEmoji";
|
||||||
|
|
|
@ -86,7 +86,14 @@
|
||||||
<EmbeddedResource Update="Forms\ImageEditorForm.resx">
|
<EmbeddedResource Update="Forms\ImageEditorForm.resx">
|
||||||
<DependentUpon>ImageEditorForm.cs</DependentUpon>
|
<DependentUpon>ImageEditorForm.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Resources\emoji-test.txt" />
|
</ItemGroup>
|
||||||
<EmbeddedResource Include="Resources\TwemojiMozilla.ttf" />
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Resources\emoji-test.txt">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Resources\TwemojiMozilla.ttf">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Add table
Add a link
Reference in a new issue