diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs
new file mode 100644
index 000000000..866bc3f97
--- /dev/null
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs
@@ -0,0 +1,105 @@
+/*
+ * 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.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Base.Core.FileFormatHandlers
+{
+ ///
+ /// THis is the default .NET bitmap file format handler
+ ///
+ public class DefaultFileFormatHandler : IFileFormatHandler
+ {
+ private static readonly string [] OurExtensions = { "png", "bmp", "gif", "jpg", "jpeg", "tiff", "tif" };
+
+ ///
+ public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return Enumerable.Empty();
+ }
+
+ return OurExtensions;
+ }
+
+ ///
+ public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return false;
+ }
+
+ return OurExtensions.Contains(extension);
+ }
+
+ ///
+ public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ return int.MaxValue;
+ }
+
+ ///
+ public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ ImageFormat imageFormat = extension?.ToLowerInvariant() switch
+ {
+ "png" => ImageFormat.Png,
+ "bmp" => ImageFormat.Bmp,
+ "gif" => ImageFormat.Gif,
+ "jpg" => ImageFormat.Jpeg,
+ "jpeg" => ImageFormat.Jpeg,
+ "tiff" => ImageFormat.Tiff,
+ "tif" => ImageFormat.Tiff,
+ _ => null
+ };
+
+ if (imageFormat == null)
+ {
+ return false;
+ }
+ bitmap.Save(destination, imageFormat);
+ return true;
+ }
+
+ ///
+ public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
+ {
+ using var tmpImage = Image.FromStream(stream, true, true);
+ bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb);
+ return true;
+ }
+
+ ///
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs
new file mode 100644
index 000000000..f43d8ff54
--- /dev/null
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs
@@ -0,0 +1,60 @@
+/*
+ * 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.IO;
+using System.Linq;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Base.Core.FileFormatHandlers
+{
+ public class GreenshotFileFormatHandler : IFileFormatHandler
+ {
+ private static readonly string[] SupportedExtensions = { "greenshot" };
+
+ public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return false;
+ }
+ return SupportedExtensions.Contains(extension);
+ }
+
+ public void SaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Bitmap Load(Stream stream, string extension)
+ {
+ var surface = SimpleServiceProvider.Current.GetInstance>().Invoke();
+ return (Bitmap)surface.GetImageForExport();
+ }
+
+ public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs
new file mode 100644
index 000000000..92a21a1ac
--- /dev/null
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs
@@ -0,0 +1,162 @@
+/*
+ * 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.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+using log4net;
+
+namespace Greenshot.Base.Core.FileFormatHandlers
+{
+ ///
+ /// THis is the default .NET bitmap file format handler
+ ///
+ public class IconFileFormatHandler : IFileFormatHandler
+ {
+ private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper));
+
+ private static readonly string[] OurExtensions = { "ico" };
+
+ ///
+ public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return Enumerable.Empty();
+ }
+
+ return OurExtensions;
+ }
+
+ ///
+ public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return false;
+ }
+
+ return OurExtensions.Contains(extension);
+ }
+
+ ///
+ public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ return int.MaxValue;
+ }
+
+ public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ // TODO: Implement this
+ return false;
+ }
+
+ public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
+ {
+ var startingPosition = stream.Seek(0, SeekOrigin.Current);
+
+ // Icon logic, try to get the Vista icon, else the biggest possible
+ try
+ {
+ using Image tmpImage = ExtractVistaIcon(stream);
+ if (tmpImage != null)
+ {
+ bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb);
+ return true;
+ }
+ }
+ catch (Exception vistaIconException)
+ {
+ Log.Warn("Can't read icon", vistaIconException);
+ }
+
+ try
+ {
+ // No vista icon, try normal icon
+ stream.Position = stream.Seek(0, SeekOrigin.Begin);
+ // We create a copy of the bitmap, so everything else can be disposed
+ using Icon tmpIcon = new Icon(stream, new Size(1024, 1024));
+ using Image tmpImage = tmpIcon.ToBitmap();
+ bitmap = ImageHelper.Clone(tmpImage, PixelFormat.Format32bppArgb);
+ return true;
+ }
+ catch (Exception iconException)
+ {
+ Log.Warn("Can't read icon", iconException);
+ }
+
+ bitmap = null;
+ return false;
+ }
+
+
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent)
+ {
+ // TODO: Implement this
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx
+ /// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx
+ ///
+ /// Stream with the icon information
+ /// Bitmap with the Vista Icon (256x256)
+ private static Bitmap ExtractVistaIcon(Stream iconStream)
+ {
+ const int sizeIconDir = 6;
+ const int sizeIconDirEntry = 16;
+ Bitmap bmpPngExtracted = null;
+ try
+ {
+ byte[] srcBuf = new byte[iconStream.Length];
+ // TODO: Check if there is a need to process the result
+ _ = iconStream.Read(srcBuf, 0, (int)iconStream.Length);
+ int iCount = BitConverter.ToInt16(srcBuf, 4);
+ for (int iIndex = 0; iIndex < iCount; iIndex++)
+ {
+ int iWidth = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex];
+ int iHeight = srcBuf[sizeIconDir + sizeIconDirEntry * iIndex + 1];
+ if (iWidth != 0 || iHeight != 0) continue;
+
+ int iImageSize = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 8);
+ int iImageOffset = BitConverter.ToInt32(srcBuf, sizeIconDir + sizeIconDirEntry * iIndex + 12);
+ using MemoryStream destStream = new MemoryStream();
+ destStream.Write(srcBuf, iImageOffset, iImageSize);
+ destStream.Seek(0, SeekOrigin.Begin);
+ bmpPngExtracted = new Bitmap(destStream); // This is PNG! :)
+ break;
+ }
+ }
+ catch
+ {
+ return null;
+ }
+
+ return bmpPngExtracted;
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs
new file mode 100644
index 000000000..6eab0ae6a
--- /dev/null
+++ b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs
@@ -0,0 +1,59 @@
+/*
+ * 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.IO;
+using System.Linq;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Base.Core.FileFormatHandlers
+{
+ public class PngFileFormatHandler : IFileFormatHandler
+ {
+ private static readonly string[] SupportedExtensions = { "png" };
+
+ public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
+ {
+ return false;
+ }
+ return SupportedExtensions.Contains(extension);
+ }
+
+ public void SaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Bitmap Load(Stream stream, string extension)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/Greenshot.Base/Core/IImage.cs b/src/Greenshot.Base/Core/IImage.cs
index d6b30c667..20aa320d9 100644
--- a/src/Greenshot.Base/Core/IImage.cs
+++ b/src/Greenshot.Base/Core/IImage.cs
@@ -61,7 +61,7 @@ namespace Greenshot.Base.Core
float HorizontalResolution { get; }
///
- /// Unterlying image, or an on demand rendered version with different attributes as the original
+ /// Underlying image, or an on demand rendered version with different attributes as the original
///
Image Image { get; }
}
diff --git a/src/Greenshot.Base/Core/ImageHelper.cs b/src/Greenshot.Base/Core/ImageHelper.cs
index 60d846eac..4aa0207fc 100644
--- a/src/Greenshot.Base/Core/ImageHelper.cs
+++ b/src/Greenshot.Base/Core/ImageHelper.cs
@@ -25,6 +25,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
+using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Effects;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
@@ -55,84 +56,15 @@ namespace Greenshot.Base.Core
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection();
private const int ExifOrientationId = 0x0112;
+ public static readonly IList FileFormatHandlers = new List();
+
static ImageHelper()
{
- StreamConverters["greenshot"] = (stream, s) =>
- {
- var surface = SimpleServiceProvider.Current.GetInstance>().Invoke();
- return surface.GetImageForExport();
- };
-
- // Add a SVG converter
- StreamConverters["svg"] = (stream, s) =>
- {
- stream.Position = 0;
- try
- {
- return SvgImage.FromStream(stream).Image;
- }
- catch (Exception ex)
- {
- Log.Error("Can't load SVG", ex);
- }
-
- return null;
- };
-
- static Image DefaultConverter(Stream stream, string s)
- {
- stream.Position = 0;
- using var tmpImage = Image.FromStream(stream, true, true);
- Log.DebugFormat("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
- return Clone(tmpImage, PixelFormat.Format32bppArgb);
- }
-
- // Fallback
- StreamConverters[string.Empty] = DefaultConverter;
- StreamConverters["gif"] = DefaultConverter;
- StreamConverters["bmp"] = DefaultConverter;
- StreamConverters["jpg"] = DefaultConverter;
- StreamConverters["jpeg"] = DefaultConverter;
- StreamConverters["png"] = DefaultConverter;
- StreamConverters["wmf"] = DefaultConverter;
-
- StreamConverters["ico"] = (stream, extension) =>
- {
- // Icon logic, try to get the Vista icon, else the biggest possible
- try
- {
- using Image tmpImage = ExtractVistaIcon(stream);
- if (tmpImage != null)
- {
- return Clone(tmpImage, PixelFormat.Format32bppArgb);
- }
- }
- catch (Exception vistaIconException)
- {
- Log.Warn("Can't read icon", vistaIconException);
- }
-
- try
- {
- // No vista icon, try normal icon
- stream.Position = 0;
- // We create a copy of the bitmap, so everything else can be disposed
- using Icon tmpIcon = new Icon(stream, new Size(1024, 1024));
- using Image tmpImage = tmpIcon.ToBitmap();
- return Clone(tmpImage, PixelFormat.Format32bppArgb);
- }
- catch (Exception iconException)
- {
- Log.Warn("Can't read icon", iconException);
- }
-
- stream.Position = 0;
- return DefaultConverter(stream, extension);
- };
+ FileFormatHandlers.Add(new IconFileFormatHandler());
+ FileFormatHandlers.Add(new GreenshotFileFormatHandler());
+ FileFormatHandlers.Add(new DefaultFileFormatHandler());
}
- public static IDictionary> StreamConverters { get; } = new Dictionary>();
-
///
/// Make sure the image is orientated correctly
///
@@ -563,8 +495,7 @@ namespace Greenshot.Base.Core
/// Changed bitmap
public static Image CreateTornEdge(Image sourceImage, int toothHeight, int horizontalToothRange, int verticalToothRange, bool[] edges)
{
- Image returnImage = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb, Color.Empty, sourceImage.HorizontalResolution,
- sourceImage.VerticalResolution);
+ Image returnImage = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
using (var path = new GraphicsPath())
{
Random random = new Random();
@@ -1516,10 +1447,10 @@ namespace Greenshot.Base.Core
///
///
/// The color to fill with, or Color.Empty to take the default depending on the pixel format
- ///
- ///
+ /// float
+ /// float
/// Bitmap
- public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution, float verticalResolution)
+ public static Bitmap CreateEmpty(int width, int height, PixelFormat format, Color backgroundColor, float horizontalResolution = 96f, float verticalResolution = 96f)
{
// Create a new "clean" image
Bitmap newImage = new Bitmap(width, height, format);
@@ -1777,31 +1708,50 @@ namespace Greenshot.Base.Core
extension = extension.Replace(".", string.Empty);
}
+ var startingPosition = stream.Position;
+
// Make sure we can try multiple times
if (!stream.CanSeek)
{
var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
stream = memoryStream;
+ // As we are if a different stream, which starts at 0, change the starting position
+ startingPosition = 0;
}
- Image returnImage = null;
- if (StreamConverters.TryGetValue(extension ?? string.Empty, out var converter))
+ foreach (var fileFormatHandler in FileFormatHandlers)
{
- returnImage = converter(stream, extension);
+ if (!fileFormatHandler.CanDoActionForExtension(FileFormatHandlerActions.Load, extension)) continue;
+
+ stream.Seek(startingPosition, SeekOrigin.Begin);
+ return fileFormatHandler.Load(stream, extension);
}
- // Fallback
- if (returnImage == null)
- {
- // We create a copy of the bitmap, so everything else can be disposed
- stream.Position = 0;
- using var tmpImage = Image.FromStream(stream, true, true);
- Log.DebugFormat("Loaded bitmap with Size {0}x{1} and PixelFormat {2}", tmpImage.Width, tmpImage.Height, tmpImage.PixelFormat);
- returnImage = Clone(tmpImage, PixelFormat.Format32bppArgb);
- }
+ return null;
+ }
- return returnImage;
+
+ ///
+ /// Rotate the image
+ ///
+ /// Input image
+ /// Angle in degrees
+ /// Rotated image
+ public static Image Rotate(this Image image, float rotationAngle)
+ {
+ var bitmap = CreateEmptyLike(image, Color.Transparent);
+
+ 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(image, new Point(0, 0));
+
+ return bitmap;
}
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Core/ImageWrapper.cs b/src/Greenshot.Base/Core/ImageWrapper.cs
deleted file mode 100644
index 517249534..000000000
--- a/src/Greenshot.Base/Core/ImageWrapper.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using System.Drawing;
-using System.Drawing.Imaging;
-
-namespace Greenshot.Base.Core
-{
- ///
- /// Wrap an image, make it resizeable
- ///
- public class ImageWrapper : IImage
- {
- // Underlying image, is used to generate a resized version of it when needed
- private readonly Image _image;
- private Image _imageClone;
-
- public ImageWrapper(Image image)
- {
- // Make sure the orientation is set correctly so Greenshot can process the image correctly
- ImageHelper.Orientate(image);
- _image = image;
- Width = _image.Width;
- Height = _image.Height;
- }
-
- public void Dispose()
- {
- _image.Dispose();
- _imageClone?.Dispose();
- }
-
- ///
- /// Height of the image, can be set to change
- ///
- public int Height { get; set; }
-
- ///
- /// Width of the image, can be set to change.
- ///
- public int Width { get; set; }
-
- ///
- /// Size of the image
- ///
- public Size Size => new Size(Width, Height);
-
- ///
- /// Pixelformat of the underlying image
- ///
- public PixelFormat PixelFormat => Image.PixelFormat;
-
- public float HorizontalResolution => Image.HorizontalResolution;
- public float VerticalResolution => Image.VerticalResolution;
-
- public Image Image
- {
- get
- {
- if (_imageClone == null)
- {
- if (_image.Height == Height && _image.Width == Width)
- {
- return _image;
- }
- }
-
- if (_imageClone?.Height == Height && _imageClone?.Width == Width)
- {
- return _imageClone;
- }
-
- // Calculate new image clone
- _imageClone?.Dispose();
- _imageClone = ImageHelper.ResizeImage(_image, false, Width, Height, null);
- return _imageClone;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Core/SvgImage.cs b/src/Greenshot.Base/Core/SvgImage.cs
deleted file mode 100644
index 25f98b212..000000000
--- a/src/Greenshot.Base/Core/SvgImage.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using Svg;
-
-namespace Greenshot.Base.Core
-{
- ///
- /// Create an image look like of the SVG
- ///
- public sealed class SvgImage : IImage
- {
- private readonly SvgDocument _svgDocument;
-
- private Image _imageClone;
-
- ///
- /// Factory to create via a stream
- ///
- /// Stream
- /// IImage
- public static IImage FromStream(Stream stream)
- {
- return new SvgImage(stream);
- }
-
- ///
- /// Default constructor
- ///
- ///
- public SvgImage(Stream stream)
- {
- _svgDocument = SvgDocument.Open(stream);
- Height = (int) _svgDocument.ViewBox.Height;
- Width = (int) _svgDocument.ViewBox.Width;
- }
-
- ///
- /// Height of the image, can be set to change
- ///
- public int Height { get; set; }
-
- ///
- /// Width of the image, can be set to change.
- ///
- public int Width { get; set; }
-
- ///
- /// Size of the image
- ///
- public Size Size => new Size(Width, Height);
-
- ///
- /// Pixelformat of the underlying image
- ///
- public PixelFormat PixelFormat => Image.PixelFormat;
-
- ///
- /// Horizontal resolution of the underlying image
- ///
- public float HorizontalResolution => Image.HorizontalResolution;
-
- ///
- /// Vertical resolution of the underlying image
- ///
- public float VerticalResolution => Image.VerticalResolution;
-
- ///
- /// Underlying image, or an on demand rendered version with different attributes as the original
- ///
- public Image Image
- {
- get
- {
- if (_imageClone?.Height == Height && _imageClone?.Width == Width)
- {
- return _imageClone;
- }
-
- // Calculate new image clone
- _imageClone?.Dispose();
- _imageClone = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent, 96, 96);
- _svgDocument.Draw((Bitmap) _imageClone);
- return _imageClone;
- }
- }
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- public void Dispose()
- {
- _imageClone?.Dispose();
- }
- }
-}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Interfaces/Drawing/Container.cs b/src/Greenshot.Base/Interfaces/Drawing/Container.cs
index 4f653ac8a..6eb0e2b35 100644
--- a/src/Greenshot.Base/Interfaces/Drawing/Container.cs
+++ b/src/Greenshot.Base/Interfaces/Drawing/Container.cs
@@ -135,7 +135,7 @@ namespace Greenshot.Base.Interfaces.Drawing
public interface IImageContainer : IDrawableContainer
{
- Image Image { get; set; }
+ Image Image { get; }
void Load(string filename);
}
diff --git a/src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs b/src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
new file mode 100644
index 000000000..fdbf72847
--- /dev/null
+++ b/src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
@@ -0,0 +1,33 @@
+/*
+ * 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 .
+ */
+
+namespace Greenshot.Base.Interfaces.Drawing
+{
+ public interface IFieldAggregator
+ {
+ void UnbindElement(IDrawableContainer dc);
+ void BindElements(IDrawableContainerList dcs);
+ void BindElement(IDrawableContainer dc);
+ IField GetField(IFieldType fieldType);
+
+ event FieldChangedEventHandler FieldChanged;
+ }
+}
diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
new file mode 100644
index 000000000..e7d5c7a83
--- /dev/null
+++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
@@ -0,0 +1,96 @@
+/*
+ * 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.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Base.Interfaces
+{
+ ///
+ /// The possible actions a IFileFormatHandler might support
+ ///
+ public enum FileFormatHandlerActions
+ {
+ SaveToStream,
+ Load,
+ LoadDrawableFromStream
+ }
+
+ ///
+ /// This interface is for code to implement the loading and saving of certain file formats
+ ///
+ public interface IFileFormatHandler
+ {
+ ///
+ /// Delivers the extension that the supplied action supports
+ ///
+ /// FileFormatHandlerActions
+ /// IEnumerable{string}
+ IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction);
+
+ ///
+ ///Does this IFileFormatHandler support the specified action for the specified extension?
+ ///
+ /// FileFormatHandlerActions
+ /// string
+ /// bool true if this IFileFormatHandler can support the action for the extension
+ public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension);
+
+ ///
+ /// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension
+ /// This should be used to sort the possible IFileFormatHandler
+ ///
+ /// FileFormatHandlerActions
+ /// string
+ /// int specifying the priority for the action and extension
+ public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension);
+
+ ///
+ /// Try to save the specified bitmap to the stream in the format belonging to the extension
+ ///
+ /// Bitmap
+ /// Stream
+ /// extension
+ /// bool true if it was successful
+ public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension);
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// bool true if it was successful
+ public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap);
+
+ ///
+ /// Try to load a drawable container from the stream
+ ///
+ /// Stream
+ /// string
+ /// IDrawableContainer out
+ /// ISurface
+ /// bool true if it was successful
+ public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent);
+ }
+}
diff --git a/src/Greenshot.Base/Interfaces/ISurface.cs b/src/Greenshot.Base/Interfaces/ISurface.cs
index d5df7ff44..85cefe452 100644
--- a/src/Greenshot.Base/Interfaces/ISurface.cs
+++ b/src/Greenshot.Base/Interfaces/ISurface.cs
@@ -21,6 +21,7 @@
using System;
using System.Drawing;
+using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
using Greenshot.Base.Core;
@@ -201,5 +202,14 @@ namespace Greenshot.Base.Interfaces
Rectangle ToImageCoordinates(Rectangle rc);
void MakeUndoable(IMemento memento, bool allowMerge);
+
+ IFieldAggregator FieldAggregator { get; }
+
+ ///
+ /// This reverses a change of the background image
+ ///
+ /// Image
+ /// Matrix
+ void UndoBackgroundChange(Image previous, Matrix matrix);
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/ArrowContainer.cs b/src/Greenshot.Editor/Drawing/ArrowContainer.cs
index f285d28bc..eb1e10e2f 100644
--- a/src/Greenshot.Editor/Drawing/ArrowContainer.cs
+++ b/src/Greenshot.Editor/Drawing/ArrowContainer.cs
@@ -22,6 +22,7 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
@@ -43,7 +44,7 @@ namespace Greenshot.Editor.Drawing
private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6);
- public ArrowContainer(Surface parent) : base(parent)
+ public ArrowContainer(ISurface parent) : base(parent)
{
}
diff --git a/src/Greenshot.Editor/Drawing/CropContainer.cs b/src/Greenshot.Editor/Drawing/CropContainer.cs
index 1aa4e06c2..2324331f0 100644
--- a/src/Greenshot.Editor/Drawing/CropContainer.cs
+++ b/src/Greenshot.Editor/Drawing/CropContainer.cs
@@ -21,6 +21,7 @@
using System.Drawing;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -32,7 +33,7 @@ namespace Greenshot.Editor.Drawing
///
public class CropContainer : DrawableContainer
{
- public CropContainer(Surface parent) : base(parent)
+ public CropContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/CursorContainer.cs b/src/Greenshot.Editor/Drawing/CursorContainer.cs
index d2e19adba..0eda46085 100644
--- a/src/Greenshot.Editor/Drawing/CursorContainer.cs
+++ b/src/Greenshot.Editor/Drawing/CursorContainer.cs
@@ -25,6 +25,7 @@ using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using log4net;
@@ -40,7 +41,7 @@ namespace Greenshot.Editor.Drawing
protected Cursor cursor;
- public CursorContainer(Surface parent) : base(parent)
+ public CursorContainer(ISurface parent) : base(parent)
{
Init();
}
@@ -56,7 +57,7 @@ namespace Greenshot.Editor.Drawing
CreateDefaultAdorners();
}
- public CursorContainer(Surface parent, string filename) : this(parent)
+ public CursorContainer(ISurface parent, string filename) : this(parent)
{
Load(filename);
}
diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
index b7202b23e..08f6ae18e 100644
--- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs
+++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
@@ -126,12 +126,17 @@ namespace Greenshot.Editor.Drawing
}
}
- [NonSerialized] internal Surface _parent;
+ [NonSerialized] internal ISurface _parent;
public ISurface Parent
{
get => _parent;
- set => SwitchParent((Surface) value);
+ set => SwitchParent(value);
+ }
+
+ protected Surface InternalParent
+ {
+ get => (Surface)_parent;
}
[NonSerialized] private TargetAdorner _targetAdorner;
@@ -277,7 +282,7 @@ namespace Greenshot.Editor.Drawing
Height = Round(newBounds.Height);
}
- public DrawableContainer(Surface parent)
+ public DrawableContainer(ISurface parent)
{
InitializeFields();
_parent = parent;
@@ -512,7 +517,7 @@ namespace Greenshot.Editor.Drawing
{
Invalidate();
- // reset "workrbench" rectangle to current bounds
+ // reset "workbench" rectangle to current bounds
_boundsAfterResize.X = _boundsBeforeResize.Left;
_boundsAfterResize.Y = _boundsBeforeResize.Top;
_boundsAfterResize.Width = x - _boundsAfterResize.Left;
@@ -536,7 +541,7 @@ namespace Greenshot.Editor.Drawing
{
}
- protected virtual void SwitchParent(Surface newParent)
+ protected virtual void SwitchParent(ISurface newParent)
{
if (newParent == Parent)
{
diff --git a/src/Greenshot.Editor/Drawing/EllipseContainer.cs b/src/Greenshot.Editor/Drawing/EllipseContainer.cs
index f7799ac71..b32ecffd3 100644
--- a/src/Greenshot.Editor/Drawing/EllipseContainer.cs
+++ b/src/Greenshot.Editor/Drawing/EllipseContainer.cs
@@ -23,6 +23,7 @@ using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -35,7 +36,7 @@ namespace Greenshot.Editor.Drawing
[Serializable()]
public class EllipseContainer : DrawableContainer
{
- public EllipseContainer(Surface parent) : base(parent)
+ public EllipseContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/Fields/FieldAggregator.cs b/src/Greenshot.Editor/Drawing/Fields/FieldAggregator.cs
index 2df16d46f..96a19b7b9 100644
--- a/src/Greenshot.Editor/Drawing/Fields/FieldAggregator.cs
+++ b/src/Greenshot.Editor/Drawing/Fields/FieldAggregator.cs
@@ -42,7 +42,7 @@ namespace Greenshot.Editor.Drawing.Fields
/// If the property values of the selected elements differ, the value of the last bound element wins.
///
[Serializable]
- public sealed class FieldAggregator : AbstractFieldHolder
+ public sealed class FieldAggregator : AbstractFieldHolder, IFieldAggregator
{
private readonly IDrawableContainerList _boundContainers;
private bool _internalUpdateRunning;
@@ -117,11 +117,10 @@ namespace Greenshot.Editor.Drawing.Fields
public void UnbindElement(IDrawableContainer dc)
{
- if (_boundContainers.Contains(dc))
- {
- _boundContainers.Remove(dc);
- UpdateFromBoundElements();
- }
+ if (!_boundContainers.Contains(dc)) return;
+
+ _boundContainers.Remove(dc);
+ UpdateFromBoundElements();
}
public void Clear()
diff --git a/src/Greenshot.Editor/Drawing/FilterContainer.cs b/src/Greenshot.Editor/Drawing/FilterContainer.cs
index 3bdb5a5fd..c6d1f8f26 100644
--- a/src/Greenshot.Editor/Drawing/FilterContainer.cs
+++ b/src/Greenshot.Editor/Drawing/FilterContainer.cs
@@ -23,6 +23,7 @@ using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -51,7 +52,7 @@ namespace Greenshot.Editor.Drawing
MAGNIFICATION
};
- public FilterContainer(Surface parent) : base(parent)
+ public FilterContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/FreehandContainer.cs b/src/Greenshot.Editor/Drawing/FreehandContainer.cs
index e37221551..ef1c69ff3 100644
--- a/src/Greenshot.Editor/Drawing/FreehandContainer.cs
+++ b/src/Greenshot.Editor/Drawing/FreehandContainer.cs
@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -50,7 +51,7 @@ namespace Greenshot.Editor.Drawing
///
/// Constructor
///
- public FreehandContainer(Surface parent) : base(parent)
+ public FreehandContainer(ISurface parent) : base(parent)
{
Width = parent.Image.Width;
Height = parent.Image.Height;
diff --git a/src/Greenshot.Editor/Drawing/HighlightContainer.cs b/src/Greenshot.Editor/Drawing/HighlightContainer.cs
index 417725322..58cf792ba 100644
--- a/src/Greenshot.Editor/Drawing/HighlightContainer.cs
+++ b/src/Greenshot.Editor/Drawing/HighlightContainer.cs
@@ -21,6 +21,7 @@
using System;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Drawing.Filters;
@@ -33,7 +34,7 @@ namespace Greenshot.Editor.Drawing
[Serializable]
public class HighlightContainer : FilterContainer
{
- public HighlightContainer(Surface parent) : base(parent)
+ public HighlightContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/IconContainer.cs b/src/Greenshot.Editor/Drawing/IconContainer.cs
index e98b37f82..adda1cc23 100644
--- a/src/Greenshot.Editor/Drawing/IconContainer.cs
+++ b/src/Greenshot.Editor/Drawing/IconContainer.cs
@@ -24,6 +24,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using log4net;
@@ -39,7 +40,7 @@ namespace Greenshot.Editor.Drawing
protected Icon icon;
- public IconContainer(Surface parent) : base(parent)
+ public IconContainer(ISurface parent) : base(parent)
{
Init();
}
@@ -55,7 +56,7 @@ namespace Greenshot.Editor.Drawing
CreateDefaultAdorners();
}
- public IconContainer(Surface parent, string filename) : base(parent)
+ public IconContainer(ISurface parent, string filename) : base(parent)
{
Load(filename);
}
diff --git a/src/Greenshot.Editor/Drawing/ImageContainer.cs b/src/Greenshot.Editor/Drawing/ImageContainer.cs
index a46b0dae5..68b4cd797 100644
--- a/src/Greenshot.Editor/Drawing/ImageContainer.cs
+++ b/src/Greenshot.Editor/Drawing/ImageContainer.cs
@@ -26,6 +26,7 @@ using System.IO;
using System.Runtime.Serialization;
using Greenshot.Base.Core;
using Greenshot.Base.Effects;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using log4net;
@@ -54,12 +55,12 @@ namespace Greenshot.Editor.Drawing
///
[NonSerialized] private Point _shadowOffset = new Point(-1, -1);
- public ImageContainer(Surface parent, string filename) : this(parent)
+ public ImageContainer(ISurface parent, string filename) : this(parent)
{
Load(filename);
}
- public ImageContainer(Surface parent) : base(parent)
+ public ImageContainer(ISurface parent) : base(parent)
{
FieldChanged += BitmapContainer_OnFieldChanged;
Init();
diff --git a/src/Greenshot.Editor/Drawing/LineContainer.cs b/src/Greenshot.Editor/Drawing/LineContainer.cs
index 1bcf25a81..729872be6 100644
--- a/src/Greenshot.Editor/Drawing/LineContainer.cs
+++ b/src/Greenshot.Editor/Drawing/LineContainer.cs
@@ -23,6 +23,7 @@ using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Adorners;
using Greenshot.Editor.Drawing.Fields;
@@ -36,7 +37,7 @@ namespace Greenshot.Editor.Drawing
[Serializable()]
public class LineContainer : DrawableContainer
{
- public LineContainer(Surface parent) : base(parent)
+ public LineContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/ObfuscateContainer.cs b/src/Greenshot.Editor/Drawing/ObfuscateContainer.cs
index 1754ba650..b0c890ffc 100644
--- a/src/Greenshot.Editor/Drawing/ObfuscateContainer.cs
+++ b/src/Greenshot.Editor/Drawing/ObfuscateContainer.cs
@@ -21,6 +21,7 @@
using System;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Drawing.Filters;
@@ -28,12 +29,12 @@ using Greenshot.Editor.Drawing.Filters;
namespace Greenshot.Editor.Drawing
{
///
- /// Description of ObfuscateContainer.
+ /// This is a FilterContainer for the obfuscator filters like blur and pixelate.
///
[Serializable]
public class ObfuscateContainer : FilterContainer
{
- public ObfuscateContainer(Surface parent) : base(parent)
+ public ObfuscateContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/RectangleContainer.cs b/src/Greenshot.Editor/Drawing/RectangleContainer.cs
index 5e38fcf4b..4dd6543a7 100644
--- a/src/Greenshot.Editor/Drawing/RectangleContainer.cs
+++ b/src/Greenshot.Editor/Drawing/RectangleContainer.cs
@@ -23,6 +23,7 @@ using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -35,7 +36,7 @@ namespace Greenshot.Editor.Drawing
[Serializable]
public class RectangleContainer : DrawableContainer
{
- public RectangleContainer(Surface parent) : base(parent)
+ public RectangleContainer(ISurface parent) : base(parent)
{
Init();
}
diff --git a/src/Greenshot.Editor/Drawing/SpeechbubbleContainer.cs b/src/Greenshot.Editor/Drawing/SpeechbubbleContainer.cs
index 2b189945d..0a19805e7 100644
--- a/src/Greenshot.Editor/Drawing/SpeechbubbleContainer.cs
+++ b/src/Greenshot.Editor/Drawing/SpeechbubbleContainer.cs
@@ -24,6 +24,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -64,8 +65,7 @@ namespace Greenshot.Editor.Drawing
InitAdorner(Color.Green, _storedTargetGripperLocation);
}
- public SpeechbubbleContainer(Surface parent)
- : base(parent)
+ public SpeechbubbleContainer(ISurface parent) : base(parent)
{
}
diff --git a/src/Greenshot.Editor/Drawing/StepLabelContainer.cs b/src/Greenshot.Editor/Drawing/StepLabelContainer.cs
index 0e7c27516..8e9217721 100644
--- a/src/Greenshot.Editor/Drawing/StepLabelContainer.cs
+++ b/src/Greenshot.Editor/Drawing/StepLabelContainer.cs
@@ -24,6 +24,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.Serialization;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -41,9 +42,9 @@ namespace Greenshot.Editor.Drawing
private readonly bool _drawAsRectangle = false;
- public StepLabelContainer(Surface parent) : base(parent)
+ public StepLabelContainer(ISurface parent) : base(parent)
{
- parent.AddStepLabel(this);
+ InternalParent?.AddStepLabel(this);
InitContent();
Init();
}
@@ -72,11 +73,10 @@ namespace Greenshot.Editor.Drawing
[OnSerializing]
private void SetValuesOnSerializing(StreamingContext context)
{
- if (Parent != null)
- {
- Number = ((Surface) Parent).CountStepLabels(this);
- _counterStart = ((Surface) Parent).CounterStart;
- }
+ if (InternalParent == null) return;
+
+ Number = InternalParent.CountStepLabels(this);
+ _counterStart = InternalParent.CounterStart;
}
///
@@ -97,23 +97,23 @@ namespace Greenshot.Editor.Drawing
/// Add the StepLabel to the parent
///
///
- protected override void SwitchParent(Surface newParent)
+ protected override void SwitchParent(ISurface newParent)
{
if (newParent == Parent)
{
return;
}
- ((Surface) Parent)?.RemoveStepLabel(this);
- base.SwitchParent(newParent);
- if (newParent == null)
+ if (newParent is not Surface newParentSurface)
{
return;
}
+ InternalParent?.RemoveStepLabel(this);
+ base.SwitchParent(newParent);
// Make sure the counter start is restored (this unfortunately happens multiple times... -> hack)
- newParent.CounterStart = _counterStart;
- newParent.AddStepLabel(this);
+ newParentSurface.CounterStart = _counterStart;
+ newParentSurface.AddStepLabel(this);
}
public override Size DefaultSize => new Size(30, 30);
diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs
index 5093ed201..2445cb486 100644
--- a/src/Greenshot.Editor/Drawing/Surface.cs
+++ b/src/Greenshot.Editor/Drawing/Surface.cs
@@ -294,7 +294,7 @@ namespace Greenshot.Editor.Drawing
///
/// all elements on the surface, needed with serialization
///
- private FieldAggregator _fieldAggregator;
+ private IFieldAggregator _fieldAggregator;
///
/// the cursor container, needed with serialization as we need a direct acces to it.
@@ -355,7 +355,7 @@ namespace Greenshot.Editor.Drawing
/// The field aggregator is that which is used to have access to all the fields inside the currently selected elements.
/// e.g. used to decided if and which line thickness is shown when multiple elements are selected.
///
- public FieldAggregator FieldAggregator
+ public IFieldAggregator FieldAggregator
{
get => _fieldAggregator;
set => _fieldAggregator = value;
diff --git a/src/Greenshot.Editor/Drawing/SvgContainer.cs b/src/Greenshot.Editor/Drawing/SvgContainer.cs
new file mode 100644
index 000000000..d1a3d1e20
--- /dev/null
+++ b/src/Greenshot.Editor/Drawing/SvgContainer.cs
@@ -0,0 +1,57 @@
+/*
+ * 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.Imaging;
+using Greenshot.Base.Core;
+using Greenshot.Base.Interfaces;
+using Svg;
+
+namespace Greenshot.Editor.Drawing
+{
+ ///
+ /// This provides a resizable SVG container, redrawing the SVG in the size the container takes.
+ ///
+ [Serializable]
+ public class SvgContainer : VectorGraphicsContainer
+ {
+ private SvgDocument _svgDocument;
+
+ public SvgContainer(SvgDocument svgDocument, ISurface parent) : base(parent)
+ {
+ _svgDocument = svgDocument;
+ Size = new Size((int)svgDocument.Width, (int)svgDocument.Height);
+ }
+
+ protected override Image ComputeBitmap()
+ {
+ var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppRgb, Color.Transparent);
+
+ _svgDocument.Draw(image);
+ if (RotationAngle == 0) return image;
+
+ var newImage = image.Rotate(RotationAngle);
+ image.Dispose();
+ return newImage;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/TextContainer.cs b/src/Greenshot.Editor/Drawing/TextContainer.cs
index 4d670b4e0..fdb718cbe 100644
--- a/src/Greenshot.Editor/Drawing/TextContainer.cs
+++ b/src/Greenshot.Editor/Drawing/TextContainer.cs
@@ -28,6 +28,7 @@ using System.Drawing.Text;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Base.Core;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers;
@@ -83,7 +84,7 @@ namespace Greenshot.Editor.Drawing
OnPropertyChanged("Text");
}
- public TextContainer(Surface parent) : base(parent)
+ public TextContainer(ISurface parent) : base(parent)
{
Init();
}
@@ -154,17 +155,17 @@ namespace Greenshot.Editor.Drawing
FieldChanged += TextContainer_FieldChanged;
}
- protected override void SwitchParent(Surface newParent)
+ protected override void SwitchParent(ISurface newParent)
{
- if (_parent != null)
+ if (InternalParent != null)
{
- _parent.SizeChanged -= Parent_SizeChanged;
+ InternalParent.SizeChanged -= Parent_SizeChanged;
}
base.SwitchParent(newParent);
- if (_parent != null)
+ if (InternalParent != null)
{
- _parent.SizeChanged += Parent_SizeChanged;
+ InternalParent.SizeChanged += Parent_SizeChanged;
}
}
@@ -221,10 +222,10 @@ namespace Greenshot.Editor.Drawing
{
ShowTextBox();
}
- else if (_parent != null && Selected && Status == EditStatus.IDLE && _textBox.Visible)
+ else if (InternalParent != null && Selected && Status == EditStatus.IDLE && _textBox.Visible)
{
// Fix (workaround) for BUG-1698
- _parent.KeysLocked = true;
+ InternalParent.KeysLocked = true;
}
}
@@ -295,10 +296,10 @@ namespace Greenshot.Editor.Drawing
private void ShowTextBox()
{
- if (_parent != null)
+ if (InternalParent != null)
{
- _parent.KeysLocked = true;
- _parent.Controls.Add(_textBox);
+ InternalParent.KeysLocked = true;
+ InternalParent.Controls.Add(_textBox);
}
EnsureTextBoxContrast();
@@ -332,15 +333,15 @@ namespace Greenshot.Editor.Drawing
private void HideTextBox()
{
- _parent?.Focus();
+ InternalParent?.Focus();
_textBox?.Hide();
- if (_parent == null)
+ if (InternalParent == null)
{
return;
}
- _parent.KeysLocked = false;
- _parent.Controls.Remove(_textBox);
+ InternalParent.KeysLocked = false;
+ InternalParent.Controls.Remove(_textBox);
}
///
diff --git a/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
new file mode 100644
index 000000000..2ad97e093
--- /dev/null
+++ b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
@@ -0,0 +1,126 @@
+/*
+ * 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.Drawing.Imaging;
+using System.Runtime.Serialization;
+using Greenshot.Base.Core;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+
+namespace Greenshot.Editor.Drawing
+{
+ ///
+ /// This is the base container for vector graphics, these ae graphics which can resize without loss of quality.
+ /// Examples for this are SVG, WMF or EMF, but also graphics based on fonts (e.g. Emoji)
+ ///
+ [Serializable]
+ public abstract class VectorGraphicsContainer : DrawableContainer
+ {
+ protected int RotationAngle;
+
+ ///
+ /// This is the cached version of the bitmap, pre-rendered to save performance
+ /// Do not serialized, it can be rebuild with some other information.
+ ///
+ [NonSerialized] private Image _cachedImage;
+
+ public VectorGraphicsContainer(ISurface parent) : base(parent)
+ {
+ Init();
+ }
+
+ protected override void OnDeserialized(StreamingContext streamingContext)
+ {
+ base.OnDeserialized(streamingContext);
+ Init();
+ }
+
+ private void Init()
+ {
+ CreateDefaultAdorners();
+ }
+
+ ///
+ /// The bulk of the clean-up code is implemented in Dispose(bool)
+ /// This Dispose is called from the Dispose and the Destructor.
+ /// When disposing==true all non-managed resources should be freed too!
+ ///
+ ///
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ ResetCachedBitmap();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ public override void Transform(Matrix matrix)
+ {
+ RotationAngle += CalculateAngle(matrix);
+ RotationAngle %= 360;
+
+ ResetCachedBitmap();
+
+ 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;
+
+ if (_cachedImage != null && _cachedImage.Size != Bounds.Size)
+ {
+ ResetCachedBitmap();
+ }
+
+ _cachedImage ??= ComputeBitmap();
+
+ graphics.DrawImage(_cachedImage, Bounds);
+ }
+
+ protected virtual Image ComputeBitmap()
+ {
+ var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppRgb, Color.Transparent);
+
+ if (RotationAngle == 0) return image;
+
+ var newImage = image.Rotate(RotationAngle);
+ image.Dispose();
+ return newImage;
+
+ }
+
+ private void ResetCachedBitmap()
+ {
+ _cachedImage?.Dispose();
+ _cachedImage = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs
new file mode 100644
index 000000000..95a683240
--- /dev/null
+++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs
@@ -0,0 +1,86 @@
+/*
+ * 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.Imaging;
+using System.IO;
+using System.Linq;
+using Greenshot.Base.Core;
+using Greenshot.Base.Interfaces;
+using Greenshot.Base.Interfaces.Drawing;
+using Greenshot.Editor.Drawing;
+using log4net;
+using Svg;
+
+namespace Greenshot.Editor.FileFormatHandlers
+{
+ ///
+ /// This handled the loading of SVG images to the editor
+ ///
+ public class SvgFileFormatHandler : IFileFormatHandler
+ {
+ private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper));
+
+ private static readonly string[] SupportedExtensions = { "svg" };
+
+ public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension)
+ {
+ if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
+ {
+ return false;
+ }
+ return SupportedExtensions.Contains(extension);
+ }
+
+ public void SaveToStream(Bitmap bitmap, Stream destination, string extension)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Bitmap Load(Stream stream, string extension)
+ {
+
+ var svgDocument = SvgDocument.Open(stream);
+ int width = (int)svgDocument.ViewBox.Width;
+ int height = (int)svgDocument.ViewBox.Height;
+
+ try
+ {
+ var result = ImageHelper.CreateEmpty(width, height, PixelFormat.Format32bppArgb, Color.Transparent);
+ svgDocument.Draw(result);
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Can't load SVG", ex);
+ }
+
+ return null;
+ }
+
+ public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent)
+ {
+ var svgDocument = SvgDocument.Open(stream);
+ return new SvgContainer(svgDocument, parent);
+ }
+ }
+}
diff --git a/src/Greenshot.Editor/Forms/ImageEditorForm.cs b/src/Greenshot.Editor/Forms/ImageEditorForm.cs
index 3e1be9489..1b83dee9c 100644
--- a/src/Greenshot.Editor/Forms/ImageEditorForm.cs
+++ b/src/Greenshot.Editor/Forms/ImageEditorForm.cs
@@ -56,13 +56,13 @@ namespace Greenshot.Editor.Forms
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageEditorForm));
private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection();
- private static readonly List IgnoreDestinations = new List
+ private static readonly List IgnoreDestinations = new()
{
nameof(WellKnownDestinations.Picker),
EditorDestination.DESIGNATION
};
- private static readonly List EditorList = new List();
+ private static readonly List EditorList = new();
private Surface _surface;
private GreenshotToolStripButton[] _toolbarButtons;
@@ -78,7 +78,7 @@ namespace Greenshot.Editor.Forms
// whether part of the editor controls are disabled depending on selected item(s)
private bool _controlsDisabledDueToConfirmable;
- // Used for tracking the mouse scrollwheel changes
+ // Used for tracking the mouse scroll wheel changes
private DateTime _zoomStartTime = DateTime.Now;
///
@@ -1290,7 +1290,7 @@ namespace Greenshot.Editor.Forms
propertiesToolStrip.SuspendLayout();
if (_surface.HasSelectedElements || _surface.DrawingMode != DrawingModes.None)
{
- FieldAggregator props = _surface.FieldAggregator;
+ var props = (FieldAggregator)_surface.FieldAggregator;
btnFillColor.Visible = props.HasFieldValue(FieldType.FILL_COLOR);
btnLineColor.Visible = props.HasFieldValue(FieldType.LINE_COLOR);
lineThicknessLabel.Visible = lineThicknessUpDown.Visible = props.HasFieldValue(FieldType.LINE_THICKNESS);
@@ -1350,7 +1350,7 @@ namespace Greenshot.Editor.Forms
btnStepLabel.Image = icon;
addCounterToolStripMenuItem.Image = icon;
- FieldAggregator props = _surface.FieldAggregator;
+ FieldAggregator props = (FieldAggregator)_surface.FieldAggregator;
// if a confirmable element is selected, we must disable most of the controls
// since we demand confirmation or cancel for confirmable element
if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag) props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE)
diff --git a/src/Greenshot.Editor/Memento/AddElementMemento.cs b/src/Greenshot.Editor/Memento/AddElementMemento.cs
index dbee523a6..1a95d19ce 100644
--- a/src/Greenshot.Editor/Memento/AddElementMemento.cs
+++ b/src/Greenshot.Editor/Memento/AddElementMemento.cs
@@ -20,9 +20,8 @@
*/
using System;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-using Greenshot.Editor.Drawing;
-
namespace Greenshot.Editor.Memento
{
///
@@ -31,9 +30,9 @@ namespace Greenshot.Editor.Memento
public class AddElementMemento : IMemento
{
private IDrawableContainer _drawableContainer;
- private Surface _surface;
+ private ISurface _surface;
- public AddElementMemento(Surface surface, IDrawableContainer drawableContainer)
+ public AddElementMemento(ISurface surface, IDrawableContainer drawableContainer)
{
_surface = surface;
_drawableContainer = drawableContainer;
diff --git a/src/Greenshot.Editor/Memento/AddElementsMemento.cs b/src/Greenshot.Editor/Memento/AddElementsMemento.cs
index 80c9d3d99..8649dec9b 100644
--- a/src/Greenshot.Editor/Memento/AddElementsMemento.cs
+++ b/src/Greenshot.Editor/Memento/AddElementsMemento.cs
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-using Greenshot.Editor.Drawing;
namespace Greenshot.Editor.Memento
{
@@ -30,9 +30,9 @@ namespace Greenshot.Editor.Memento
public class AddElementsMemento : IMemento
{
private IDrawableContainerList _containerList;
- private Surface _surface;
+ private ISurface _surface;
- public AddElementsMemento(Surface surface, IDrawableContainerList containerList)
+ public AddElementsMemento(ISurface surface, IDrawableContainerList containerList)
{
_surface = surface;
_containerList = containerList;
diff --git a/src/Greenshot.Editor/Memento/DeleteElementMemento.cs b/src/Greenshot.Editor/Memento/DeleteElementMemento.cs
index ade27b23a..0acc19f83 100644
--- a/src/Greenshot.Editor/Memento/DeleteElementMemento.cs
+++ b/src/Greenshot.Editor/Memento/DeleteElementMemento.cs
@@ -20,8 +20,8 @@
*/
using System;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-using Greenshot.Editor.Drawing;
namespace Greenshot.Editor.Memento
{
@@ -31,9 +31,9 @@ namespace Greenshot.Editor.Memento
public class DeleteElementMemento : IMemento
{
private IDrawableContainer _drawableContainer;
- private readonly Surface _surface;
+ private readonly ISurface _surface;
- public DeleteElementMemento(Surface surface, IDrawableContainer drawableContainer)
+ public DeleteElementMemento(ISurface surface, IDrawableContainer drawableContainer)
{
_surface = surface;
_drawableContainer = drawableContainer;
diff --git a/src/Greenshot.Editor/Memento/DeleteElementsMemento.cs b/src/Greenshot.Editor/Memento/DeleteElementsMemento.cs
index d4d4a3be1..e4b0b747e 100644
--- a/src/Greenshot.Editor/Memento/DeleteElementsMemento.cs
+++ b/src/Greenshot.Editor/Memento/DeleteElementsMemento.cs
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-using Greenshot.Editor.Drawing;
namespace Greenshot.Editor.Memento
{
@@ -30,9 +30,9 @@ namespace Greenshot.Editor.Memento
public class DeleteElementsMemento : IMemento
{
private IDrawableContainerList _containerList;
- private Surface _surface;
+ private ISurface _surface;
- public DeleteElementsMemento(Surface surface, IDrawableContainerList containerList)
+ public DeleteElementsMemento(ISurface surface, IDrawableContainerList containerList)
{
_surface = surface;
_containerList = containerList;
diff --git a/src/Greenshot.Editor/Memento/SurfaceBackgroundChangeMemento.cs b/src/Greenshot.Editor/Memento/SurfaceBackgroundChangeMemento.cs
index 71d2e9f36..c6ba814c3 100644
--- a/src/Greenshot.Editor/Memento/SurfaceBackgroundChangeMemento.cs
+++ b/src/Greenshot.Editor/Memento/SurfaceBackgroundChangeMemento.cs
@@ -21,8 +21,8 @@
using System.Drawing;
using System.Drawing.Drawing2D;
+using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
-using Greenshot.Editor.Drawing;
namespace Greenshot.Editor.Memento
{
@@ -32,10 +32,10 @@ namespace Greenshot.Editor.Memento
public class SurfaceBackgroundChangeMemento : IMemento
{
private Image _image;
- private Surface _surface;
+ private ISurface _surface;
private Matrix _matrix;
- public SurfaceBackgroundChangeMemento(Surface surface, Matrix matrix)
+ public SurfaceBackgroundChangeMemento(ISurface surface, Matrix matrix)
{
_surface = surface;
_image = surface.Image;