diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
index 9fb0e1e8da..15b7df2a22 100644
--- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
+++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
@@ -39,8 +39,8 @@
All
-
-
+
+
..\..\ImageSharp.ruleset
diff --git a/src/ImageSharp.Drawing/Text/DrawText.cs b/src/ImageSharp.Drawing/Text/DrawText.cs
index 876d17aca0..1e87fd0084 100644
--- a/src/ImageSharp.Drawing/Text/DrawText.cs
+++ b/src/ImageSharp.Drawing/Text/DrawText.cs
@@ -181,7 +181,8 @@ namespace ImageSharp
{
ApplyKerning = options.ApplyKerning,
TabWidth = options.TabWidth,
- WrappingWidth = options.WrapTextWidth
+ WrappingWidth = options.WrapTextWidth,
+ Alignment = options.TextAlignment
};
renderer.RenderText(text, style);
diff --git a/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs b/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs
index 6b09f23951..388b39bcc5 100644
--- a/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs
+++ b/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs
@@ -2,9 +2,11 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
-
namespace ImageSharp.Drawing
{
+ using ImageSharp.PixelFormats;
+ using SixLabors.Fonts;
+
///
/// Options for influencing the drawing functions.
///
@@ -15,50 +17,94 @@ namespace ImageSharp.Drawing
///
public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true);
+ private float? blendPercentage;
+
+ private int? antialiasSubpixelDepth;
+
+ private bool? antialias;
+
+ private bool? applyKerning;
+
+ private float? tabWidth;
+
+ private PixelBlenderMode blenderMode;
+
+ private bool? useImageResolution;
+
+ private float wrapTextWidth;
+
+ private SixLabors.Fonts.TextAlignment? textAlignment;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// If set to true [enable antialiasing].
+ public TextGraphicsOptions(bool enableAntialiasing)
+ {
+ this.applyKerning = true;
+ this.tabWidth = 4;
+ this.useImageResolution = false;
+ this.wrapTextWidth = 0;
+ this.textAlignment = SixLabors.Fonts.TextAlignment.Left;
+
+ this.antialiasSubpixelDepth = 16;
+ this.blenderMode = PixelBlenderMode.Normal;
+ this.blendPercentage = 1;
+ this.antialias = enableAntialiasing;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether antialiasing should be applied.
+ ///
+ public bool Antialias { get => this.antialias ?? true; set => this.antialias = value; }
+
+ ///
+ /// Gets or sets a value indicating the number of subpixels to use while rendering with antialiasing enabled.
+ ///
+ public int AntialiasSubpixelDepth { get => this.antialiasSubpixelDepth ?? 16; set => this.antialiasSubpixelDepth = value; }
+
///
- /// Whether antialiasing should be applied.
+ /// Gets or sets a value indicating the blending percentage to apply to the drawing operation
///
- public bool Antialias;
+ public float BlendPercentage { get => (this.blendPercentage ?? 1).Clamp(0, 1); set => this.blendPercentage = value; }
+
+ // In the future we could expose a PixelBlender directly on here
+ // or some forms of PixelBlender factory for each pixel type. Will need
+ // some API thought post V1.
///
- /// The number of subpixels to use while rendering with antialiasing enabled.
+ /// Gets or sets a value indicating the blending percentage to apply to the drawing operation
///
- public int AntialiasSubpixelDepth;
+ public PixelBlenderMode BlenderMode { get => this.blenderMode; set => this.blenderMode = value; }
///
- /// Whether the text should be drawing with kerning enabled.
+ /// Gets or sets a value indicating whether the text should be drawing with kerning enabled.
///
- public bool ApplyKerning;
+ public bool ApplyKerning { get => this.applyKerning ?? true; set => this.applyKerning = value; }
///
- /// The number of space widths a tab should lock to.
+ /// Gets or sets a value indicating the number of space widths a tab should lock to.
///
- public float TabWidth;
+ public float TabWidth { get => this.tabWidth ?? 4; set => this.tabWidth = value; }
///
- /// Flag weather to use the current image resultion to for point size scaling.
+ /// Gets or sets a value indicating whether to use the current image resultion to for point size scaling.
/// If this is [false] the text renders at 72dpi otherwise it renders at Image resolution
///
- public bool UseImageResolution;
+ public bool UseImageResolution { get => this.useImageResolution ?? false; set => this.useImageResolution = value; }
///
- /// If greater than zero determine the width at which text should wrap.
+ /// Gets or sets a value indicating if greater than zero determine the width at which text should wrap.
///
- public float WrapTextWidth;
+ public float WrapTextWidth { get => this.wrapTextWidth; set => this.wrapTextWidth = value; }
///
- /// Initializes a new instance of the struct.
+ /// Gets or sets a value indicating how to align the text relative to the rendering space.
+ /// If is greater than zero it will align relative to the space
+ /// defined by the location and width, if equals zero, and thus
+ /// wrapping disabled, then the alignment is relative to the drawing location.
///
- /// If set to true [enable antialiasing].
- public TextGraphicsOptions(bool enableAntialiasing)
- {
- this.Antialias = enableAntialiasing;
- this.ApplyKerning = true;
- this.TabWidth = 4;
- this.AntialiasSubpixelDepth = 16;
- this.UseImageResolution = false;
- this.WrapTextWidth = 0;
- }
+ public TextAlignment TextAlignment { get => this.textAlignment ?? TextAlignment.Left; set => this.textAlignment = value; }
///
/// Performs an implicit conversion from to .
@@ -71,7 +117,9 @@ namespace ImageSharp.Drawing
{
return new TextGraphicsOptions(options.Antialias)
{
- AntialiasSubpixelDepth = options.AntialiasSubpixelDepth
+ AntialiasSubpixelDepth = options.AntialiasSubpixelDepth,
+ blendPercentage = options.BlendPercentage,
+ blenderMode = options.BlenderMode
};
}
@@ -86,7 +134,9 @@ namespace ImageSharp.Drawing
{
return new GraphicsOptions(options.Antialias)
{
- AntialiasSubpixelDepth = options.AntialiasSubpixelDepth
+ AntialiasSubpixelDepth = options.AntialiasSubpixelDepth,
+ BlenderMode = options.BlenderMode,
+ BlendPercentage = options.BlendPercentage
};
}
}
diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs
index bc6a11955c..cff9fc04e0 100644
--- a/src/ImageSharp/Common/Helpers/ImageMaths.cs
+++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs
@@ -182,7 +182,7 @@ namespace ImageSharp
break;
}
- Func, int> getMinY = pixels =>
+ int GetMinY(PixelAccessor pixels)
{
for (int y = 0; y < height; y++)
{
@@ -196,9 +196,9 @@ namespace ImageSharp
}
return 0;
- };
+ }
- Func, int> getMaxY = pixels =>
+ int GetMaxY(PixelAccessor pixels)
{
for (int y = height - 1; y > -1; y--)
{
@@ -212,9 +212,9 @@ namespace ImageSharp
}
return height;
- };
+ }
- Func, int> getMinX = pixels =>
+ int GetMinX(PixelAccessor pixels)
{
for (int x = 0; x < width; x++)
{
@@ -228,9 +228,9 @@ namespace ImageSharp
}
return 0;
- };
+ }
- Func, int> getMaxX = pixels =>
+ int GetMaxX(PixelAccessor pixels)
{
for (int x = width - 1; x > -1; x--)
{
@@ -244,14 +244,14 @@ namespace ImageSharp
}
return height;
- };
+ }
using (PixelAccessor bitmapPixels = bitmap.Lock())
{
- topLeft.Y = getMinY(bitmapPixels);
- topLeft.X = getMinX(bitmapPixels);
- bottomRight.Y = (getMaxY(bitmapPixels) + 1).Clamp(0, height);
- bottomRight.X = (getMaxX(bitmapPixels) + 1).Clamp(0, width);
+ topLeft.Y = GetMinY(bitmapPixels);
+ topLeft.X = GetMinX(bitmapPixels);
+ bottomRight.Y = (GetMaxY(bitmapPixels) + 1).Clamp(0, height);
+ bottomRight.X = (GetMaxX(bitmapPixels) + 1).Clamp(0, width);
}
return GetBoundingRectangle(topLeft, bottomRight);
diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs
index 5a6eebf405..ac2627701f 100644
--- a/src/ImageSharp/PixelFormats/Alpha8.cs
+++ b/src/ImageSharp/PixelFormats/Alpha8.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing a single 8 bit normalized W values.
+ ///
/// Ranges from <0, 0, 0, 0> to <0, 0, 0, 1> in vector form.
+ ///
///
public struct Alpha8 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs
index 2798c4c5ad..61e860aeee 100644
--- a/src/ImageSharp/PixelFormats/Argb32.cs
+++ b/src/ImageSharp/PixelFormats/Argb32.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in alpha, red, green, and blue order.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
///
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs
index 78442a3cef..813b6fe857 100644
--- a/src/ImageSharp/PixelFormats/Bgr565.cs
+++ b/src/ImageSharp/PixelFormats/Bgr565.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing unsigned normalized values ranging from 0 to 1. The x and z components use 5 bits, and the y component uses 6 bits.
+ ///
/// Ranges from <0, 0, 0, 1> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Bgr565 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs
index 9138e25ca5..8fb2d0c260 100644
--- a/src/ImageSharp/PixelFormats/Bgra4444.cs
+++ b/src/ImageSharp/PixelFormats/Bgra4444.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing unsigned normalized values, ranging from 0 to 1, using 4 bits each for x, y, z, and w.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Bgra4444 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs
index 9ff571243e..26cfa6b8c0 100644
--- a/src/ImageSharp/PixelFormats/Bgra5551.cs
+++ b/src/ImageSharp/PixelFormats/Bgra5551.cs
@@ -11,6 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing unsigned normalized values ranging from 0 to 1. The x , y and z components use 5 bits, and the w component uses 1 bit.
+ ///
+ /// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Bgra5551 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs
index b27952ce4d..951b7c3cb5 100644
--- a/src/ImageSharp/PixelFormats/Byte4.cs
+++ b/src/ImageSharp/PixelFormats/Byte4.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 8-bit unsigned integer values, ranging from 0 to 255.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Byte4 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs
index 2a686f5356..e9f02d34eb 100644
--- a/src/ImageSharp/PixelFormats/HalfSingle.cs
+++ b/src/ImageSharp/PixelFormats/HalfSingle.cs
@@ -10,7 +10,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing a single 16 bit floating point value.
+ ///
/// Ranges from <0, 0, 0, 1> to <1, 0, 0, 1> in vector form.
+ ///
///
public struct HalfSingle : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs
index ef9676b562..8813fd455f 100644
--- a/src/ImageSharp/PixelFormats/HalfVector2.cs
+++ b/src/ImageSharp/PixelFormats/HalfVector2.cs
@@ -10,7 +10,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing two 16-bit floating-point values.
+ ///
/// Ranges from <0, 0, 0, 1> to <1, 0, 0, 1> in vector form.
+ ///
///
public struct HalfVector2 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs
index 8b284509f7..e8c78047ea 100644
--- a/src/ImageSharp/PixelFormats/HalfVector4.cs
+++ b/src/ImageSharp/PixelFormats/HalfVector4.cs
@@ -10,7 +10,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 16-bit floating-point values.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct HalfVector4 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs
index c5b6eff6bb..93226342ed 100644
--- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed packed pixel type containing two 8-bit signed normalized values, ranging from −1 to 1.
+ ///
/// Ranges from <-1, -1, 0, 1> to <1, 1, 0, 1> in vector form.
+ ///
///
public struct NormalizedByte2 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs
index 9e36766601..66a79fefc6 100644
--- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 8-bit signed normalized values, ranging from −1 to 1.
+ ///
/// Ranges from <-1, -1, -1, -1> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct NormalizedByte4 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs
index 01a2d99547..99e5a98c00 100644
--- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs
@@ -10,7 +10,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing two 16-bit signed normalized values, ranging from −1 to 1.
+ ///
/// Ranges from <-1, -1, 0, 1> to <1, 1, 0, 1> in vector form.
+ ///
///
public struct NormalizedShort2 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs
index 3e4535fdf1..932ab97cf8 100644
--- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs
@@ -10,7 +10,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 16-bit signed normalized values, ranging from −1 to 1.
+ ///
/// Ranges from <-1, -1, -1, -1> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct NormalizedShort4 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs
index 4d1f0fecfd..3e23777f68 100644
--- a/src/ImageSharp/PixelFormats/Rg32.cs
+++ b/src/ImageSharp/PixelFormats/Rg32.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing two 16-bit unsigned normalized values ranging from 0 to 1.
+ ///
/// Ranges from <0, 0, 0, 1> to <1, 1, 0, 1> in vector form.
+ ///
///
public struct Rg32 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs
index 96f7af7732..747112fd80 100644
--- a/src/ImageSharp/PixelFormats/Rgba1010102.cs
+++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs
@@ -12,7 +12,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed vector type containing unsigned normalized values ranging from 0 to 1.
/// The x, y and z components use 10 bits, and the w component uses 2 bits.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Rgba1010102 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs
index 31eae8abe5..f58150e2e0 100644
--- a/src/ImageSharp/PixelFormats/Rgba32.cs
+++ b/src/ImageSharp/PixelFormats/Rgba32.cs
@@ -14,7 +14,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in red, green, blue, and alpha order.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
///
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs
index b7ff143a95..296c17a4e1 100644
--- a/src/ImageSharp/PixelFormats/Rgba64.cs
+++ b/src/ImageSharp/PixelFormats/Rgba64.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 16-bit unsigned normalized values ranging from 0 to 1.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
public struct Rgba64 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs
index 25eaa97117..a92b794efb 100644
--- a/src/ImageSharp/PixelFormats/RgbaVector.cs
+++ b/src/ImageSharp/PixelFormats/RgbaVector.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Unpacked pixel type containing four 16-bit floating-point values typically ranging from 0 to 1.
/// The color components are stored in red, green, blue, and alpha order.
+ ///
/// Ranges from <0, 0, 0, 0> to <1, 1, 1, 1> in vector form.
+ ///
///
///
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs
index d681e27b78..6c871ecb67 100644
--- a/src/ImageSharp/PixelFormats/Short2.cs
+++ b/src/ImageSharp/PixelFormats/Short2.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing two 16-bit signed integer values.
+ ///
/// Ranges from <-32767, -32767, 0, 1> to <32767, 32767, 0, 1> in vector form.
+ ///
///
public struct Short2 : IPixel, IPackedVector
{
diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs
index f58949a720..de110c7d3b 100644
--- a/src/ImageSharp/PixelFormats/Short4.cs
+++ b/src/ImageSharp/PixelFormats/Short4.cs
@@ -11,7 +11,9 @@ namespace ImageSharp.PixelFormats
///
/// Packed pixel type containing four 16-bit signed integer values.
+ ///
/// Ranges from <-37267, -37267, -37267, -37267> to <37267, 37267, 37267, 37267> in vector form.
+ ///
///
public struct Short4 : IPixel, IPackedVector
{