2013-11-11 13:48:31 +13:00
#region License Information ( GPL v3 )
/ *
ShareX - A program that allows you to take screenshots and share any file type
2018-01-02 03:59:14 +13:00
Copyright ( c ) 2007 - 2018 ShareX Team
2013-11-11 13:48:31 +13:00
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 2
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 , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
Optionally you can also view the license at < http : //www.gnu.org/licenses/>.
* /
#endregion License Information ( GPL v3 )
2014-12-11 09:25:20 +13:00
using ShareX.HelpersLib ;
2013-11-13 15:54:29 +13:00
using System.Collections.Generic ;
2013-11-11 13:48:31 +13:00
using System.ComponentModel ;
using System.Drawing ;
using System.Drawing.Design ;
using System.Drawing.Drawing2D ;
2013-11-13 15:54:29 +13:00
using System.Linq ;
2017-07-26 18:20:37 +12:00
using System.Windows.Forms ;
2013-11-11 13:48:31 +13:00
2014-12-11 09:25:20 +13:00
namespace ShareX.ImageEffectsLib
2013-11-11 13:48:31 +13:00
{
2014-10-13 12:36:18 +13:00
[Description("Text watermark")]
2013-11-17 22:30:47 +13:00
public class DrawText : ImageEffect
2013-11-11 13:48:31 +13:00
{
2013-11-16 22:50:08 +13:00
[DefaultValue(ContentAlignment.BottomRight)]
2013-11-17 22:30:47 +13:00
public ContentAlignment Placement { get ; set ; }
private Point offset ;
2013-11-11 13:48:31 +13:00
2013-11-16 22:50:08 +13:00
[DefaultValue(typeof(Point), "5, 5")]
2013-11-17 22:30:47 +13:00
public Point Offset
{
get
{
return offset ;
}
set
{
offset = new Point ( value . X . Min ( 0 ) , value . Y . Min ( 0 ) ) ;
}
}
2013-11-11 13:48:31 +13:00
2014-10-25 06:36:06 +13:00
[DefaultValue(true), Description("If text watermark size bigger than source image then don't draw it.")]
2013-11-11 13:48:31 +13:00
public bool AutoHide { get ; set ; }
2018-04-14 22:36:37 +12:00
[DefaultValue("Text watermark"), Editor(typeof(NameParserEditor), typeof(UITypeEditor))]
2013-11-11 13:48:31 +13:00
public string Text { get ; set ; }
2013-11-12 12:32:16 +13:00
private FontSafe textFontSafe = new FontSafe ( ) ;
// Workaround for "System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
2014-09-29 18:46:41 +13:00
[DefaultValue(typeof(Font), "Arial, 11.25pt")]
2013-11-12 12:32:16 +13:00
public Font TextFont
{
get
{
return textFontSafe . GetFont ( ) ;
}
set
{
using ( value )
{
textFontSafe . SetFont ( value ) ;
}
}
}
2013-11-11 13:48:31 +13:00
[DefaultValue(typeof(Color), "White"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
public Color TextColor { get ; set ; }
2013-11-26 08:34:44 +13:00
[DefaultValue(true)]
public bool DrawTextShadow { get ; set ; }
[DefaultValue(typeof(Color), "Black"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
public Color TextShadowColor { get ; set ; }
[DefaultValue(typeof(Point), "-1, -1")]
public Point TextShadowOffset { get ; set ; }
2013-11-17 22:30:47 +13:00
private int cornerRadius ;
2013-11-17 04:16:09 +13:00
2013-11-11 13:48:31 +13:00
[DefaultValue(4)]
2013-11-17 04:16:09 +13:00
public int CornerRadius
{
get
{
return cornerRadius ;
}
set
{
cornerRadius = value . Min ( 0 ) ;
}
}
2013-11-11 13:48:31 +13:00
2017-07-26 18:20:37 +12:00
[DefaultValue(typeof(Padding), "5, 5, 5, 5")]
public Padding Padding { get ; set ; }
2015-01-01 01:50:42 +13:00
[DefaultValue(true)]
public bool DrawBorder { get ; set ; }
2013-11-11 13:48:31 +13:00
[DefaultValue(typeof(Color), "Black"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
public Color BorderColor { get ; set ; }
2017-07-26 18:20:37 +12:00
[DefaultValue(1)]
public int BorderSize { get ; set ; }
2015-01-01 01:50:42 +13:00
[DefaultValue(true)]
public bool DrawBackground { get ; set ; }
2013-11-17 22:30:47 +13:00
[DefaultValue(typeof(Color), "10, 110, 230"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
2013-11-11 13:48:31 +13:00
public Color BackgroundColor { get ; set ; }
[DefaultValue(true)]
public bool UseGradient { get ; set ; }
2014-09-08 18:40:04 +12:00
[DefaultValue(LinearGradientMode.Vertical)]
public LinearGradientMode GradientType { get ; set ; }
2018-04-14 22:36:37 +12:00
[DefaultValue(typeof(Color), "0, 30, 80"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
2013-11-11 13:48:31 +13:00
public Color BackgroundColor2 { get ; set ; }
2014-08-04 12:49:24 +12:00
[DefaultValue(false)]
2013-11-13 15:54:29 +13:00
public bool UseCustomGradient { get ; set ; }
2014-09-08 18:40:04 +12:00
[Editor(typeof(GradientEditor), typeof(UITypeEditor))]
public GradientInfo Gradient { get ; set ; }
2013-11-11 13:48:31 +13:00
public DrawText ( )
{
this . ApplyDefaultPropertyValues ( ) ;
2014-09-16 18:32:28 +12:00
AddDefaultGradient ( ) ;
}
2014-09-08 18:40:04 +12:00
2014-09-16 18:32:28 +12:00
private void AddDefaultGradient ( )
{
2014-09-08 18:40:04 +12:00
Gradient = new GradientInfo ( ) ;
Gradient . Colors . Add ( new GradientStop ( Color . FromArgb ( 68 , 120 , 194 ) , 0f ) ) ;
Gradient . Colors . Add ( new GradientStop ( Color . FromArgb ( 13 , 58 , 122 ) , 50f ) ) ;
Gradient . Colors . Add ( new GradientStop ( Color . FromArgb ( 6 , 36 , 78 ) , 50f ) ) ;
2014-09-16 18:32:28 +12:00
Gradient . Colors . Add ( new GradientStop ( Color . FromArgb ( 23 , 89 , 174 ) , 100f ) ) ;
2013-11-11 13:48:31 +13:00
}
public override Image Apply ( Image img )
{
2013-11-12 12:32:16 +13:00
if ( string . IsNullOrEmpty ( Text ) )
2013-11-11 19:28:23 +13:00
{
return img ;
}
2013-11-12 12:32:16 +13:00
using ( Font textFont = TextFont )
2013-11-11 13:48:31 +13:00
{
2013-11-12 12:32:16 +13:00
if ( textFont = = null | | textFont . Size < 1 )
{
return img ;
}
2013-11-11 13:48:31 +13:00
2016-04-05 01:12:09 +12:00
NameParser parser = new NameParser ( NameParserType . Text ) ;
if ( img ! = null )
{
parser . ImageWidth = img . Width ;
parser . ImageHeight = img . Height ;
}
2013-11-12 12:32:16 +13:00
string parsedText = parser . Parse ( Text ) ;
2013-11-11 13:48:31 +13:00
2013-11-13 14:29:20 +13:00
Size textSize = Helpers . MeasureText ( parsedText , textFont ) ;
2017-07-26 18:20:37 +12:00
Size watermarkSize = new Size ( Padding . Left + textSize . Width + Padding . Right , Padding . Top + textSize . Height + Padding . Bottom ) ;
2013-11-17 22:30:47 +13:00
Point watermarkPosition = Helpers . GetPosition ( Placement , Offset , img . Size , watermarkSize ) ;
2013-11-17 20:26:41 +13:00
Rectangle watermarkRectangle = new Rectangle ( watermarkPosition , watermarkSize ) ;
2013-11-11 13:48:31 +13:00
2013-11-17 20:26:41 +13:00
if ( AutoHide & & ! new Rectangle ( 0 , 0 , img . Width , img . Height ) . Contains ( watermarkRectangle ) )
2013-11-11 13:48:31 +13:00
{
2013-11-12 12:32:16 +13:00
return img ;
}
2013-11-11 13:48:31 +13:00
2015-01-01 02:32:48 +13:00
using ( Graphics g = Graphics . FromImage ( img ) )
2013-11-12 12:32:16 +13:00
{
2017-07-26 18:20:37 +12:00
g . SmoothingMode = SmoothingMode . HighQuality ;
2013-11-11 13:48:31 +13:00
2015-01-02 22:57:16 +13:00
using ( GraphicsPath gp = new GraphicsPath ( ) )
2013-11-12 12:32:16 +13:00
{
2016-08-09 06:59:09 +12:00
gp . AddRoundedRectangleProper ( watermarkRectangle , CornerRadius ) ;
2013-11-12 12:32:16 +13:00
2015-01-02 22:57:16 +13:00
if ( DrawBackground )
2014-07-20 08:08:45 +12:00
{
2015-01-02 22:57:16 +13:00
Brush backgroundBrush = null ;
try
2014-09-08 18:40:04 +12:00
{
2015-01-02 22:57:16 +13:00
if ( UseGradient )
2014-12-01 01:23:31 +13:00
{
2015-01-02 22:57:16 +13:00
if ( UseCustomGradient & & Gradient ! = null & & Gradient . IsValid )
{
backgroundBrush = new LinearGradientBrush ( watermarkRectangle , Color . Transparent , Color . Transparent , Gradient . Type ) ;
ColorBlend colorBlend = new ColorBlend ( ) ;
IEnumerable < GradientStop > gradient = Gradient . Colors . OrderBy ( x = > x . Location ) ;
colorBlend . Colors = gradient . Select ( x = > x . Color ) . ToArray ( ) ;
colorBlend . Positions = gradient . Select ( x = > x . Location / 100 ) . ToArray ( ) ;
( ( LinearGradientBrush ) backgroundBrush ) . InterpolationColors = colorBlend ;
}
else
{
backgroundBrush = new LinearGradientBrush ( watermarkRectangle , BackgroundColor , BackgroundColor2 , GradientType ) ;
}
2014-12-01 01:23:31 +13:00
}
else
{
2015-01-02 22:57:16 +13:00
backgroundBrush = new SolidBrush ( BackgroundColor ) ;
2014-12-01 01:23:31 +13:00
}
2013-11-11 13:48:31 +13:00
2015-01-01 02:32:48 +13:00
g . FillPath ( backgroundBrush , gp ) ;
2015-01-02 22:57:16 +13:00
}
finally
{
if ( backgroundBrush ! = null ) backgroundBrush . Dispose ( ) ;
2013-11-12 12:32:16 +13:00
}
2013-11-11 13:48:31 +13:00
}
2015-01-01 02:32:48 +13:00
2015-01-02 22:57:16 +13:00
if ( DrawBorder )
2015-01-01 02:32:48 +13:00
{
2017-07-26 18:20:37 +12:00
int borderSize = BorderSize . Min ( 1 ) ;
if ( borderSize . IsEvenNumber ( ) )
{
g . PixelOffsetMode = PixelOffsetMode . Half ;
}
using ( Pen borderPen = new Pen ( BorderColor , borderSize ) )
2015-01-02 22:57:16 +13:00
{
g . DrawPath ( borderPen , gp ) ;
}
2017-07-26 18:20:37 +12:00
g . PixelOffsetMode = PixelOffsetMode . Default ;
2015-01-01 02:32:48 +13:00
}
2013-11-11 13:48:31 +13:00
}
2017-07-26 18:20:37 +12:00
if ( DrawTextShadow )
{
using ( Brush textShadowBrush = new SolidBrush ( TextShadowColor ) )
2013-11-26 08:34:44 +13:00
{
2017-07-26 18:20:37 +12:00
g . DrawString ( parsedText , textFont , textShadowBrush , watermarkRectangle . X + Padding . Left + TextShadowOffset . X ,
watermarkRectangle . Y + Padding . Top + TextShadowOffset . Y ) ;
2013-11-26 08:34:44 +13:00
}
2017-07-26 18:20:37 +12:00
}
2013-11-26 08:34:44 +13:00
2017-07-26 18:20:37 +12:00
using ( Brush textBrush = new SolidBrush ( TextColor ) )
{
g . DrawString ( parsedText , textFont , textBrush , watermarkRectangle . X + Padding . Left , watermarkRectangle . Y + Padding . Top ) ;
2013-11-12 12:32:16 +13:00
}
2013-11-11 13:48:31 +13:00
}
}
return img ;
}
}
}