diff --git a/src/Greenshot.Base/Interfaces/Drawing/Container.cs b/src/Greenshot.Base/Interfaces/Drawing/Container.cs
index 7eb595fdf..1fc35eeb2 100644
--- a/src/Greenshot.Base/Interfaces/Drawing/Container.cs
+++ b/src/Greenshot.Base/Interfaces/Drawing/Container.cs
@@ -135,6 +135,11 @@ namespace Greenshot.Base.Interfaces.Drawing
void Load(string filename);
}
+ public interface IEmojiContainer : IDrawableContainer
+ {
+ string Emoji { get; set; }
+ }
+
public interface ICursorContainer : IDrawableContainer
{
Cursor Cursor { get; set; }
diff --git a/src/Greenshot.Base/Interfaces/DrawingModes.cs b/src/Greenshot.Base/Interfaces/DrawingModes.cs
index cd84aea4f..d406038c5 100644
--- a/src/Greenshot.Base/Interfaces/DrawingModes.cs
+++ b/src/Greenshot.Base/Interfaces/DrawingModes.cs
@@ -35,6 +35,7 @@ namespace Greenshot.Base.Interfaces
Bitmap,
Path,
SpeechBubble,
- StepLabel
+ StepLabel,
+ Emoji
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Interfaces/ISurface.cs b/src/Greenshot.Base/Interfaces/ISurface.cs
index 7b8d6884e..ca0ee3a48 100644
--- a/src/Greenshot.Base/Interfaces/ISurface.cs
+++ b/src/Greenshot.Base/Interfaces/ISurface.cs
@@ -93,6 +93,7 @@ namespace Greenshot.Base.Interfaces
IImageContainer AddImageContainer(string filename, int x, int y);
ICursorContainer AddCursorContainer(string filename, int x, int y);
IIconContainer AddIconContainer(string filename, int x, int y);
+ IEmojiContainer AddEmojiContainer(string emoji, int x, int y, int size);
long SaveElementsToStream(Stream stream);
void LoadElementsFromStream(Stream stream);
diff --git a/src/Greenshot.Editor/Drawing/EmojiContainer.cs b/src/Greenshot.Editor/Drawing/EmojiContainer.cs
new file mode 100644
index 000000000..cd419d79a
--- /dev/null
+++ b/src/Greenshot.Editor/Drawing/EmojiContainer.cs
@@ -0,0 +1,191 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: https://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Windows.Forms;
+using System.Windows.Forms.Integration;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Greenshot.Base.Interfaces.Drawing;
+using Greenshot.Editor.Drawing.Adorners;
+using Greenshot.Editor.Helpers;
+using log4net;
+using Point = System.Drawing.Point;
+using Size = System.Windows.Size;
+
+namespace Greenshot.Editor.Drawing
+{
+ ///
+ /// Description of EmojiContainer.
+ ///
+ [Serializable]
+ public class EmojiContainer : DrawableContainer, IEmojiContainer
+ {
+ private static readonly ILog Log = LogManager.GetLogger(typeof(IconContainer));
+
+ [NonSerialized] private System.Windows.Controls.Image _image;
+
+ private int _rotateAngle;
+ private string _emoji;
+
+ public string Emoji
+ {
+ get => _emoji;
+ set
+ {
+ _emoji = value;
+ if (_image != null)
+ {
+ global::Emoji.Wpf.Image.SetSource(_image, Emoji);
+ }
+ }
+ }
+
+ public EmojiContainer(Surface parent) : this(parent, "🙂", size: 64)
+ {
+ }
+
+ public EmojiContainer(Surface parent, string emoji, int size) : base(parent)
+ {
+ Emoji = emoji;
+ Width = size;
+ Height = size;
+ Init();
+ }
+
+ public override void OnDoubleClick()
+ {
+ var host = new ElementHost();
+ host.Dock = DockStyle.None;
+ var rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
+ host.Width = rect.Width;
+ host.Height = rect.Height;
+ host.Left = rect.Left;
+ host.Top = rect.Top;
+
+ var picker = new Emoji.Wpf.Picker { Selection = Emoji };
+ picker.Picked += (o, args) =>
+ {
+ Emoji = args.Emoji;
+ _parent.Controls.Remove(host);
+
+ };
+ host.Child = picker;
+
+ if (_parent != null)
+ {
+ _parent.KeysLocked = true;
+ _parent.Controls.Add(host);
+ }
+
+ host.Show();
+ host.Focus();
+ }
+
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
+
+ // Create WPF control
+ _image = new System.Windows.Controls.Image();
+ global::Emoji.Wpf.Image.SetSource(_image, Emoji);
+ }
+
+ public override void Transform(System.Drawing.Drawing2D.Matrix matrix)
+ {
+ _rotateAngle += CalculateAngle(matrix);
+ _rotateAngle %= 360;
+ base.Transform(matrix);
+ }
+
+ public override void Draw(Graphics graphics, RenderMode rm)
+ {
+ graphics.SmoothingMode = SmoothingMode.HighQuality;
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+ graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+
+ var rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
+
+ var iconSize = Math.Min(rect.Width, rect.Height);
+
+ if (iconSize > 0)
+ {
+ _image.Measure(new Size(iconSize, iconSize));
+ _image.Arrange(new Rect(0, 0, iconSize, iconSize));
+
+ var renderTargetBitmap = new RenderTargetBitmap(iconSize, iconSize, 96, 96, PixelFormats.Pbgra32);
+ renderTargetBitmap.Render(_image);
+
+ using var bitmap = BitmapFromSource(renderTargetBitmap);
+
+ if (_rotateAngle != 0)
+ {
+ graphics.DrawImage(RotateImage(bitmap, _rotateAngle), Bounds);
+ return;
+ }
+
+ graphics.DrawImage(bitmap, Bounds);
+ }
+ }
+ private Bitmap BitmapFromSource(BitmapSource bitmapSource)
+ {
+ var src = new FormatConvertedBitmap();
+ src.BeginInit();
+ src.Source = bitmapSource;
+ src.DestinationFormat = PixelFormats.Bgra32;
+ src.EndInit();
+
+ var bitmap = new Bitmap(src.PixelWidth, src.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ var data = bitmap.LockBits(new Rectangle(new Point(0, 0), bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ src.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
+ bitmap.UnlockBits(data);
+
+ return bitmap;
+ }
+
+ private static Image RotateImage(Image img, float rotationAngle)
+ {
+ var bitmap = new Bitmap(img.Width, img.Height);
+
+ using var gfx = Graphics.FromImage(bitmap);
+ gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
+
+ gfx.TranslateTransform((float)bitmap.Width / 2, (float)bitmap.Height / 2);
+ gfx.RotateTransform(rotationAngle);
+ gfx.TranslateTransform(-(float)bitmap.Width / 2, -(float)bitmap.Height / 2);
+
+ gfx.DrawImage(img, new Point(0, 0));
+
+ return bitmap;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/ImageContainer.cs b/src/Greenshot.Editor/Drawing/ImageContainer.cs
index a46b0dae5..5ccf01c4e 100644
--- a/src/Greenshot.Editor/Drawing/ImageContainer.cs
+++ b/src/Greenshot.Editor/Drawing/ImageContainer.cs
@@ -179,16 +179,19 @@ namespace Greenshot.Editor.Drawing
///
public override void Transform(Matrix matrix)
{
- int rotateAngle = CalculateAngle(matrix);
- // we currently assume only one transformation has been made.
- if (rotateAngle != 0)
+ if (image != null)
{
- Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle);
- DisposeShadow();
- using var tmpMatrix = new Matrix();
- using (image)
+ int rotateAngle = CalculateAngle(matrix);
+ // we currently assume only one transformation has been made.
+ if (rotateAngle != 0)
{
- image = ImageHelper.ApplyEffect(image, new RotateEffect(rotateAngle), tmpMatrix);
+ Log.DebugFormat("Rotating element with {0} degrees.", rotateAngle);
+ DisposeShadow();
+ using var tmpMatrix = new Matrix();
+ using (image)
+ {
+ image = ImageHelper.ApplyEffect(image, new RotateEffect(rotateAngle), tmpMatrix);
+ }
}
}
diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs
index 7fd7485d0..644718598 100644
--- a/src/Greenshot.Editor/Drawing/Surface.cs
+++ b/src/Greenshot.Editor/Drawing/Surface.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom
*
@@ -748,6 +748,9 @@ namespace Greenshot.Editor.Drawing
case DrawingModes.None:
_undrawnElement = null;
break;
+ case DrawingModes.Emoji:
+ _undrawnElement = new EmojiContainer(this);
+ break;
}
if (_undrawnElement != null)
@@ -802,6 +805,15 @@ namespace Greenshot.Editor.Drawing
return iconContainer;
}
+ public IEmojiContainer AddEmojiContainer(string emoji, int x, int y, int size)
+ {
+ var iconContainer = new EmojiContainer(this, emoji, size);
+ iconContainer.Left = x;
+ iconContainer.Top = y;
+ AddElement(iconContainer);
+ return iconContainer;
+ }
+
public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y)
{
CursorContainer cursorContainer = new CursorContainer(this)
diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.Designer.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.Designer.cs
index 82fecf559..938068f8e 100644
--- a/src/Greenshot.Editor/Forms/ImageEditorForm.Designer.cs
+++ b/src/Greenshot.Editor/Forms/ImageEditorForm.Designer.cs
@@ -70,7 +70,8 @@ namespace Greenshot.Editor.Forms {
this.btnText = new GreenshotToolStripButton();
this.btnSpeechBubble = new GreenshotToolStripButton();
this.btnStepLabel = new GreenshotToolStripButton();
- this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator();
+ this.btnEmoji = new GreenshotToolStripButton();
+ this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator();
this.btnHighlight = new GreenshotToolStripButton();
this.btnObfuscate = new GreenshotToolStripButton();
this.toolStripSplitButton1 = new GreenshotToolStripDropDownButton();
@@ -334,8 +335,9 @@ namespace Greenshot.Editor.Forms {
this.btnText,
this.btnSpeechBubble,
this.btnStepLabel,
+ this.btnEmoji,
this.toolStripSeparator14,
- this.btnHighlight,
+ this.btnHighlight,
this.btnObfuscate,
this.toolStripSplitButton1,
this.toolStripSeparator13,
@@ -443,10 +445,20 @@ namespace Greenshot.Editor.Forms {
this.btnStepLabel.LanguageKey = "editor_counter";
this.btnStepLabel.Name = "btnStepLabel";
this.btnStepLabel.Click += new System.EventHandler(this.BtnStepLabelClick);
- //
- // toolStripSeparator14
- //
- this.toolStripSeparator14.Name = "toolStripSeparator14";
+ //
+ // btnStepEmoji
+ //
+ this.btnEmoji.CheckOnClick = true;
+ this.btnEmoji.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.btnEmoji.Image = ((System.Drawing.Image)(resources.GetObject("btnEmoji.Image")));
+ this.btnEmoji.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.btnEmoji.LanguageKey = "editor_emoji";
+ this.btnEmoji.Name = "btnEmoji";
+ this.btnEmoji.Click += new System.EventHandler(this.BtnEmojiClick);
+ //
+ // toolStripSeparator14
+ //
+ this.toolStripSeparator14.Name = "toolStripSeparator14";
//
// btnHighlight
//
@@ -1928,7 +1940,8 @@ namespace Greenshot.Editor.Forms {
private GreenshotToolStripButton btnText;
private GreenshotToolStripButton btnSpeechBubble;
private GreenshotToolStripButton btnStepLabel;
- private GreenshotToolStripMenuItem drawLineToolStripMenuItem;
+ private GreenshotToolStripButton btnEmoji;
+ private GreenshotToolStripMenuItem drawLineToolStripMenuItem;
private GreenshotToolStripButton btnLine;
private GreenshotToolStripButton btnSettings;
private GreenshotToolStripButton btnHelp;
diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.cs
index e3b65b980..20b4de8cb 100644
--- a/src/Greenshot.Editor/Forms/ImageEditorForm.cs
+++ b/src/Greenshot.Editor/Forms/ImageEditorForm.cs
@@ -269,7 +269,7 @@ namespace Greenshot.Editor.Forms
_toolbarButtons = new[]
{
- btnCursor, btnRect, btnEllipse, btnText, btnLine, btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop, btnStepLabel, btnSpeechBubble
+ btnCursor, btnRect, btnEllipse, btnText, btnLine, btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop, btnStepLabel, btnSpeechBubble, btnEmoji
};
//toolbarDropDownButtons = new ToolStripDropDownButton[]{btnBlur, btnPixeliate, btnTextHighlighter, btnAreaHighlighter, btnMagnifier};
@@ -655,6 +655,12 @@ namespace Greenshot.Editor.Forms
RefreshFieldControls();
}
+ private void BtnEmojiClick(object sender, EventArgs e)
+ {
+ _surface.DrawingMode = DrawingModes.Emoji;
+ RefreshFieldControls();
+ }
+
private void BtnLineClick(object sender, EventArgs e)
{
_surface.DrawingMode = DrawingModes.Line;
diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.resx b/src/Greenshot.Editor/Forms/ImageEditorForm.resx
index 57fe2f2c7..63524f930 100644
--- a/src/Greenshot.Editor/Forms/ImageEditorForm.resx
+++ b/src/Greenshot.Editor/Forms/ImageEditorForm.resx
@@ -1107,4 +1107,7 @@
782, 17
+
+ ..\Resources\btnEmoji.Image.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Greenshot.Editor.csproj b/src/Greenshot.Editor/Greenshot.Editor.csproj
index 768bdb99d..601a9f38d 100644
--- a/src/Greenshot.Editor/Greenshot.Editor.csproj
+++ b/src/Greenshot.Editor/Greenshot.Editor.csproj
@@ -4,6 +4,9 @@
PreserveNewest
+
+
+
@@ -81,4 +84,8 @@
ImageEditorForm.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Resources/btnEmoji.Image.bmp b/src/Greenshot.Editor/Resources/btnEmoji.Image.bmp
new file mode 100644
index 000000000..fa6bf1b07
Binary files /dev/null and b/src/Greenshot.Editor/Resources/btnEmoji.Image.bmp differ
diff --git a/src/Greenshot/Languages/language-en-US.xml b/src/Greenshot/Languages/language-en-US.xml
index 3db9fbf0e..09570f11f 100644
--- a/src/Greenshot/Languages/language-en-US.xml
+++ b/src/Greenshot/Languages/language-en-US.xml
@@ -305,8 +305,9 @@ All Greenshot features still work directly from the tray icon context menu witho
Add counter (I)
Add speechbubble (S)
+ Add emoji
- Resize
+ Resize
Resize settings
Maintain aspect ratio
Width