mirror of
https://github.com/greenshot/greenshot
synced 2025-08-21 22:13:23 -07:00
This feature will make it easier to support different file formats later on, and also adds a "VectorGraphicsContainer" base class to better support non pixel graphics in the editor. Examples are SVG, WMF/EMF and Emoji which scale automatically to the correct size and are not resized from pixels.
This commit is contained in:
parent
fdbaca6c3f
commit
7e77f3678a
39 changed files with 934 additions and 368 deletions
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// THis is the default .NET bitmap file format handler
|
||||
/// </summary>
|
||||
public class DefaultFileFormatHandler : IFileFormatHandler
|
||||
{
|
||||
private static readonly string [] OurExtensions = { "png", "bmp", "gif", "jpg", "jpeg", "tiff", "tif" };
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
|
||||
{
|
||||
if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
|
||||
{
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
return OurExtensions;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
|
||||
{
|
||||
if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OurExtensions.Contains(extension);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Func<ISurface>>().Invoke();
|
||||
return (Bitmap)surface.GetImageForExport();
|
||||
}
|
||||
|
||||
public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// THis is the default .NET bitmap file format handler
|
||||
/// </summary>
|
||||
public class IconFileFormatHandler : IFileFormatHandler
|
||||
{
|
||||
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper));
|
||||
|
||||
private static readonly string[] OurExtensions = { "ico" };
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
|
||||
{
|
||||
if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
|
||||
{
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
return OurExtensions;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
|
||||
{
|
||||
if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OurExtensions.Contains(extension);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Based on: https://www.codeproject.com/KB/cs/IconExtractor.aspx
|
||||
/// And a hint from: https://www.codeproject.com/KB/cs/IconLib.aspx
|
||||
/// </summary>
|
||||
/// <param name="iconStream">Stream with the icon information</param>
|
||||
/// <returns>Bitmap with the Vista Icon (256x256)</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ namespace Greenshot.Base.Core
|
|||
float HorizontalResolution { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
Image Image { get; }
|
||||
}
|
||||
|
|
|
@ -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<CoreConfiguration>();
|
||||
private const int ExifOrientationId = 0x0112;
|
||||
|
||||
public static readonly IList<IFileFormatHandler> FileFormatHandlers = new List<IFileFormatHandler>();
|
||||
|
||||
static ImageHelper()
|
||||
{
|
||||
StreamConverters["greenshot"] = (stream, s) =>
|
||||
{
|
||||
var surface = SimpleServiceProvider.Current.GetInstance<Func<ISurface>>().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<string, Func<Stream, string, Image>> StreamConverters { get; } = new Dictionary<string, Func<Stream, string, Image>>();
|
||||
|
||||
/// <summary>
|
||||
/// Make sure the image is orientated correctly
|
||||
/// </summary>
|
||||
|
@ -563,8 +495,7 @@ namespace Greenshot.Base.Core
|
|||
/// <returns>Changed bitmap</returns>
|
||||
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
|
|||
/// <param name="height"></param>
|
||||
/// <param name="format"></param>
|
||||
/// <param name="backgroundColor">The color to fill with, or Color.Empty to take the default depending on the pixel format</param>
|
||||
/// <param name="horizontalResolution"></param>
|
||||
/// <param name="verticalResolution"></param>
|
||||
/// <param name="horizontalResolution">float</param>
|
||||
/// <param name="verticalResolution">float</param>
|
||||
/// <returns>Bitmap</returns>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Rotate the image
|
||||
/// </summary>
|
||||
/// <param name="image">Input image</param>
|
||||
/// <param name="rotationAngle">Angle in degrees</param>
|
||||
/// <returns>Rotated image</returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace Greenshot.Base.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrap an image, make it resizeable
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Height of the image, can be set to change
|
||||
/// </summary>
|
||||
public int Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Width of the image, can be set to change.
|
||||
/// </summary>
|
||||
public int Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the image
|
||||
/// </summary>
|
||||
public Size Size => new Size(Width, Height);
|
||||
|
||||
/// <summary>
|
||||
/// Pixelformat of the underlying image
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using Svg;
|
||||
|
||||
namespace Greenshot.Base.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an image look like of the SVG
|
||||
/// </summary>
|
||||
public sealed class SvgImage : IImage
|
||||
{
|
||||
private readonly SvgDocument _svgDocument;
|
||||
|
||||
private Image _imageClone;
|
||||
|
||||
/// <summary>
|
||||
/// Factory to create via a stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream</param>
|
||||
/// <returns>IImage</returns>
|
||||
public static IImage FromStream(Stream stream)
|
||||
{
|
||||
return new SvgImage(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
public SvgImage(Stream stream)
|
||||
{
|
||||
_svgDocument = SvgDocument.Open<SvgDocument>(stream);
|
||||
Height = (int) _svgDocument.ViewBox.Height;
|
||||
Width = (int) _svgDocument.ViewBox.Width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Height of the image, can be set to change
|
||||
/// </summary>
|
||||
public int Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Width of the image, can be set to change.
|
||||
/// </summary>
|
||||
public int Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the image
|
||||
/// </summary>
|
||||
public Size Size => new Size(Width, Height);
|
||||
|
||||
/// <summary>
|
||||
/// Pixelformat of the underlying image
|
||||
/// </summary>
|
||||
public PixelFormat PixelFormat => Image.PixelFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Horizontal resolution of the underlying image
|
||||
/// </summary>
|
||||
public float HorizontalResolution => Image.HorizontalResolution;
|
||||
|
||||
/// <summary>
|
||||
/// Vertical resolution of the underlying image
|
||||
/// </summary>
|
||||
public float VerticalResolution => Image.VerticalResolution;
|
||||
|
||||
/// <summary>
|
||||
/// Underlying image, or an on demand rendered version with different attributes as the original
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_imageClone?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -135,7 +135,7 @@ namespace Greenshot.Base.Interfaces.Drawing
|
|||
|
||||
public interface IImageContainer : IDrawableContainer
|
||||
{
|
||||
Image Image { get; set; }
|
||||
Image Image { get; }
|
||||
void Load(string filename);
|
||||
}
|
||||
|
||||
|
|
33
src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
Normal file
33
src/Greenshot.Base/Interfaces/Drawing/IFieldAggregator.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
96
src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
Normal file
96
src/Greenshot.Base/Interfaces/IFileFormatHandler.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Greenshot.Base.Interfaces.Drawing;
|
||||
|
||||
namespace Greenshot.Base.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible actions a IFileFormatHandler might support
|
||||
/// </summary>
|
||||
public enum FileFormatHandlerActions
|
||||
{
|
||||
SaveToStream,
|
||||
Load,
|
||||
LoadDrawableFromStream
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This interface is for code to implement the loading and saving of certain file formats
|
||||
/// </summary>
|
||||
public interface IFileFormatHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Delivers the extension that the supplied action supports
|
||||
/// </summary>
|
||||
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
|
||||
/// <returns>IEnumerable{string}</returns>
|
||||
IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction);
|
||||
|
||||
/// <summary>
|
||||
///Does this IFileFormatHandler support the specified action for the specified extension?
|
||||
/// </summary>
|
||||
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
|
||||
/// <param name="extension">string</param>
|
||||
/// <returns>bool true if this IFileFormatHandler can support the action for the extension</returns>
|
||||
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension);
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
|
||||
/// <param name="extension">string</param>
|
||||
/// <returns>int specifying the priority for the action and extension</returns>
|
||||
public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension);
|
||||
|
||||
/// <summary>
|
||||
/// Try to save the specified bitmap to the stream in the format belonging to the extension
|
||||
/// </summary>
|
||||
/// <param name="bitmap">Bitmap</param>
|
||||
/// <param name="destination">Stream</param>
|
||||
/// <param name="extension">extension</param>
|
||||
/// <returns>bool true if it was successful</returns>
|
||||
public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="extension"></param>
|
||||
/// <param name="bitmap"></param>
|
||||
/// <returns>bool true if it was successful</returns>
|
||||
public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap);
|
||||
|
||||
/// <summary>
|
||||
/// Try to load a drawable container from the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream</param>
|
||||
/// <param name="extension">string</param>
|
||||
/// <param name="drawableContainer">IDrawableContainer out</param>
|
||||
/// <param name="parent">ISurface</param>
|
||||
/// <returns>bool true if it was successful</returns>
|
||||
public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent);
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// This reverses a change of the background image
|
||||
/// </summary>
|
||||
/// <param name="previous">Image</param>
|
||||
/// <param name="matrix">Matrix</param>
|
||||
void UndoBackgroundChange(Image previous, Matrix matrix);
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|||
/// </summary>
|
||||
public class CropContainer : DrawableContainer
|
||||
{
|
||||
public CropContainer(Surface parent) : base(parent)
|
||||
public CropContainer(ISurface parent) : base(parent)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
/// </summary>
|
||||
[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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
|||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public FreehandContainer(Surface parent) : base(parent)
|
||||
public FreehandContainer(ISurface parent) : base(parent)
|
||||
{
|
||||
Width = parent.Image.Width;
|
||||
Height = parent.Image.Height;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
|||
/// </summary>
|
||||
[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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of ObfuscateContainer.
|
||||
/// This is a FilterContainer for the obfuscator filters like blur and pixelate.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ObfuscateContainer : FilterContainer
|
||||
{
|
||||
public ObfuscateContainer(Surface parent) : base(parent)
|
||||
public ObfuscateContainer(ISurface parent) : base(parent)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -97,23 +97,23 @@ namespace Greenshot.Editor.Drawing
|
|||
/// Add the StepLabel to the parent
|
||||
/// </summary>
|
||||
/// <param name="newParent"></param>
|
||||
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);
|
||||
|
|
|
@ -294,7 +294,7 @@ namespace Greenshot.Editor.Drawing
|
|||
/// <summary>
|
||||
/// all elements on the surface, needed with serialization
|
||||
/// </summary>
|
||||
private FieldAggregator _fieldAggregator;
|
||||
private IFieldAggregator _fieldAggregator;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public FieldAggregator FieldAggregator
|
||||
public IFieldAggregator FieldAggregator
|
||||
{
|
||||
get => _fieldAggregator;
|
||||
set => _fieldAggregator = value;
|
||||
|
|
57
src/Greenshot.Editor/Drawing/SvgContainer.cs
Normal file
57
src/Greenshot.Editor/Drawing/SvgContainer.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using Greenshot.Base.Core;
|
||||
using Greenshot.Base.Interfaces;
|
||||
using Svg;
|
||||
|
||||
namespace Greenshot.Editor.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// This provides a resizable SVG container, redrawing the SVG in the size the container takes.
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
126
src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
Normal file
126
src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class VectorGraphicsContainer : DrawableContainer
|
||||
{
|
||||
protected int RotationAngle;
|
||||
|
||||
/// <summary>
|
||||
/// This is the cached version of the bitmap, pre-rendered to save performance
|
||||
/// Do not serialized, it can be rebuild with some other information.
|
||||
/// </summary>
|
||||
[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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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!
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// This handled the loading of SVG images to the editor
|
||||
/// </summary>
|
||||
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<SvgDocument>(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<SvgDocument>(stream);
|
||||
return new SvgContainer(svgDocument, parent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,13 +56,13 @@ namespace Greenshot.Editor.Forms
|
|||
private static readonly ILog Log = LogManager.GetLogger(typeof(ImageEditorForm));
|
||||
private static readonly EditorConfiguration EditorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
|
||||
|
||||
private static readonly List<string> IgnoreDestinations = new List<string>
|
||||
private static readonly List<string> IgnoreDestinations = new()
|
||||
{
|
||||
nameof(WellKnownDestinations.Picker),
|
||||
EditorDestination.DESIGNATION
|
||||
};
|
||||
|
||||
private static readonly List<IImageEditor> EditorList = new List<IImageEditor>();
|
||||
private static readonly List<IImageEditor> 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;
|
||||
|
||||
/// <summary>
|
||||
|
@ -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)
|
||||
|
|
|
@ -20,9 +20,8 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using Greenshot.Base.Interfaces;
|
||||
using Greenshot.Base.Interfaces.Drawing;
|
||||
using Greenshot.Editor.Drawing;
|
||||
|
||||
namespace Greenshot.Editor.Memento
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -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;
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue