From a1ac901852b93219860a60d95001444c7fadd3c7 Mon Sep 17 00:00:00 2001 From: Jaex Date: Mon, 22 Dec 2014 23:42:56 +0200 Subject: [PATCH] Interim Greenshot image editor merge --- Greenshot.ImageEditor/Core/ImageHelper.cs | 21 +- .../Drawing/DrawableContainer.cs | 43 +++- .../Fields/Binding/AlignmentConverter.cs | 101 --------- .../Drawing/Filters/BlurFilter.cs | 1 - .../Drawing/Filters/BrightnessFilter.cs | 6 +- .../Drawing/Filters/GrayscaleFilter.cs | 8 +- Greenshot.ImageEditor/Drawing/Gripper.cs | 29 +-- .../Drawing/SpeechbubbleContainer.cs | 213 +++++++++++++----- .../Drawing/StepLabelContainer.cs | 1 - .../Drawing/TextContainer.cs | 2 +- .../Forms/ImageEditorForm.Designer.cs | 20 +- .../Forms/ImageEditorForm.cs | 4 +- .../Greenshot.ImageEditor.csproj | 1 - 13 files changed, 231 insertions(+), 219 deletions(-) delete mode 100644 Greenshot.ImageEditor/Drawing/Fields/Binding/AlignmentConverter.cs diff --git a/Greenshot.ImageEditor/Core/ImageHelper.cs b/Greenshot.ImageEditor/Core/ImageHelper.cs index 639918a05..7d80dffb3 100644 --- a/Greenshot.ImageEditor/Core/ImageHelper.cs +++ b/Greenshot.ImageEditor/Core/ImageHelper.cs @@ -1061,10 +1061,12 @@ public static void ApplyColorMatrix(Bitmap source, ColorMatrix colorMatrix) /// ColorMatrix to apply public static void ApplyColorMatrix(Bitmap source, Rectangle sourceRect, Bitmap dest, Rectangle destRect, ColorMatrix colorMatrix) { - ImageAttributes imageAttributes = new ImageAttributes(); - imageAttributes.ClearColorMatrix(); - imageAttributes.SetColorMatrix(colorMatrix); - ApplyImageAttributes(source, sourceRect, dest, destRect, imageAttributes); + using (ImageAttributes imageAttributes = new ImageAttributes()) + { + imageAttributes.ClearColorMatrix(); + imageAttributes.SetColorMatrix(colorMatrix); + ApplyImageAttributes(source, sourceRect, dest, destRect, imageAttributes); + } } /// @@ -1223,7 +1225,10 @@ public static Image Adjust(Image sourceImage, float brightness, float contrast, //create a blank bitmap the same size as original // If using 8bpp than the following exception comes: A Graphics object cannot be created from an image that has an indexed pixel format. Bitmap newBitmap = CreateEmpty(sourceImage.Width, sourceImage.Height, PixelFormat.Format24bppRgb, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); - ApplyImageAttributes((Bitmap)sourceImage, Rectangle.Empty, newBitmap, Rectangle.Empty, CreateAdjustAttributes(brightness, contrast, gamma)); + using (ImageAttributes adjustAttributes = CreateAdjustAttributes(brightness, contrast, gamma)) + { + ApplyImageAttributes((Bitmap)sourceImage, Rectangle.Empty, newBitmap, Rectangle.Empty, adjustAttributes); + } return newBitmap; } @@ -1649,7 +1654,11 @@ public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, boo using (Graphics graphics = Graphics.FromImage(newImage)) { graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphics.DrawImage(sourceImage, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), GraphicsUnit.Pixel); + using (ImageAttributes wrapMode = new ImageAttributes()) + { + wrapMode.SetWrapMode(WrapMode.TileFlipXY); + graphics.DrawImage(sourceImage, new Rectangle(destX, destY, destWidth, destHeight), 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, wrapMode); + } } return newImage; } diff --git a/Greenshot.ImageEditor/Drawing/DrawableContainer.cs b/Greenshot.ImageEditor/Drawing/DrawableContainer.cs index b5e62ea0c..901e3cbea 100644 --- a/Greenshot.ImageEditor/Drawing/DrawableContainer.cs +++ b/Greenshot.ImageEditor/Drawing/DrawableContainer.cs @@ -279,11 +279,11 @@ public Size Size [NonSerialized] // will store current bounds of this DrawableContainer before starting a resize - private Rectangle _boundsBeforeResize = Rectangle.Empty; + protected Rectangle _boundsBeforeResize = Rectangle.Empty; [NonSerialized] // "workbench" rectangle - used for calculatoing bounds during resizing (to be applied to this DrawableContainer afterwards) - private RectangleF _boundsAfterResize = RectangleF.Empty; + protected RectangleF _boundsAfterResize = RectangleF.Empty; public Rectangle Bounds { @@ -364,7 +364,10 @@ public virtual Rectangle DrawingBounds public virtual void Invalidate() { - _parent.Invalidate(DrawingBounds); + if (Status != EditStatus.UNDRAWN) + { + _parent.Invalidate(DrawingBounds); + } } public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) @@ -414,14 +417,38 @@ private void InitControls() } /// - /// Should be overridden to handle gripper moves on the "TargetGripper" + /// Move the TargetGripper around, confined to the surface to solve BUG-1682 /// /// /// protected virtual void TargetGripperMove(int newX, int newY) { - _targetGripper.Left = newX; - _targetGripper.Top = newY; + Point newGripperLocation = new Point(newX, newY); + Rectangle surfaceBounds = new Rectangle(0, 0, _parent.Width, _parent.Height); + // Check if gripper inside the parent (surface), if not we need to move it inside + // This was made for BUG-1682 + if (!surfaceBounds.Contains(newGripperLocation)) + { + if (newGripperLocation.X > surfaceBounds.Right) + { + newGripperLocation.X = surfaceBounds.Right - 5; + } + if (newGripperLocation.X < surfaceBounds.Left) + { + newGripperLocation.X = surfaceBounds.Left; + } + if (newGripperLocation.Y > surfaceBounds.Bottom) + { + newGripperLocation.Y = surfaceBounds.Bottom - 5; + } + if (newGripperLocation.Y < surfaceBounds.Top) + { + newGripperLocation.Y = surfaceBounds.Top; + } + } + + _targetGripper.Left = newGripperLocation.X; + _targetGripper.Top = newGripperLocation.Y; } /// @@ -560,6 +587,7 @@ private void GripperMouseUp(object sender, MouseEventArgs e) private void GripperMouseMove(object sender, MouseEventArgs e) { + Invalidate(); Gripper originatingGripper = (Gripper)sender; int absX = originatingGripper.Left + e.X; int absY = originatingGripper.Top + e.Y; @@ -578,7 +606,6 @@ private void GripperMouseMove(object sender, MouseEventArgs e) MakeBoundsChangeUndoable(false); } - Invalidate(); SuspendLayout(); // reset "workbench" rectangle to current bounds @@ -594,8 +621,8 @@ private void GripperMouseMove(object sender, MouseEventArgs e) ApplyBounds(_boundsAfterResize); ResumeLayout(); - Invalidate(); } + Invalidate(); } public bool hasFilters diff --git a/Greenshot.ImageEditor/Drawing/Fields/Binding/AlignmentConverter.cs b/Greenshot.ImageEditor/Drawing/Fields/Binding/AlignmentConverter.cs deleted file mode 100644 index 9c4134e44..000000000 --- a/Greenshot.ImageEditor/Drawing/Fields/Binding/AlignmentConverter.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Greenshot - a free and open source screenshot tool - * Copyright (C) 2007-2013 Thomas Braun, Jens Klingen, Robin Krom - * - * For more information see: http://getgreenshot.org/ - * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 Greenshot.Plugin; -using System; -using System.Drawing; -using System.Windows.Forms; - -namespace Greenshot.Drawing.Fields.Binding -{ - /// - /// Converting horizontal alignment to its StringAlignment representation and vice versa. - /// Beware: there's currently no RTL support. - /// - public class HorizontalAlignmentConverter : AbstractBindingConverter - { - private static HorizontalAlignmentConverter uniqueInstance; - - protected override HorizontalAlignment convert(StringAlignment stringAlignment) - { - switch (stringAlignment) - { - case StringAlignment.Near: return HorizontalAlignment.Left; - case StringAlignment.Center: return HorizontalAlignment.Center; - case StringAlignment.Far: return HorizontalAlignment.Right; - default: throw new NotImplementedException("Cannot handle: " + stringAlignment); - } - } - - protected override StringAlignment convert(HorizontalAlignment horizontalAligment) - { - switch (horizontalAligment) - { - case HorizontalAlignment.Left: return StringAlignment.Near; - case HorizontalAlignment.Center: return StringAlignment.Center; - case HorizontalAlignment.Right: return StringAlignment.Far; - default: throw new NotImplementedException("Cannot handle: " + horizontalAligment); - } - } - - public static HorizontalAlignmentConverter GetInstance() - { - if (uniqueInstance == null) uniqueInstance = new HorizontalAlignmentConverter(); - return uniqueInstance; - } - } - - /// - /// Converting vertical alignment to its StringAlignment representation and vice versa. - /// - public class VerticalAlignmentConverter : AbstractBindingConverter - { - private static VerticalAlignmentConverter uniqueInstance; - - protected override VerticalAlignment convert(StringAlignment stringAlignment) - { - switch (stringAlignment) - { - case StringAlignment.Near: return VerticalAlignment.TOP; - case StringAlignment.Center: return VerticalAlignment.CENTER; - case StringAlignment.Far: return VerticalAlignment.BOTTOM; - default: throw new NotImplementedException("Cannot handle: " + stringAlignment); - } - } - - protected override StringAlignment convert(VerticalAlignment verticalAligment) - { - switch (verticalAligment) - { - case VerticalAlignment.TOP: return StringAlignment.Near; - case VerticalAlignment.CENTER: return StringAlignment.Center; - case VerticalAlignment.BOTTOM: return StringAlignment.Far; - default: throw new NotImplementedException("Cannot handle: " + verticalAligment); - } - } - - public static VerticalAlignmentConverter GetInstance() - { - if (uniqueInstance == null) uniqueInstance = new VerticalAlignmentConverter(); - return uniqueInstance; - } - } -} \ No newline at end of file diff --git a/Greenshot.ImageEditor/Drawing/Filters/BlurFilter.cs b/Greenshot.ImageEditor/Drawing/Filters/BlurFilter.cs index 210675b11..2cae5496e 100644 --- a/Greenshot.ImageEditor/Drawing/Filters/BlurFilter.cs +++ b/Greenshot.ImageEditor/Drawing/Filters/BlurFilter.cs @@ -49,7 +49,6 @@ public BlurFilter(DrawableContainer parent) public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) { int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS); - double previewQuality = GetFieldValueAsDouble(FieldType.PREVIEW_QUALITY); Rectangle applyRect = ImageHelper.CreateIntersectRectangle(applyBitmap.Size, rect, Invert); if (applyRect.Width == 0 || applyRect.Height == 0) { diff --git a/Greenshot.ImageEditor/Drawing/Filters/BrightnessFilter.cs b/Greenshot.ImageEditor/Drawing/Filters/BrightnessFilter.cs index 39743a419..0ce0c971f 100644 --- a/Greenshot.ImageEditor/Drawing/Filters/BrightnessFilter.cs +++ b/Greenshot.ImageEditor/Drawing/Filters/BrightnessFilter.cs @@ -62,8 +62,10 @@ public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect graphics.ExcludeClip(rect); } float brightness = GetFieldValueAsFloat(FieldType.BRIGHTNESS); - ImageAttributes ia = ImageHelper.CreateAdjustAttributes(brightness, 1f, 1f); - graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); + using (ImageAttributes ia = ImageHelper.CreateAdjustAttributes(brightness, 1f, 1f)) + { + graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); + } graphics.Restore(state); } } diff --git a/Greenshot.ImageEditor/Drawing/Filters/GrayscaleFilter.cs b/Greenshot.ImageEditor/Drawing/Filters/GrayscaleFilter.cs index f142a8a63..f01080279 100644 --- a/Greenshot.ImageEditor/Drawing/Filters/GrayscaleFilter.cs +++ b/Greenshot.ImageEditor/Drawing/Filters/GrayscaleFilter.cs @@ -61,9 +61,11 @@ public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1} }); - ImageAttributes ia = new ImageAttributes(); - ia.SetColorMatrix(grayscaleMatrix); - graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); + using (ImageAttributes ia = new ImageAttributes()) + { + ia.SetColorMatrix(grayscaleMatrix); + graphics.DrawImage(applyBitmap, applyRect, applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height, GraphicsUnit.Pixel, ia); + } graphics.Restore(state); } } diff --git a/Greenshot.ImageEditor/Drawing/Gripper.cs b/Greenshot.ImageEditor/Drawing/Gripper.cs index b97861c85..9bb60107c 100644 --- a/Greenshot.ImageEditor/Drawing/Gripper.cs +++ b/Greenshot.ImageEditor/Drawing/Gripper.cs @@ -25,7 +25,7 @@ namespace Greenshot.Drawing { /// - /// Description of Gripper. + /// Grippers are the dragable edges of our containers /// public class Gripper : Label { @@ -45,7 +45,7 @@ public class Gripper : Label public const int POSITION_MIDDLE_LEFT = 7; public const int GripperSize = 7; - public int Position; + public int Position { get; set; } public Gripper() { @@ -54,30 +54,5 @@ public Gripper() BackColor = Color.White; BorderStyle = BorderStyle.FixedSingle; } - - public bool IsTop() - { - return Position == 0 || Position == 1 || Position == 2; - } - - public bool IsRight() - { - return Position == 2 || Position == 3 || Position == 4; - } - - public bool IsBottom() - { - return Position == 4 || Position == 5 || Position == 6; - } - - public bool IsLeft() - { - return Position == 6 || Position == 7 || Position == 0; - } - - public bool IsCorner() - { - return Position == 0 || Position == 2 || Position == 4 || Position == 6; - } } } \ No newline at end of file diff --git a/Greenshot.ImageEditor/Drawing/SpeechbubbleContainer.cs b/Greenshot.ImageEditor/Drawing/SpeechbubbleContainer.cs index db408e56b..0753fc884 100644 --- a/Greenshot.ImageEditor/Drawing/SpeechbubbleContainer.cs +++ b/Greenshot.ImageEditor/Drawing/SpeechbubbleContainer.cs @@ -1,6 +1,6 @@ /* * Greenshot - a free and open source screenshot tool - * Copyright (C) 2007-2014 Thomas Braun, Jens Klingen, Robin Krom + * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom * * For more information see: http://getgreenshot.org/ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ @@ -28,6 +28,7 @@ using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Runtime.Serialization; +using System.Windows.Forms; namespace Greenshot.Drawing { @@ -37,6 +38,8 @@ namespace Greenshot.Drawing [Serializable] public class SpeechbubbleContainer : TextContainer { + private Point _initialGripperPoint; + #region TargetGripper serializing code // Only used for serializing the TargetGripper location @@ -86,13 +89,7 @@ protected override void InitializeFields() AddField(GetType(), FieldType.FONT_FAMILY, FontFamily.GenericSansSerif.Name); AddField(GetType(), FieldType.FONT_SIZE, 20f); AddField(GetType(), FieldType.TEXT_HORIZONTAL_ALIGNMENT, StringAlignment.Center); - AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, VerticalAlignment.CENTER); - } - - protected override void TargetGripperMove(int absX, int absY) - { - base.TargetGripperMove(absX, absY); - Invalidate(); + AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, StringAlignment.CENTER); } /// @@ -103,49 +100,73 @@ public override bool HandleMouseDown(int mouseX, int mouseY) { if (TargetGripper == null) { + _initialGripperPoint = new Point(mouseX, mouseY); InitTargetGripper(Color.Yellow, new Point(mouseX, mouseY)); } - return base.HandleMouseDown(mouseX + 20, mouseY + 20); + return base.HandleMouseDown(mouseX, mouseY); } + /// + /// Overriding the HandleMouseMove will help us to make sure the tail is always visible. + /// Should fix BUG-1682 + /// + /// + /// + /// base.HandleMouseMove + public override bool HandleMouseMove(int x, int y) + { + bool returnValue = base.HandleMouseMove(x, y); + + bool leftAligned = _boundsAfterResize.Right - _boundsAfterResize.Left >= 0; + bool topAligned = _boundsAfterResize.Bottom - _boundsAfterResize.Top >= 0; + + int xOffset = leftAligned ? -20 : 20; + int yOffset = topAligned ? -20 : 20; + + Point newGripperLocation = _initialGripperPoint; + newGripperLocation.Offset(xOffset, yOffset); + + if (TargetGripper.Location != newGripperLocation) + { + Invalidate(); + TargetGripperMove(newGripperLocation.X, newGripperLocation.Y); + Invalidate(); + } + return returnValue; + } + + /// + /// The DrawingBound should be so close as possible to the shape, so we don't invalidate to much. + /// public override Rectangle DrawingBounds { get { - // TODO: Use the normal bounds and extend with the TargetGripper - return new Rectangle(0, 0, _parent.Width, _parent.Height); + if (Status != EditStatus.UNDRAWN) + { + int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); + Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); + using (Pen pen = new Pen(lineColor, lineThickness)) + { + using (GraphicsPath tailPath = CreateTail()) + { + return Rectangle.Inflate(Rectangle.Union(Rectangle.Round(tailPath.GetBounds(new Matrix(), pen)), GuiRectangle.GetGuiRectangle(Left, Top, Width, Height)), lineThickness + 2, lineThickness + 2); + } + } + } + return Rectangle.Empty; } } - public override void Draw(Graphics graphics, RenderMode renderMode) + /// + /// Helper method to create the bubble GraphicsPath, so we can also calculate the bounds + /// + /// + /// + private GraphicsPath CreateBubble(int lineThickness) { - if (TargetGripper == null) - { - return; - } - graphics.SmoothingMode = SmoothingMode.HighQuality; - graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; - graphics.CompositingQuality = CompositingQuality.HighQuality; - graphics.PixelOffsetMode = PixelOffsetMode.None; - graphics.TextRenderingHint = TextRenderingHint.SystemDefault; - - Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); - Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); - int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); - - bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); - Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); - - if (Selected && renderMode == RenderMode.EDIT) - { - DrawSelectionBorder(graphics, rect); - } - - int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); - int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); - int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20; - GraphicsPath bubble = new GraphicsPath(); + Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle bubbleRect = GuiRectangle.GetGuiRectangle(0, 0, rect.Width, rect.Height); // adapt corner radius to small rectangle dimensions @@ -163,20 +184,113 @@ public override void Draw(Graphics graphics, RenderMode renderMode) bubble.AddRectangle(bubbleRect); } bubble.CloseAllFigures(); + using (Matrix bubbleMatrix = new Matrix()) + { + bubbleMatrix.Translate(rect.Left, rect.Top); + bubble.Transform(bubbleMatrix); + } + return bubble; + } + + /// + /// Helper method to create the tail of the bubble, so we can also calculate the bounds + /// + /// + private GraphicsPath CreateTail() + { + Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); + + int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); + int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20; + + // This should fix a problem with the tail being to wide + tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth); + tailWidth = Math.Min(Math.Abs(rect.Height) / 2, tailWidth); GraphicsPath tail = new GraphicsPath(); tail.AddLine(-tailWidth, 0, tailWidth, 0); tail.AddLine(tailWidth, 0, 0, -tailLength); tail.CloseFigure(); + int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top); + + using (Matrix tailMatrix = new Matrix()) + { + tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); + tailMatrix.Rotate(tailAngle); + tail.Transform(tailMatrix); + } + + return tail; + } + + /// + /// This is to draw the actual container + /// + /// + /// + public override void Draw(Graphics graphics, RenderMode renderMode) + { + if (TargetGripper == null) + { + return; + } + graphics.SmoothingMode = SmoothingMode.HighQuality; + graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + graphics.CompositingQuality = CompositingQuality.HighQuality; + graphics.PixelOffsetMode = PixelOffsetMode.None; + graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; + + Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR); + Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR); + bool shadow = GetFieldValueAsBool(FieldType.SHADOW); + int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); + + bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor)); + Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); + + if (Selected && renderMode == RenderMode.EDIT) + { + DrawSelectionBorder(graphics, rect); + } + + GraphicsPath bubble = CreateBubble(lineThickness); + + GraphicsPath tail = CreateTail(); + + //draw shadow first + if (shadow && (lineVisible || Colors.IsVisible(fillColor))) + { + const int basealpha = 100; + int alpha = basealpha; + const int steps = 5; + int currentStep = lineVisible ? 1 : 0; + using (Matrix shadowMatrix = new Matrix()) + using (GraphicsPath bubbleClone = (GraphicsPath)bubble.Clone()) + using (GraphicsPath tailClone = (GraphicsPath)tail.Clone()) + { + shadowMatrix.Translate(1, 1); + while (currentStep <= steps) + { + using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) + { + shadowPen.Width = lineVisible ? lineThickness : 1; + tailClone.Transform(shadowMatrix); + graphics.DrawPath(shadowPen, tailClone); + bubbleClone.Transform(shadowMatrix); + graphics.DrawPath(shadowPen, bubbleClone); + } + currentStep++; + alpha = alpha - (basealpha / steps); + } + } + } + GraphicsState state = graphics.Save(); // draw the tail border where the bubble is not visible using (Region clipRegion = new Region(bubble)) { - clipRegion.Translate(rect.Left, rect.Top); graphics.SetClip(clipRegion, CombineMode.Exclude); - graphics.TranslateTransform(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); - graphics.RotateTransform(tailAngle); using (Pen pen = new Pen(lineColor, lineThickness)) { graphics.DrawPath(pen, tail); @@ -188,7 +302,6 @@ public override void Draw(Graphics graphics, RenderMode renderMode) { //draw the bubbleshape state = graphics.Save(); - graphics.TranslateTransform(rect.Left, rect.Top); using (Brush brush = new SolidBrush(fillColor)) { graphics.FillPath(brush, bubble); @@ -203,14 +316,7 @@ public override void Draw(Graphics graphics, RenderMode renderMode) // Draw bubble where the Tail is not visible. using (Region clipRegion = new Region(tail)) { - using (Matrix transformMatrix = new Matrix()) - { - transformMatrix.Rotate(tailAngle); - clipRegion.Transform(transformMatrix); - } - clipRegion.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); graphics.SetClip(clipRegion, CombineMode.Exclude); - graphics.TranslateTransform(rect.Left, rect.Top); using (Pen pen = new Pen(lineColor, lineThickness)) { //pen.EndCap = pen.StartCap = LineCap.Round; @@ -224,8 +330,6 @@ public override void Draw(Graphics graphics, RenderMode renderMode) { // Draw the tail border state = graphics.Save(); - graphics.TranslateTransform(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); - graphics.RotateTransform(tailAngle); using (Brush brush = new SolidBrush(fillColor)) { graphics.FillPath(brush, tail); @@ -239,7 +343,7 @@ public override void Draw(Graphics graphics, RenderMode renderMode) // Draw the text UpdateFormat(); - DrawText(graphics, rect, lineThickness, lineColor, false, StringFormat, Text, Font); + DrawText(graphics, rect, lineThickness, lineColor, shadow, StringFormat, Text, Font); } public override bool Contains(int x, int y) @@ -278,10 +382,7 @@ public override bool ClickableAt(int x, int y) } } } - else - { - return false; - } + return false; } } } \ No newline at end of file diff --git a/Greenshot.ImageEditor/Drawing/StepLabelContainer.cs b/Greenshot.ImageEditor/Drawing/StepLabelContainer.cs index 2fbf9f1f1..b874f5e1d 100644 --- a/Greenshot.ImageEditor/Drawing/StepLabelContainer.cs +++ b/Greenshot.ImageEditor/Drawing/StepLabelContainer.cs @@ -31,7 +31,6 @@ namespace Greenshot.Drawing { /// - /// Description of StepLabelContainer. /// This is an enumerated label, every single StepLabelContainer shows the number of the order it was created. /// To make sure that deleting recalculates, we check the location before every draw. /// diff --git a/Greenshot.ImageEditor/Drawing/TextContainer.cs b/Greenshot.ImageEditor/Drawing/TextContainer.cs index d7dbe4a9c..5720246ba 100644 --- a/Greenshot.ImageEditor/Drawing/TextContainer.cs +++ b/Greenshot.ImageEditor/Drawing/TextContainer.cs @@ -109,7 +109,7 @@ protected override void InitializeFields() AddField(GetType(), FieldType.FONT_FAMILY, FontFamily.GenericSansSerif.Name); AddField(GetType(), FieldType.FONT_SIZE, 20f); AddField(GetType(), FieldType.TEXT_HORIZONTAL_ALIGNMENT, StringAlignment.Center); - AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, VerticalAlignment.CENTER); + AddField(GetType(), FieldType.TEXT_VERTICAL_ALIGNMENT, StringAlignment.CENTER); } [OnDeserialized] diff --git a/Greenshot.ImageEditor/Forms/ImageEditorForm.Designer.cs b/Greenshot.ImageEditor/Forms/ImageEditorForm.Designer.cs index 48ed1286e..ac5530cf3 100644 --- a/Greenshot.ImageEditor/Forms/ImageEditorForm.Designer.cs +++ b/Greenshot.ImageEditor/Forms/ImageEditorForm.Designer.cs @@ -1215,9 +1215,9 @@ private void InitializeComponent() { this.textHorizontalAlignmentButton.ImageTransparentColor = System.Drawing.Color.Magenta; this.textHorizontalAlignmentButton.LanguageKey = "editor_align_horizontal"; this.textHorizontalAlignmentButton.Name = "textHorizontalAlignmentButton"; - this.textHorizontalAlignmentButton.SelectedTag = System.Windows.Forms.HorizontalAlignment.Center; + this.textHorizontalAlignmentButton.SelectedTag = System.Drawing.StringAlignment.Center; this.textHorizontalAlignmentButton.Size = new System.Drawing.Size(29, 20); - this.textHorizontalAlignmentButton.Tag = System.Windows.Forms.HorizontalAlignment.Center; + this.textHorizontalAlignmentButton.Tag = System.Drawing.StringAlignment.Center; this.textHorizontalAlignmentButton.Text = "Horizontal alignment"; // // alignLeftToolStripMenuItem @@ -1226,7 +1226,7 @@ private void InitializeComponent() { this.alignLeftToolStripMenuItem.LanguageKey = "editor_align_left"; this.alignLeftToolStripMenuItem.Name = "alignLeftToolStripMenuItem"; this.alignLeftToolStripMenuItem.Size = new System.Drawing.Size(109, 22); - this.alignLeftToolStripMenuItem.Tag = System.Windows.Forms.HorizontalAlignment.Left; + this.alignLeftToolStripMenuItem.Tag = System.Drawing.StringAlignment.Near; this.alignLeftToolStripMenuItem.Text = "Left"; // // alignCenterToolStripMenuItem @@ -1235,7 +1235,7 @@ private void InitializeComponent() { this.alignCenterToolStripMenuItem.LanguageKey = "editor_align_center"; this.alignCenterToolStripMenuItem.Name = "alignCenterToolStripMenuItem"; this.alignCenterToolStripMenuItem.Size = new System.Drawing.Size(109, 22); - this.alignCenterToolStripMenuItem.Tag = System.Windows.Forms.HorizontalAlignment.Center; + this.alignCenterToolStripMenuItem.Tag = System.Drawing.StringAlignment.Center; this.alignCenterToolStripMenuItem.Text = "Center"; // // alignRightToolStripMenuItem @@ -1244,7 +1244,7 @@ private void InitializeComponent() { this.alignRightToolStripMenuItem.LanguageKey = "editor_align_right"; this.alignRightToolStripMenuItem.Name = "alignRightToolStripMenuItem"; this.alignRightToolStripMenuItem.Size = new System.Drawing.Size(109, 22); - this.alignRightToolStripMenuItem.Tag = System.Windows.Forms.HorizontalAlignment.Right; + this.alignRightToolStripMenuItem.Tag = System.Drawing.StringAlignment.Far; this.alignRightToolStripMenuItem.Text = "Right"; // // textVerticalAlignmentButton @@ -1258,9 +1258,9 @@ private void InitializeComponent() { this.textVerticalAlignmentButton.ImageTransparentColor = System.Drawing.Color.Magenta; this.textVerticalAlignmentButton.LanguageKey = "editor_align_vertical"; this.textVerticalAlignmentButton.Name = "textVerticalAlignmentButton"; - this.textVerticalAlignmentButton.SelectedTag = Greenshot.Plugin.VerticalAlignment.CENTER; + this.textVerticalAlignmentButton.SelectedTag = System.Drawing.StringAlignment.Center; this.textVerticalAlignmentButton.Size = new System.Drawing.Size(29, 20); - this.textVerticalAlignmentButton.Tag = Greenshot.Plugin.VerticalAlignment.CENTER; + this.textVerticalAlignmentButton.Tag = System.Drawing.StringAlignment.Center; this.textVerticalAlignmentButton.Text = "Vertical alignment"; // // alignTopToolStripMenuItem @@ -1269,7 +1269,7 @@ private void InitializeComponent() { this.alignTopToolStripMenuItem.LanguageKey = "editor_align_top"; this.alignTopToolStripMenuItem.Name = "alignTopToolStripMenuItem"; this.alignTopToolStripMenuItem.Size = new System.Drawing.Size(114, 22); - this.alignTopToolStripMenuItem.Tag = Greenshot.Plugin.VerticalAlignment.TOP; + this.alignTopToolStripMenuItem.Tag = System.Drawing.StringAlignment.Near; this.alignTopToolStripMenuItem.Text = "Top"; // // alignMiddleToolStripMenuItem @@ -1278,7 +1278,7 @@ private void InitializeComponent() { this.alignMiddleToolStripMenuItem.LanguageKey = "editor_align_middle"; this.alignMiddleToolStripMenuItem.Name = "alignMiddleToolStripMenuItem"; this.alignMiddleToolStripMenuItem.Size = new System.Drawing.Size(114, 22); - this.alignMiddleToolStripMenuItem.Tag = Greenshot.Plugin.VerticalAlignment.CENTER; + this.alignMiddleToolStripMenuItem.Tag = System.Drawing.StringAlignment.Center; this.alignMiddleToolStripMenuItem.Text = "Middle"; // // alignBottomToolStripMenuItem @@ -1287,7 +1287,7 @@ private void InitializeComponent() { this.alignBottomToolStripMenuItem.LanguageKey = "editor_align_bottom"; this.alignBottomToolStripMenuItem.Name = "alignBottomToolStripMenuItem"; this.alignBottomToolStripMenuItem.Size = new System.Drawing.Size(114, 22); - this.alignBottomToolStripMenuItem.Tag = Greenshot.Plugin.VerticalAlignment.BOTTOM; + this.alignBottomToolStripMenuItem.Tag = System.Drawing.StringAlignment.Far; this.alignBottomToolStripMenuItem.Text = "Bottom"; // // blurRadiusLabel diff --git a/Greenshot.ImageEditor/Forms/ImageEditorForm.cs b/Greenshot.ImageEditor/Forms/ImageEditorForm.cs index e76f5bc2d..ba9a6d54a 100644 --- a/Greenshot.ImageEditor/Forms/ImageEditorForm.cs +++ b/Greenshot.ImageEditor/Forms/ImageEditorForm.cs @@ -841,8 +841,8 @@ private void bindFieldControls() new BidirectionalBinding(fontSizeUpDown, "Value", surface.FieldAggregator.GetField(FieldType.FONT_SIZE), "Value", DecimalFloatConverter.GetInstance(), NotNullValidator.GetInstance()); new BidirectionalBinding(fontBoldButton, "Checked", surface.FieldAggregator.GetField(FieldType.FONT_BOLD), "Value", NotNullValidator.GetInstance()); new BidirectionalBinding(fontItalicButton, "Checked", surface.FieldAggregator.GetField(FieldType.FONT_ITALIC), "Value", NotNullValidator.GetInstance()); - new BidirectionalBinding(textHorizontalAlignmentButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.TEXT_HORIZONTAL_ALIGNMENT), "Value", HorizontalAlignmentConverter.GetInstance(), NotNullValidator.GetInstance()); - new BidirectionalBinding(textVerticalAlignmentButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.TEXT_VERTICAL_ALIGNMENT), "Value", VerticalAlignmentConverter.GetInstance(), NotNullValidator.GetInstance()); + new BidirectionalBinding(textHorizontalAlignmentButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.TEXT_HORIZONTAL_ALIGNMENT), "Value", NotNullValidator.GetInstance()); + new BidirectionalBinding(textVerticalAlignmentButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.TEXT_VERTICAL_ALIGNMENT), "Value", NotNullValidator.GetInstance()); new BidirectionalBinding(shadowButton, "Checked", surface.FieldAggregator.GetField(FieldType.SHADOW), "Value", NotNullValidator.GetInstance()); new BidirectionalBinding(previewQualityUpDown, "Value", surface.FieldAggregator.GetField(FieldType.PREVIEW_QUALITY), "Value", DecimalDoublePercentageConverter.GetInstance(), NotNullValidator.GetInstance()); new BidirectionalBinding(obfuscateModeButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_OBFUSCATE), "Value"); diff --git a/Greenshot.ImageEditor/Greenshot.ImageEditor.csproj b/Greenshot.ImageEditor/Greenshot.ImageEditor.csproj index 4a3507e1b..49f365cab 100644 --- a/Greenshot.ImageEditor/Greenshot.ImageEditor.csproj +++ b/Greenshot.ImageEditor/Greenshot.ImageEditor.csproj @@ -173,7 +173,6 @@ -