diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 990564152..4c3a36ae3 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -23,7 +23,7 @@ jobs:
sdk-preview: true
runtime: -x64
codecov: false
- - os: macos-latest
+ - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net7.0
sdk: 7.0.x
sdk-preview: true
@@ -46,7 +46,7 @@ jobs:
sdk: 6.0.x
runtime: -x64
codecov: false
- - os: macos-latest
+ - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net6.0
sdk: 6.0.x
runtime: -x64
diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
index 68619e1ca..44e9ed380 100644
--- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
+++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
@@ -45,8 +45,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/RichTextGlyphRenderer.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/RichTextGlyphRenderer.cs
index b937e84a2..985a3f2f1 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Text/RichTextGlyphRenderer.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Text/RichTextGlyphRenderer.cs
@@ -367,9 +367,10 @@ protected override void EndGlyph()
if (renderData.OutlineMap != null)
{
+ int offset = (int)((this.currentPen?.StrokeWidth ?? 0) / 2);
this.DrawingOperations.Add(new DrawingOperation
{
- RenderLocation = renderLocation,
+ RenderLocation = renderLocation - new Size(offset, offset),
Map = renderData.OutlineMap,
Brush = this.currentPen?.StrokeFill ?? this.currentBrush!,
RenderPass = RenderOrderOutline
diff --git a/src/ImageSharp.Drawing/Processing/RichTextOptions.cs b/src/ImageSharp.Drawing/Processing/RichTextOptions.cs
index 21d239036..e547e4bb9 100644
--- a/src/ImageSharp.Drawing/Processing/RichTextOptions.cs
+++ b/src/ImageSharp.Drawing/Processing/RichTextOptions.cs
@@ -16,8 +16,7 @@ public class RichTextOptions : TextOptions
/// The font.
public RichTextOptions(Font font)
: base(font)
- {
- }
+ => this.TextRuns = Array.Empty();
///
/// Initializes a new instance of the class from properties
diff --git a/tests/ImageSharp.Drawing.Tests/Issues/Issue_330.cs b/tests/ImageSharp.Drawing.Tests/Issues/Issue_330.cs
new file mode 100644
index 000000000..fa2f57fbc
--- /dev/null
+++ b/tests/ImageSharp.Drawing.Tests/Issues/Issue_330.cs
@@ -0,0 +1,68 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SixLabors.Fonts;
+using SixLabors.ImageSharp.Drawing.Processing;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Drawing.Tests.Issues;
+public class Issue_330
+{
+ [Theory]
+ [WithSolidFilledImages(2084, 2084, "BlueViolet", PixelTypes.Rgba32)]
+ public void OffsetTextOutlines(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ FontFamily fontFamily = TestFontUtilities.GetFontFamily(TestFonts.OpenSans);
+
+ Font bibfont = fontFamily.CreateFont(600, FontStyle.Bold);
+ Font namefont = fontFamily.CreateFont(140, FontStyle.Bold);
+
+ provider.RunValidatingProcessorTest(p =>
+ {
+ p.DrawText(
+ new RichTextOptions(bibfont)
+ {
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ TextAlignment = TextAlignment.Center,
+ TextDirection = TextDirection.LeftToRight,
+ Origin = new Point(1156, 1024),
+ },
+ "9999",
+ Brushes.Solid(Color.White),
+ Pens.Solid(Color.Black, 20));
+
+ p.DrawText(
+ new RichTextOptions(namefont)
+ {
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ TextAlignment = TextAlignment.Center,
+ TextDirection = TextDirection.LeftToRight,
+ Origin = new Point(1156, 713),
+ },
+ "JOHAN",
+ Brushes.Solid(Color.White),
+ Pens.Solid(Color.Black, 5));
+
+ p.DrawText(
+ new RichTextOptions(namefont)
+ {
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ TextAlignment = TextAlignment.Center,
+ TextDirection = TextDirection.LeftToRight,
+ Origin = new Point(1156, 1381),
+ },
+ "TIGERTECH",
+ Brushes.Solid(Color.White),
+ Pens.Solid(Color.Black, 5));
+ });
+ }
+}
diff --git a/tests/ImageSharp.Drawing.Tests/Issues/Issue_332.cs b/tests/ImageSharp.Drawing.Tests/Issues/Issue_332.cs
new file mode 100644
index 000000000..e842afc4c
--- /dev/null
+++ b/tests/ImageSharp.Drawing.Tests/Issues/Issue_332.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.Fonts;
+using SixLabors.ImageSharp.Drawing.Processing;
+
+namespace SixLabors.ImageSharp.Drawing.Tests.Issues;
+
+public class Issue_332
+{
+ [Fact]
+ public void CanAccessEmptyRichTextRuns()
+ {
+ Font font = TestFontUtilities.GetFont(TestFonts.OpenSans, 70);
+ RichTextOptions options = new(font);
+ Assert.Empty(options.TextRuns);
+ }
+}
diff --git a/tests/ImageSharp.Drawing.Tests/TestFontUtilities.cs b/tests/ImageSharp.Drawing.Tests/TestFontUtilities.cs
index f0e20c151..699bd5500 100644
--- a/tests/ImageSharp.Drawing.Tests/TestFontUtilities.cs
+++ b/tests/ImageSharp.Drawing.Tests/TestFontUtilities.cs
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
+using System.Globalization;
using System.Reflection;
using SixLabors.Fonts;
using IOPath = System.IO.Path;
@@ -19,7 +20,15 @@ public static class TestFontUtilities
/// The font size.
/// The
public static Font GetFont(string name, float size)
- => GetFont(new FontCollection(), name, size);
+ => GetFontFamily(name).CreateFont(size);
+
+ ///
+ /// Gets a font family with the given name.
+ ///
+ /// The name of the font.
+ /// The
+ public static FontFamily GetFontFamily(string name)
+ => GetFontFamily(new FontCollection(), name);
///
/// Gets a font with the given name and size.
@@ -29,7 +38,16 @@ public static Font GetFont(string name, float size)
/// The font size.
/// The
public static Font GetFont(FontCollection collection, string name, float size)
- => collection.Add(GetPath(name)).CreateFont(size);
+ => GetFontFamily(collection, name).CreateFont(size);
+
+ ///
+ /// Gets a font family with the given name
+ ///
+ /// The collection to add the font to
+ /// The name of the font.
+ /// The
+ public static FontFamily GetFontFamily(FontCollection collection, string name)
+ => collection.Add(GetPath(name), CultureInfo.InvariantCulture);
///
/// The formats directory.
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-Quic).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-Quic).png
index 79b65427a..b3ab8340f 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-Quic).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-Quic).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9ff9565be8de6cab9694b59a0722e1749685f67a4f2e3db9f9be86390098c16f
-size 1968
+oid sha256:a519106bb39b4ec9c569fe43cb0c63ef46808c29ffb3f172b4db9a93f4faf9f4
+size 1962
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-Quic).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-Quic).png
index ed8e9ade6..bd6a20504 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-Quic).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateFilledFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-Quic).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9dc2980efa5b3ad73139d98e88f2fb0fc6f0e0a2e1153009f36de253386b773b
-size 1709
+oid sha256:bde19b36b56e7974c47c459183210589ced41b93bd9fcd0ba22b4baabaac2176
+size 1704
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-STR(1)-Quic).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-STR(1)-Quic).png
index c9df5153c..fbc985abc 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-STR(1)-Quic).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(32)-A(75)-STR(1)-Quic).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ce6a7b5ca590a8594fe215e8b15e9f22c57644df9aa5770d7434755019fdc679
-size 2608
+oid sha256:82fd62a3b4080137e31a23a4485b467b2804313fb57455017f1ef11de1d38e5e
+size 2595
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-STR(2)-Quic).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-STR(2)-Quic).png
index f326e8d75..83b223d34 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-STR(2)-Quic).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/CanRotateOutlineFont_Issue175_Solid300x200_(255,255,255,255)_F(OpenSans-Regular.ttf)-S(40)-A(90)-STR(2)-Quic).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4396a75b759dad700ae08df7549df0ab35f2ae154a948eca5bb51710490f0d83
-size 2447
+oid sha256:f9e7f3f9aabf29e053e05eb4e4f7c3114e58d6229e9539aa566e42a19a775b90
+size 2430
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FallbackFontRendering_Rgba32_Solid400x200_(255,255,255,255).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FallbackFontRendering_Rgba32_Solid400x200_(255,255,255,255).png
index 4a43cf209..0d9b5dd7f 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FallbackFontRendering_Rgba32_Solid400x200_(255,255,255,255).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FallbackFontRendering_Rgba32_Solid400x200_(255,255,255,255).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:460ab85bf88b181f95fcfc5f029f826d2781aa56f6e770e676e1c7a0e0f02f11
-size 1819
+oid sha256:6fdc4f70e69b94796a45ee83c6d79c7e1d3bca364ca164fa2c9bcd38f40b2664
+size 1783
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(150,50).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(150,50).png
index c378e8e8b..ca6f4af56 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(150,50).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(150,50).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:450d4edb2b067c212705387ea6a42763464707c86d0ddd365b81c1795ad31c93
-size 17917
+oid sha256:8333f5bf72363f6cbebd69efe351d4234ae7f870b5c088991bd0a18ee855aa30
+size 33277
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB.woff-50-ABAB-(0,0).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB.woff-50-ABAB-(0,0).png
index d2f981c1b..4353698b4 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB.woff-50-ABAB-(0,0).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB.woff-50-ABAB-(0,0).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bb97d53d830d65c290158ce1bbd5eae4033727f8fe8b534b7555c4bde89c9db0
-size 1244
+oid sha256:74bc71359f75ab560474d53aa74d2e4a4d09807552020d426e6f1545b769b71b
+size 2821
diff --git a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(0,0).png b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(0,0).png
index a812816e3..da4ba2e66 100644
--- a/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(0,0).png
+++ b/tests/Images/ReferenceOutput/Drawing/Text/DrawTextOnImageTests/FontShapesAreRenderedCorrectlyWithAPenPatterned_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular.ttf-50-Sphi-(0,0).png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:65702ca76b6301fa1c4c1ecf4b07e654de1a4a59940ed156fc91d8670cf4c56a
-size 17366
+oid sha256:3ffcef97021e6572d9827ac1a128882042695bf2b3bf1e27127358d7cef994f6
+size 31488
diff --git a/tests/Images/ReferenceOutput/Issue_330/OffsetTextOutlines_Rgba32_Solid2084x2084_(138,43,226,255).png b/tests/Images/ReferenceOutput/Issue_330/OffsetTextOutlines_Rgba32_Solid2084x2084_(138,43,226,255).png
new file mode 100644
index 000000000..1dee57d4e
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Issue_330/OffsetTextOutlines_Rgba32_Solid2084x2084_(138,43,226,255).png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b44ee8f82a88b7a6d8c0c908308aac7c9d90ad22370e2942b976c06cbdf2f1b3
+size 186486