diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs index d37e4634f..0ab70e5b2 100644 --- a/src/Greenshot.Base/Core/ClipboardHelper.cs +++ b/src/Greenshot.Base/Core/ClipboardHelper.cs @@ -34,6 +34,7 @@ using Greenshot.Base.Core.Enums; using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.UnmanagedHelpers; using log4net; @@ -300,13 +301,14 @@ EndSelection:<<<<<<<4 return true; } + var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); foreach (var fileData in IterateClipboardContent(dataObject)) { try { - using (ImageHelper.FromStream(fileData)) + var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant(); + if (supportedExtensions.Contains(extension)) { - // If we get here, there is an image return true; } } @@ -316,7 +318,7 @@ EndSelection:<<<<<<<4 } finally { - fileData?.Dispose(); + fileData.stream?.Dispose(); } } @@ -328,6 +330,7 @@ EndSelection:<<<<<<<4 var imageStream = clipboardContent as MemoryStream; if (IsValidStream(imageStream)) { + // TODO: How to check if we support "just a stream"? using (ImageHelper.FromStream(imageStream)) { // If we get here, there is an image @@ -374,8 +377,8 @@ EndSelection:<<<<<<<4 /// Iterate the clipboard content /// /// IDataObject - /// IEnumerable{MemoryStream} - private static IEnumerable IterateClipboardContent(IDataObject dataObject) + /// IEnumerable{(MemoryStream,string)} + private static IEnumerable<(MemoryStream stream,string filename)> IterateClipboardContent(IDataObject dataObject) { var fileDescriptors = AvailableFileDescriptors(dataObject); if (fileDescriptors == null) yield break; @@ -414,8 +417,8 @@ EndSelection:<<<<<<<4 /// /// IEnumerable{FileDescriptor} /// IDataObject - /// IEnumerable{MemoryStream} - private static IEnumerable IterateFileDescriptors(IEnumerable fileDescriptors, IDataObject dataObject) + /// IEnumerable{(MemoryStream stream, string filename)} + private static IEnumerable<(MemoryStream stream, string filename)> IterateFileDescriptors(IEnumerable fileDescriptors, IDataObject dataObject) { if (fileDescriptors == null) { @@ -446,7 +449,7 @@ EndSelection:<<<<<<<4 if (fileData?.Length > 0) { fileData.Position = 0; - yield return fileData; + yield return (fileData, fileDescriptor.FileName); } fileIndex++; @@ -505,56 +508,75 @@ EndSelection:<<<<<<<4 /// /// /// IEnumerable of Image - public static IEnumerable GetImages(IDataObject dataObject) + public static IEnumerable GetImages(IDataObject dataObject) { // Get single image, this takes the "best" match - Image singleImage = GetImage(dataObject); + IDrawableContainer singleImage = GetImage(dataObject); if (singleImage != null) { - Log.InfoFormat("Got image from clipboard with size {0} and format {1}", singleImage.Size, singleImage.PixelFormat); + Log.InfoFormat($"Got {singleImage.GetType()} from clipboard with size {singleImage.Size}"); yield return singleImage; + yield break; } - else + + var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); + + foreach (var fileData in IterateClipboardContent(dataObject)) { - foreach (var fileData in IterateClipboardContent(dataObject)) + var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant(); + if (!supportedExtensions.Contains(extension)) { - Image image; - try + continue; + } + + IDrawableContainer drawableContainer = null; + + try + { + if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileData.stream, extension, out drawableContainer)) { - image = ImageHelper.FromStream(fileData); - } - catch (Exception ex) - { - Log.Error("Couldn't read file contents", ex); continue; } - finally - { - fileData?.Dispose(); - } - // If we get here, there is an image - yield return image; - } - // check if files are supplied - foreach (string imageFile in GetImageFilenames(dataObject)) + } + catch (Exception ex) { - Image returnImage = null; - try - { - returnImage = ImageHelper.LoadImage(imageFile); - } - catch (Exception streamImageEx) - { - Log.Error("Problem retrieving Image from clipboard.", streamImageEx); - } + Log.Error("Couldn't read file contents", ex); + continue; + } + finally + { + fileData.stream?.Dispose(); + } + // If we get here, there is an image + yield return drawableContainer; + } - if (returnImage != null) + // check if files are supplied + foreach (string imageFile in GetImageFilenames(dataObject)) + { + var extension = Path.GetExtension(imageFile)?.ToLowerInvariant(); + if (!supportedExtensions.Contains(extension)) + { + continue; + } + + IDrawableContainer drawableContainer = null; + using FileStream fileStream = new FileStream(imageFile, FileMode.Open, FileAccess.Read, FileShare.Read); + try + { + if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(fileStream, extension, out drawableContainer)) { - Log.InfoFormat("Got image from clipboard with size {0} and format {1}", returnImage.Size, returnImage.PixelFormat); - yield return returnImage; + continue; } } + catch (Exception ex) + { + Log.Error("Couldn't read file contents", ex); + continue; + } + // If we get here, there is an image + yield return drawableContainer; } } @@ -563,51 +585,50 @@ EndSelection:<<<<<<<4 /// /// /// Image or null - private static Image GetImage(IDataObject dataObject) + private static IDrawableContainer GetImage(IDataObject dataObject) { - Image returnImage = null; - if (dataObject != null) - { - IList formats = GetFormats(dataObject); - string[] retrieveFormats; + if (dataObject == null) return null; - // Found a weird bug, where PNG's from Outlook 2010 are clipped - // So I build some special logic to get the best format: - if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib)) + IDrawableContainer returnImage = null; + IList formats = GetFormats(dataObject); + string[] retrieveFormats; + + // Found a weird bug, where PNG's from Outlook 2010 are clipped + // So I build some special logic to get the best format: + if (formats != null && formats.Contains(FORMAT_PNG_OFFICEART) && formats.Contains(DataFormats.Dib)) + { + // Outlook ?? + Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front..."); + retrieveFormats = new[] { - // Outlook ?? - Log.Info("Most likely the current clipboard contents come from Outlook, as this has a problem with PNG and others we place the DIB format to the front..."); - retrieveFormats = new[] - { - DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, - DataFormats.Tiff, FORMAT_GIF, FORMAT_HTML - }; + DataFormats.Dib, FORMAT_BITMAP, FORMAT_FILECONTENTS, FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, + DataFormats.Tiff, FORMAT_GIF, FORMAT_HTML + }; + } + else + { + retrieveFormats = new[] + { + FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, + FORMAT_FILECONTENTS, FORMAT_GIF, FORMAT_HTML + }; + } + + foreach (string currentFormat in retrieveFormats) + { + if (formats != null && formats.Contains(currentFormat)) + { + Log.InfoFormat("Found {0}, trying to retrieve.", currentFormat); + returnImage = GetImageForFormat(currentFormat, dataObject); } else { - retrieveFormats = new[] - { - FORMAT_PNG_OFFICEART, FORMAT_PNG, FORMAT_17, FORMAT_JFIF_OFFICEART, FORMAT_JPG, FORMAT_JPEG, FORMAT_JFIF, DataFormats.Tiff, DataFormats.Dib, FORMAT_BITMAP, - FORMAT_FILECONTENTS, FORMAT_GIF, FORMAT_HTML - }; + Log.DebugFormat("Couldn't find format {0}.", currentFormat); } - foreach (string currentFormat in retrieveFormats) + if (returnImage != null) { - if (formats != null && formats.Contains(currentFormat)) - { - Log.InfoFormat("Found {0}, trying to retrieve.", currentFormat); - returnImage = GetImageForFormat(currentFormat, dataObject); - } - else - { - Log.DebugFormat("Couldn't find format {0}.", currentFormat); - } - - if (returnImage != null) - { - return returnImage; - } + return returnImage; } } @@ -615,15 +636,17 @@ EndSelection:<<<<<<<4 } /// - /// Helper method to try to get an image in the specified format from the dataObject + /// Helper method to try to get an IDrawableContainer in the specified format from the dataObject /// the DIB reader should solve some issues /// It also supports Format17/DibV5, by using the following information: https://stackoverflow.com/a/14335591 /// /// string with the format /// IDataObject - /// Image or null - private static Image GetImageForFormat(string format, IDataObject dataObject) + /// IDrawableContainer or null + private static IDrawableContainer GetImageForFormat(string format, IDataObject dataObject) { + IDrawableContainer drawableContainer = null; + if (format == FORMAT_HTML) { var textObject = ContentAsString(dataObject, FORMAT_HTML, Encoding.UTF8); @@ -639,10 +662,10 @@ EndSelection:<<<<<<<4 var srcAttribute = imgNode.Attributes["src"]; var imageUrl = srcAttribute.Value; Log.Debug(imageUrl); - var image = NetworkHelper.DownloadImage(imageUrl); - if (image != null) + drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(imageUrl); + if (drawableContainer != null) { - return image; + return drawableContainer; } } } @@ -653,110 +676,29 @@ EndSelection:<<<<<<<4 var imageStream = clipboardObject as MemoryStream; if (!IsValidStream(imageStream)) { - // TODO: add "HTML Format" support here... + // TODO: add text based, like "HTML Format" support here... + // TODO: solve the issue that we do not have a factory for the ImageContainer + /*var image = clipboardObject as Image; + if (image != null) + { + return new ImageContainer(this) + { + Image = image, + Left = x, + Top = y + }; + } return clipboardObject as Image; +*/ + return null; } - if (CoreConfig.EnableSpecialDIBClipboardReader) + // From here, imageStream is a valid stream + + if (!FileFormatHandlerRegistry.TryLoadDrawableFromStream(imageStream, format, out drawableContainer)) { - if (format == FORMAT_17 || format == DataFormats.Dib) - { - Log.Info("Found DIB stream, trying to process it."); - try - { - if (imageStream != null) - { - byte[] dibBuffer = new byte[imageStream.Length]; - _ = imageStream.Read(dibBuffer, 0, dibBuffer.Length); - var infoHeader = BinaryStructHelper.FromByteArray(dibBuffer); - if (!infoHeader.IsDibV5) - { - Log.InfoFormat("Using special DIB GetImageFilenames(IDataObject dataObject) { string[] dropFileNames = (string[])dataObject.GetData(DataFormats.FileDrop); - if (dropFileNames != null && dropFileNames.Length > 0) - { - var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); - return dropFileNames - .Where(filename => !string.IsNullOrEmpty(filename)) - .Where(Path.HasExtension) - .Where(filename => supportedExtensions.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1))); - } + if (dropFileNames is not { Length: > 0 }) return Enumerable.Empty(); + + var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); + return dropFileNames + .Where(filename => !string.IsNullOrEmpty(filename)) + .Where(Path.HasExtension) + .Where(filename => supportedExtensions.Contains(Path.GetExtension(filename))); - return Enumerable.Empty(); } /// diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs new file mode 100644 index 000000000..c8d842b45 --- /dev/null +++ b/src/Greenshot.Base/Core/FileFormatHandlers/AbstractFileFormatHandler.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; + +namespace Greenshot.Base.Core.FileFormatHandlers +{ + public abstract class AbstractFileFormatHandler + { + /// + /// Make sure we handle the input extension always the same, by "normalizing" it + /// + /// string + /// string + protected string NormalizeExtension(string extension) + { + if (string.IsNullOrEmpty(extension)) + { + return null; + } + + extension = extension.ToLowerInvariant(); + return !extension.StartsWith(".") ? $".{extension}" : extension; + } + } +} diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs index 93db7f5d2..0dded0b55 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs @@ -24,6 +24,7 @@ using System.Drawing; using System.IO; using System.Linq; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; namespace Greenshot.Base.Core.FileFormatHandlers { @@ -31,13 +32,6 @@ namespace Greenshot.Base.Core.FileFormatHandlers { public static IList FileFormatHandlers { get; } = new List(); - static FileFormatHandlerRegistry() - { - FileFormatHandlers.Add(new IconFileFormatHandler()); - FileFormatHandlers.Add(new GreenshotFileFormatHandler()); - FileFormatHandlers.Add(new DefaultFileFormatHandler()); - } - public static IEnumerable ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction) { return FileFormatHandlers.SelectMany(ffh => ffh.SupportedExtensions(fileFormatHandlerAction)).Distinct(); @@ -66,5 +60,29 @@ namespace Greenshot.Base.Core.FileFormatHandlers return fileFormatHandler.TrySaveToStream(bitmap, destination, extension); } + + /// + /// Try to load a drawable container from the stream + /// + /// Stream + /// string + /// IDrawableContainer out + /// ISurface + /// bool true if it was successful + public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) + { + var fileFormatHandler = FileFormatHandlers + .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension)) + .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension)) + .FirstOrDefault(); + + if (fileFormatHandler == null) + { + drawableContainer = null; + return false; + } + + return fileFormatHandler.TryLoadDrawableFromStream(stream, extension, out drawableContainer, parentSurface); + } } } diff --git a/src/Greenshot.Base/Core/ImageHelper.cs b/src/Greenshot.Base/Core/ImageHelper.cs index c74e9f80c..e9745dd9b 100644 --- a/src/Greenshot.Base/Core/ImageHelper.cs +++ b/src/Greenshot.Base/Core/ImageHelper.cs @@ -1320,7 +1320,7 @@ namespace Greenshot.Base.Core } // If no pixelformat is supplied - if (PixelFormat.DontCare == targetFormat || PixelFormat.Undefined == targetFormat) + if (targetFormat is PixelFormat.DontCare or PixelFormat.Undefined) { if (SupportsPixelFormat(sourceImage.PixelFormat)) { diff --git a/src/Greenshot.Base/Core/NetworkHelper.cs b/src/Greenshot.Base/Core/NetworkHelper.cs index e9671db38..23427ce0d 100644 --- a/src/Greenshot.Base/Core/NetworkHelper.cs +++ b/src/Greenshot.Base/Core/NetworkHelper.cs @@ -31,6 +31,7 @@ using System.Text.RegularExpressions; using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Plugin; using log4net; @@ -89,25 +90,13 @@ namespace Greenshot.Base.Core } /// - /// Download the uri to Bitmap + /// Download the uri to build an IDrawableContainer /// /// Of an image - /// Bitmap - public static Image DownloadImage(string url) + /// IDrawableContainer + public static IDrawableContainer DownloadImageAsDrawableContainer(string url) { - var extensions = new StringBuilder(); - var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); - foreach (var extension in supportedExtensions) - { - if (string.IsNullOrEmpty(extension)) - { - continue; - } - - extensions.AppendFormat(@"\.{0}|", extension); - } - - extensions.Length--; + var extensions = string.Join("|", FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream)); var imageUrlRegex = new Regex($@"(http|https)://.*(?{extensions})"); var match = imageUrlRegex.Match(url); @@ -116,7 +105,10 @@ namespace Greenshot.Base.Core using var memoryStream = GetAsMemoryStream(url); try { - return ImageHelper.FromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null); + if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) + { + return drawableContainer; + } } catch (Exception) { @@ -139,7 +131,10 @@ namespace Greenshot.Base.Core } using var memoryStream2 = GetAsMemoryStream(match.Value); - return ImageHelper.FromStream(memoryStream2, match.Groups["extension"]?.Value); + if (FileFormatHandlerRegistry.TryLoadDrawableFromStream(memoryStream2, match.Success ? match.Groups["extension"]?.Value : null, out var drawableContainer)) + { + return drawableContainer; + } } } catch (Exception e) diff --git a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs index 1742b8054..24abc2d25 100644 --- a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs +++ b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs @@ -30,7 +30,14 @@ namespace Greenshot.Base.Interfaces.Drawing { public interface IDrawableContainer : INotifyPropertyChanged, IDisposable { + /// + /// The parent surface where this IDrawableContainer is on + /// ISurface Parent { get; set; } + + /// + /// Is this IDrawableContainer selected on the surface + /// bool Selected { get; set; } int Left { get; set; } @@ -54,15 +61,25 @@ namespace Greenshot.Base.Interfaces.Drawing bool HasFilters { get; } EditStatus Status { get; set; } + void Invalidate(); + bool ClickableAt(int x, int y); + void MoveBy(int x, int y); + void Transform(Matrix matrix); + bool HandleMouseDown(int x, int y); + void HandleMouseUp(int x, int y); + bool HandleMouseMove(int x, int y); + bool InitContent(); + void MakeBoundsChangeUndoable(bool allowMerge); + EditStatus DefaultEditMode { get; } /// diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs index 04442d71b..7281f0228 100644 --- a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs +++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs @@ -89,8 +89,8 @@ namespace Greenshot.Base.Interfaces /// Stream /// string /// IDrawableContainer out - /// ISurface + /// ISurface /// bool true if it was successful - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent); + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null); } } diff --git a/src/Greenshot.Editor/Drawing/IconContainer.cs b/src/Greenshot.Editor/Drawing/IconContainer.cs index adda1cc23..dd6668ce9 100644 --- a/src/Greenshot.Editor/Drawing/IconContainer.cs +++ b/src/Greenshot.Editor/Drawing/IconContainer.cs @@ -61,6 +61,11 @@ namespace Greenshot.Editor.Drawing Load(filename); } + public IconContainer(ISurface parent, Stream stream) : base(parent) + { + Load(stream); + } + public Icon Icon { set @@ -100,6 +105,18 @@ namespace Greenshot.Editor.Drawing Log.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width); } + public void Load(Stream iconStream) + { + if (iconStream == null) + { + return; + } + + using Icon fileIcon = new Icon(iconStream); + Icon = fileIcon; + Log.Debug("Loaded stream: with resolution: " + Height + "," + Width); + } + public override void Draw(Graphics graphics, RenderMode rm) { if (icon == null) diff --git a/src/Greenshot.Editor/Drawing/MetafileContainer.cs b/src/Greenshot.Editor/Drawing/MetafileContainer.cs new file mode 100644 index 000000000..79159b262 --- /dev/null +++ b/src/Greenshot.Editor/Drawing/MetafileContainer.cs @@ -0,0 +1,71 @@ +/* + * 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 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 MetafileContainer : VectorGraphicsContainer + { + private readonly Metafile _metafile; + + public MetafileContainer(Metafile metafile, ISurface parent) : base(parent) + { + _metafile = metafile; + Size = new Size(metafile.Width/4, metafile.Height/4); + } + + protected override Image ComputeBitmap() + { + var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent); + + var dstRect = new Rectangle(0, 0, Width, Height); + using (Graphics graphics = Graphics.FromImage(image)) + { + graphics.SmoothingMode = SmoothingMode.HighQuality; + graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + graphics.CompositingQuality = CompositingQuality.HighQuality; + graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; + graphics.DrawImage(_metafile, dstRect); + } + + if (RotationAngle == 0) return image; + + var newImage = image.Rotate(RotationAngle); + image.Dispose(); + return newImage; + } + + public override bool HasDefaultSize => true; + + public override Size DefaultSize => new Size(_metafile.Width, _metafile.Height); + } +} \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs index 2445cb486..d39276992 100644 --- a/src/Greenshot.Editor/Drawing/Surface.cs +++ b/src/Greenshot.Editor/Drawing/Surface.cs @@ -49,7 +49,6 @@ namespace Greenshot.Editor.Drawing public sealed class Surface : Control, ISurface, INotifyPropertyChanged { private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface)); - public static int Count; private static readonly CoreConfiguration conf = IniConfig.GetIniSection(); // Property to identify the Surface ID @@ -207,7 +206,7 @@ namespace Greenshot.Editor.Drawing [NonSerialized] private IDrawableContainer _undrawnElement; /// - /// the cropcontainer, when cropping this is set, do not serialize + /// the crop container, when cropping this is set, do not serialize /// [NonSerialized] private IDrawableContainer _cropContainer; @@ -467,7 +466,6 @@ namespace Greenshot.Editor.Drawing public Surface() { _fieldAggregator = new FieldAggregator(this); - Count++; _elements = new DrawableContainerList(_uniqueId); selectedElements = new DrawableContainerList(_uniqueId); LOG.Debug("Creating surface!"); @@ -550,7 +548,6 @@ namespace Greenshot.Editor.Drawing { if (disposing) { - Count--; LOG.Debug("Disposing surface!"); if (_buffer != null) { @@ -927,20 +924,23 @@ namespace Greenshot.Editor.Drawing // Test if it's an url and try to download the image so we have it in the original form if (possibleUrl != null && possibleUrl.StartsWith("http")) { - using Image image = NetworkHelper.DownloadImage(possibleUrl); - if (image != null) + var drawableContainer = NetworkHelper.DownloadImageAsDrawableContainer(possibleUrl); + if (drawableContainer != null) { - AddImageContainer(image, mouse.X, mouse.Y); + drawableContainer.Left = Location.X; + drawableContainer.Top = Location.Y; + AddElement(drawableContainer); return; } } } - foreach (Image image in ClipboardHelper.GetImages(e.Data)) + foreach (var drawableContainer in ClipboardHelper.GetImages(e.Data)) { - AddImageContainer(image, mouse.X, mouse.Y); + drawableContainer.Left = mouse.X; + drawableContainer.Top = mouse.Y; + AddElement(drawableContainer); mouse.Offset(10, 10); - image.Dispose(); } } @@ -2057,17 +2057,15 @@ namespace Greenshot.Editor.Drawing { Point pasteLocation = GetPasteLocation(0.1f, 0.1f); - foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard)) + foreach (var drawableContainer in ClipboardHelper.GetImages(clipboard)) { - if (clipboardImage != null) - { - DeselectAllElements(); - IImageContainer container = AddImageContainer(clipboardImage as Bitmap, pasteLocation.X, pasteLocation.Y); - SelectElement(container); - clipboardImage.Dispose(); - pasteLocation.X += 10; - pasteLocation.Y += 10; - } + if (drawableContainer == null) continue; + DeselectAllElements(); + drawableContainer.Left = pasteLocation.X; + drawableContainer.Top = pasteLocation.Y; + SelectElement(drawableContainer); + pasteLocation.X += 10; + pasteLocation.Y += 10; } } else if (ClipboardHelper.ContainsText(clipboard)) diff --git a/src/Greenshot.Editor/Drawing/SvgContainer.cs b/src/Greenshot.Editor/Drawing/SvgContainer.cs index d1a3d1e20..f98f03a32 100644 --- a/src/Greenshot.Editor/Drawing/SvgContainer.cs +++ b/src/Greenshot.Editor/Drawing/SvgContainer.cs @@ -21,7 +21,6 @@ using System; using System.Drawing; -using System.Drawing.Imaging; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; using Svg; @@ -44,14 +43,19 @@ namespace Greenshot.Editor.Drawing protected override Image ComputeBitmap() { - var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppRgb, Color.Transparent); + //var image = ImageHelper.CreateEmpty(Width, Height, PixelFormat.Format32bppArgb, Color.Transparent); - _svgDocument.Draw(image); + var image = _svgDocument.Draw(Width, Height); + if (RotationAngle == 0) return image; var newImage = image.Rotate(RotationAngle); image.Dispose(); return newImage; } + + public override bool HasDefaultSize => true; + + public override Size DefaultSize => new Size((int)_svgDocument.Width, (int)_svgDocument.Height); } } \ No newline at end of file diff --git a/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs index 2ad97e093..0c467c0b8 100644 --- a/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs +++ b/src/Greenshot.Editor/Drawing/VectorGraphicsContainer.cs @@ -22,9 +22,7 @@ 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; @@ -78,6 +76,7 @@ namespace Greenshot.Editor.Drawing base.Dispose(disposing); } + /// public override void Transform(Matrix matrix) { RotationAngle += CalculateAngle(matrix); @@ -88,34 +87,26 @@ namespace Greenshot.Editor.Drawing 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(); + _cachedImage ??= ComputeBitmap(); + + graphics.SmoothingMode = SmoothingMode.HighQuality; + graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + graphics.CompositingQuality = CompositingQuality.HighQuality; + graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; + 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; - - } + protected abstract Image ComputeBitmap(); private void ResetCachedBitmap() { diff --git a/src/Greenshot.Editor/EditorInitialize.cs b/src/Greenshot.Editor/EditorInitialize.cs index e3b2667fd..47a50e7ac 100644 --- a/src/Greenshot.Editor/EditorInitialize.cs +++ b/src/Greenshot.Editor/EditorInitialize.cs @@ -29,6 +29,11 @@ namespace Greenshot.Editor public static void Initialize() { FileFormatHandlerRegistry.FileFormatHandlers.Add(new SvgFileFormatHandler()); + FileFormatHandlerRegistry.FileFormatHandlers.Add(new DefaultFileFormatHandler()); + FileFormatHandlerRegistry.FileFormatHandlers.Add(new DibFileFormatHandler()); + FileFormatHandlerRegistry.FileFormatHandlers.Add(new GreenshotFileFormatHandler()); + FileFormatHandlerRegistry.FileFormatHandlers.Add(new IconFileFormatHandler()); + FileFormatHandlerRegistry.FileFormatHandlers.Add(new MetaFileFormatHandler()); } } } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs similarity index 68% rename from src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs rename to src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs index 74d2e3573..419e1898e 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/DefaultFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs @@ -19,44 +19,36 @@ * 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.Core; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Editor.Drawing; -namespace Greenshot.Base.Core.FileFormatHandlers +namespace Greenshot.Editor.FileFormatHandlers { /// /// This is the default .NET bitmap file format handler /// - public class DefaultFileFormatHandler : IFileFormatHandler + public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - private static readonly string [] OurExtensions = { "png", "bmp", "gif", "jpg", "jpeg", "tiff", "tif" }; + 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?.ToLowerInvariant()); + return OurExtensions.Contains(NormalizeExtension(extension)); } /// @@ -68,15 +60,15 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) { - ImageFormat imageFormat = extension?.ToLowerInvariant() switch + ImageFormat imageFormat = NormalizeExtension(extension) switch { - "png" => ImageFormat.Png, - "bmp" => ImageFormat.Bmp, - "gif" => ImageFormat.Gif, - "jpg" => ImageFormat.Jpeg, - "jpeg" => ImageFormat.Jpeg, - "tiff" => ImageFormat.Tiff, - "tif" => ImageFormat.Tiff, + ".png" => ImageFormat.Png, + ".bmp" => ImageFormat.Bmp, + ".gif" => ImageFormat.Gif, + ".jpg" => ImageFormat.Jpeg, + ".jpeg" => ImageFormat.Jpeg, + ".tiff" => ImageFormat.Tiff, + ".tif" => ImageFormat.Tiff, _ => null }; @@ -97,9 +89,20 @@ namespace Greenshot.Base.Core.FileFormatHandlers } /// - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null) { - throw new NotImplementedException(); + if (TryLoadFromStream(stream, extension, out var bitmap)) + { + var imageContainer = new ImageContainer(surface) + { + Image = bitmap + }; + drawableContainer = imageContainer; + return true; + } + + drawableContainer = null; + return true; } } } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs similarity index 68% rename from src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs rename to src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs index 79c78ef27..495f669b9 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/DibFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs @@ -26,40 +26,36 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Runtime.InteropServices; +using Greenshot.Base.Core; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.UnmanagedHelpers; +using Greenshot.Editor.Drawing; +using log4net; -namespace Greenshot.Base.Core.FileFormatHandlers +namespace Greenshot.Editor.FileFormatHandlers { /// /// This handles creating a DIB (Device Independent Bitmap) on the clipboard /// - public class DibFileFormatHandler : IFileFormatHandler + public class DibFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private const double DpiToPelsPerMeter = 39.3701; - private static readonly string [] OurExtensions = { "dib" }; + private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler)); + private static readonly string [] OurExtensions = { ".dib", ".format17" }; /// public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) - { - return Enumerable.Empty(); - } - return OurExtensions; } /// public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) { - if (string.IsNullOrEmpty(extension) || fileFormatHandlerAction != FileFormatHandlerActions.SaveToStream) - { - return false; - } - - return OurExtensions.Contains(extension.ToLowerInvariant()); + extension = NormalizeExtension(extension); + return OurExtensions.Contains(extension); } /// @@ -79,13 +75,79 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { - throw new NotImplementedException(); + byte[] dibBuffer = new byte[stream.Length]; + _ = stream.Read(dibBuffer, 0, dibBuffer.Length); + var infoHeader = BinaryStructHelper.FromByteArray(dibBuffer); + if (!infoHeader.IsDibV5) + { + Log.InfoFormat("Using special DIB - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null) { - throw new NotImplementedException(); + if (TryLoadFromStream(stream, extension, out var bitmap)) + { + var imageContainer = new ImageContainer(surface) + { + Image = bitmap + }; + drawableContainer = imageContainer; + return true; + } + + drawableContainer = null; + return true; } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs similarity index 83% rename from src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs rename to src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs index 5370f8934..0a4483884 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs @@ -24,14 +24,16 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; +using Greenshot.Base.Core; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; -namespace Greenshot.Base.Core.FileFormatHandlers +namespace Greenshot.Editor.FileFormatHandlers { - public class GreenshotFileFormatHandler : IFileFormatHandler + public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - private static readonly string[] OurExtensions = { "greenshot" }; + private static readonly string[] OurExtensions = { ".greenshot" }; /// public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) @@ -51,8 +53,12 @@ namespace Greenshot.Base.Core.FileFormatHandlers { return false; } + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) + { + return false; + } - return OurExtensions.Contains(extension?.ToLowerInvariant()); + return OurExtensions.Contains(NormalizeExtension(extension)); } @@ -75,7 +81,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers return true; } - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null) { throw new NotImplementedException(); } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs similarity index 86% rename from src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs rename to src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs index ab92f814e..aa254e760 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/IconFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs @@ -25,25 +25,28 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; +using Greenshot.Base.Core; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Editor.Drawing; using log4net; -namespace Greenshot.Base.Core.FileFormatHandlers +namespace Greenshot.Editor.FileFormatHandlers { /// /// THis is the default .NET bitmap file format handler /// - public class IconFileFormatHandler : IFileFormatHandler + public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper)); - private static readonly string[] OurExtensions = { "ico" }; + private static readonly string[] OurExtensions = { ".ico" }; /// public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) { return Enumerable.Empty(); } @@ -54,12 +57,12 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) { return false; } - return OurExtensions.Contains(extension?.ToLowerInvariant()); + return OurExtensions.Contains(NormalizeExtension(extension)); } /// @@ -76,7 +79,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { - var startingPosition = stream.Seek(0, SeekOrigin.Current); + _ = stream.Seek(0, SeekOrigin.Current); // Icon logic, try to get the Vista icon, else the biggest possible try @@ -113,10 +116,20 @@ namespace Greenshot.Base.Core.FileFormatHandlers } - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null) { - // TODO: Implement this - throw new NotImplementedException(); + if (TryLoadFromStream(stream, extension, out var bitmap)) + { + var imageContainer = new ImageContainer(surface) + { + Image = bitmap + }; + drawableContainer = imageContainer; + return true; + } + + drawableContainer = null; + return true; } /// diff --git a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs new file mode 100644 index 000000000..42280c0c2 --- /dev/null +++ b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs @@ -0,0 +1,108 @@ +/* + * 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.Drawing.Imaging; +using System.IO; +using System.Linq; +using Greenshot.Base.Core; +using Greenshot.Base.Core.FileFormatHandlers; +using Greenshot.Base.Interfaces; +using Greenshot.Base.Interfaces.Drawing; +using Greenshot.Editor.Drawing; + +namespace Greenshot.Editor.FileFormatHandlers +{ + /// + /// This handles the Windows metafile files + /// + public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler + { + private static readonly string [] OurExtensions = { ".wmf", ".emf" }; + + /// + public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) + { + return Enumerable.Empty(); + } + + return OurExtensions; + } + + /// + public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) + { + return false; + } + + return OurExtensions.Contains(NormalizeExtension(extension)); + } + + /// + public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + return int.MaxValue; + } + + /// + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) + { + return false; + } + + /// + public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) + { + try + { + if (Image.FromStream(stream, true, true) is Metafile metaFile) + { + bitmap = ImageHelper.Clone(metaFile, PixelFormat.Format32bppArgb); + return true; + } + } + catch + { + // Ignore + } + bitmap = null; + return false; + } + + /// + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface surface = null) + { + if (Image.FromStream(stream, true, true) is Metafile metaFile) + { + drawableContainer = new MetafileContainer(metaFile, surface); + return true; + } + + drawableContainer = null; + return false; + } + } +} diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs similarity index 98% rename from src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs rename to src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs index 84ed74c17..a7a2820d5 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/PngFileFormatHandler.cs @@ -27,7 +27,7 @@ using System.Linq; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; -namespace Greenshot.Base.Core.FileFormatHandlers +namespace Greenshot.Editor.FileFormatHandlers { /// /// This can be an ImageSharp implementation diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs index aa0a512de..17c3eb542 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs @@ -26,6 +26,7 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using Greenshot.Base.Core; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing; @@ -37,15 +38,15 @@ namespace Greenshot.Editor.FileFormatHandlers /// /// This handled the loading of SVG images to the editor /// - public class SvgFileFormatHandler : IFileFormatHandler + public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper)); - private static readonly string[] OurExtensions = { "svg" }; + private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler)); + private static readonly string[] OurExtensions = { ".svg" }; /// public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) { return Enumerable.Empty(); } @@ -56,12 +57,12 @@ namespace Greenshot.Editor.FileFormatHandlers /// public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) { return false; } - return OurExtensions.Contains(extension); + return OurExtensions.Contains(NormalizeExtension(extension)); } /// public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) @@ -96,9 +97,14 @@ namespace Greenshot.Editor.FileFormatHandlers return false; } - public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent = null) { var svgDocument = SvgDocument.Open(stream); + if (svgDocument == null) + { + drawableContainer = null; + return false; + } drawableContainer = new SvgContainer(svgDocument, parent); return true; } diff --git a/src/Greenshot.Editor/Greenshot.Editor.csproj b/src/Greenshot.Editor/Greenshot.Editor.csproj index 768bdb99d..7da9d555d 100644 --- a/src/Greenshot.Editor/Greenshot.Editor.csproj +++ b/src/Greenshot.Editor/Greenshot.Editor.csproj @@ -1,4 +1,7 @@  + + True + PreserveNewest diff --git a/src/Greenshot/Helpers/CaptureHelper.cs b/src/Greenshot/Helpers/CaptureHelper.cs index 3d0d3385d..5e031c6af 100644 --- a/src/Greenshot/Helpers/CaptureHelper.cs +++ b/src/Greenshot/Helpers/CaptureHelper.cs @@ -389,6 +389,7 @@ namespace Greenshot.Helpers HandleCapture(); break; case CaptureMode.Clipboard: + // TODO: Fix getting image vs. drawablecontainer Image clipboardImage = ClipboardHelper.GetImage(); if (clipboardImage != null) {