mirror of
https://github.com/ShareX/ShareX.git
synced 2024-07-04 22:21:23 +12:00
Interim Greenshot image editor merge
This commit is contained in:
parent
08e45ba960
commit
a1ac901852
|
@ -1061,10 +1061,12 @@ public static void ApplyColorMatrix(Bitmap source, ColorMatrix colorMatrix)
|
|||
/// <param name="colorMatrix">ColorMatrix to apply</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be overridden to handle gripper moves on the "TargetGripper"
|
||||
/// Move the TargetGripper around, confined to the surface to solve BUG-1682
|
||||
/// </summary>
|
||||
/// <param name="newX"></param>
|
||||
/// <param name="newY"></param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Greenshot.Plugin;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Greenshot.Drawing.Fields.Binding
|
||||
{
|
||||
/// <summary>
|
||||
/// Converting horizontal alignment to its StringAlignment representation and vice versa.
|
||||
/// Beware: there's currently no RTL support.
|
||||
/// </summary>
|
||||
public class HorizontalAlignmentConverter : AbstractBindingConverter<HorizontalAlignment, StringAlignment>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converting vertical alignment to its StringAlignment representation and vice versa.
|
||||
/// </summary>
|
||||
public class VerticalAlignmentConverter : AbstractBindingConverter<VerticalAlignment, StringAlignment>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
namespace Greenshot.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of Gripper.
|
||||
/// Grippers are the dragable edges of our containers
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overriding the HandleMouseMove will help us to make sure the tail is always visible.
|
||||
/// Should fix BUG-1682
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns>base.HandleMouseMove</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DrawingBound should be so close as possible to the shape, so we don't invalidate to much.
|
||||
/// </summary>
|
||||
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)
|
||||
/// <summary>
|
||||
/// Helper method to create the bubble GraphicsPath, so we can also calculate the bounds
|
||||
/// </summary>
|
||||
/// <param name="lineThickness"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create the tail of the bubble, so we can also calculate the bounds
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is to draw the actual container
|
||||
/// </summary>
|
||||
/// <param name="graphics"></param>
|
||||
/// <param name="renderMode"></param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,7 +31,6 @@
|
|||
namespace Greenshot.Drawing
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -1215,9 +1215,9 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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 @@ protected override void Dispose(bool disposing)
|
|||
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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -173,7 +173,6 @@
|
|||
<Compile Include="Core\WindowCapture.cs" />
|
||||
<Compile Include="Core\WindowsHelper.cs" />
|
||||
<Compile Include="Drawing\ArrowContainer.cs" />
|
||||
<Compile Include="Drawing\Fields\Binding\AlignmentConverter.cs" />
|
||||
<Compile Include="Drawing\ImageContainer.cs" />
|
||||
<Compile Include="Drawing\CropContainer.cs" />
|
||||
<Compile Include="Drawing\CursorContainer.cs" />
|
||||
|
|
Loading…
Reference in a new issue