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
Copyright ( C ) 2008 - 2013 ShareX Developers
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 )
using HelpersLib ;
2013-11-13 14:29:20 +13:00
using System ;
2013-11-13 15:54:29 +13:00
using System.Collections ;
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 ;
using System.Drawing.Text ;
using System.IO ;
2013-11-13 15:54:29 +13:00
using System.Linq ;
2013-11-11 13:48:31 +13:00
using System.Windows.Forms ;
namespace ImageEffectsLib
{
[Description("Text")]
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
[DefaultValue(false), Description("If watermark size bigger than source image then don't draw it.")]
public bool AutoHide { get ; set ; }
2013-11-13 14:29:20 +13:00
[DefaultValue("getsharex.com")]
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."
2013-11-12 15:42:10 +13:00
[DefaultValue(typeof(Font), "Arial, 10pt")]
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-11 13:48:31 +13:00
[DefaultValue(true)]
public bool DrawBackground { get ; set ; }
[DefaultValue(5)]
public int BackgroundPadding { 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
[DefaultValue(typeof(Color), "Black"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
public Color BorderColor { 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 ; }
2013-11-17 22:30:47 +13:00
[DefaultValue(typeof(Color), "0, 20, 40"), Editor(typeof(MyColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(MyColorConverter))]
2013-11-11 13:48:31 +13:00
public Color BackgroundColor2 { get ; set ; }
2013-11-13 15:54:29 +13:00
[Browsable(false), DefaultValue(false)]
public bool UseCustomGradient { get ; set ; }
2013-11-17 02:24:03 +13:00
// Need custom editor
2013-11-13 15:54:29 +13:00
[Browsable(false)]
public List < GradientStop > CustomGradientList { get ; set ; }
2013-11-11 13:48:31 +13:00
[DefaultValue(LinearGradientMode.Vertical)]
public LinearGradientMode GradientType { get ; set ; }
public DrawText ( )
{
this . ApplyDefaultPropertyValues ( ) ;
}
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
2013-11-12 12:32:16 +13:00
NameParser parser = new NameParser ( NameParserType . Text ) { Picture = img } ;
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 ) ;
Size watermarkSize = new Size ( textSize . Width + BackgroundPadding * 2 , textSize . Height + BackgroundPadding * 2 ) ;
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
2013-11-13 14:29:20 +13:00
using ( Bitmap bmpWatermark = new Bitmap ( watermarkSize . Width , watermarkSize . Height ) )
using ( Graphics gWatermark = Graphics . FromImage ( bmpWatermark ) )
2013-11-12 12:32:16 +13:00
{
2013-11-13 14:29:20 +13:00
gWatermark . SetHighQuality ( ) ;
2013-11-11 13:48:31 +13:00
2013-11-12 12:32:16 +13:00
if ( DrawBackground )
{
2013-11-13 14:29:20 +13:00
using ( GraphicsPath backgroundPath = new GraphicsPath ( ) )
2013-11-11 13:48:31 +13:00
{
2013-11-13 14:29:20 +13:00
Rectangle backgroundRect = new Rectangle ( 0 , 0 , watermarkSize . Width , watermarkSize . Height ) ;
backgroundPath . AddRoundedRectangle ( backgroundRect , CornerRadius ) ;
2013-11-12 12:32:16 +13:00
Brush backgroundBrush = null ;
try
2013-11-11 13:48:31 +13:00
{
2013-11-12 12:32:16 +13:00
if ( UseGradient )
{
2013-11-13 14:29:20 +13:00
backgroundBrush = new LinearGradientBrush ( backgroundRect , BackgroundColor , BackgroundColor2 , GradientType ) ;
2013-11-13 15:54:29 +13:00
if ( UseCustomGradient & & CustomGradientList ! = null & & CustomGradientList . Count > 1 )
{
ColorBlend colorBlend = new ColorBlend ( ) ;
IEnumerable < GradientStop > gradient = CustomGradientList . OrderBy ( x = > x . Offset ) ;
colorBlend . Colors = gradient . Select ( x = > x . Color ) . ToArray ( ) ;
colorBlend . Positions = gradient . Select ( x = > x . Offset ) . ToArray ( ) ;
( ( LinearGradientBrush ) backgroundBrush ) . InterpolationColors = colorBlend ;
}
2013-11-12 12:32:16 +13:00
}
else
{
backgroundBrush = new SolidBrush ( BackgroundColor ) ;
}
2013-11-13 14:29:20 +13:00
gWatermark . FillPath ( backgroundBrush , backgroundPath ) ;
2013-11-11 13:48:31 +13:00
}
2013-11-12 12:32:16 +13:00
finally
2013-11-11 13:48:31 +13:00
{
2013-11-12 12:32:16 +13:00
if ( backgroundBrush ! = null ) backgroundBrush . Dispose ( ) ;
2013-11-11 13:48:31 +13:00
}
2013-11-12 12:32:16 +13:00
using ( Pen borderPen = new Pen ( BorderColor ) )
{
2013-11-13 14:29:20 +13:00
gWatermark . DrawPath ( borderPen , backgroundPath ) ;
2013-11-12 12:32:16 +13:00
}
2013-11-11 13:48:31 +13:00
}
}
2013-11-13 14:29:20 +13:00
gWatermark . TextRenderingHint = TextRenderingHint . AntiAliasGridFit ;
2013-11-12 12:32:16 +13:00
using ( StringFormat sf = new StringFormat { Alignment = StringAlignment . Center , LineAlignment = StringAlignment . Center } )
{
2013-11-26 08:34:44 +13:00
float centerX = bmpWatermark . Width / 2f ;
float centerY = bmpWatermark . Height / 2f ;
if ( DrawTextShadow )
{
using ( Brush textShadowBrush = new SolidBrush ( TextShadowColor ) )
{
gWatermark . DrawString ( parsedText , textFont , textShadowBrush ,
centerX + TextShadowOffset . X , centerY + TextShadowOffset . Y , sf ) ;
}
}
using ( Brush textBrush = new SolidBrush ( TextColor ) )
{
gWatermark . DrawString ( parsedText , textFont , textBrush , centerX , centerY , sf ) ;
}
2013-11-12 12:32:16 +13:00
}
2013-11-11 13:48:31 +13:00
2013-11-13 14:29:20 +13:00
using ( Graphics gResult = Graphics . FromImage ( img ) )
2013-11-12 12:32:16 +13:00
{
2013-11-13 14:29:20 +13:00
gResult . SetHighQuality ( ) ;
2013-11-17 20:26:41 +13:00
gResult . DrawImage ( bmpWatermark , watermarkRectangle ) ;
2013-11-12 12:32:16 +13:00
}
2013-11-11 13:48:31 +13:00
}
}
return img ;
}
}
}