diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 1095de325..49a653063 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -97,7 +97,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text this.textRenderer = new CachingGlyphRenderer(source.GetMemoryAllocator(), this.Text.Length, this.Pen, this.Brush != null); this.textRenderer.Options = (GraphicsOptions)this.Options; - TextRenderer.RenderTextTo(this.textRenderer, this.Text, style); + var renderer = new TextRenderer(this.textRenderer); + renderer.RenderText(this.Text, style); } protected override void AfterImageApply(Image source, Rectangle sourceRectangle) @@ -164,14 +165,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text private class CachingGlyphRenderer : IGlyphRenderer, IDisposable { + // just enough accuracy to allow for half pixel differences which + // later are componded into full pixel offsets while rendering. + private const float AcuracyMultiple = 2; + private PathBuilder builder; private Point currentRenderPosition = default; - private GlyphRendererParameters currentGlyphRenderParams = default; + private (GlyphRendererParameters glyph, PointF subPixelOffset) currentGlyphRenderParams = default; private int offset = 0; private PointF currentPoint = default(PointF); - private readonly Dictionary glyphData = new Dictionary(); + private readonly Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> glyphData = new Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData>(); private bool renderOutline = false; private bool renderFill = false; @@ -216,11 +221,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters paramters) { this.currentRenderPosition = Point.Truncate(bounds.Location); + PointF dif = bounds.Location - this.currentRenderPosition; + + dif.X = ((int)(dif.X * AcuracyMultiple)) / AcuracyMultiple; + dif.Y = ((int)(dif.Y * AcuracyMultiple)) / AcuracyMultiple; // we have offset our rendering origion a little bit down to prevent edge cropping, move the draw origin up to compensate this.currentRenderPosition = new Point(this.currentRenderPosition.X - this.offset, this.currentRenderPosition.Y - this.offset); - this.currentGlyphRenderParams = paramters; - if (this.glyphData.ContainsKey(paramters)) + this.currentGlyphRenderParams = (paramters, dif); + if (this.glyphData.ContainsKey(this.currentGlyphRenderParams)) { // we have already drawn the glyph vectors skip trying again this.raterizationRequired = false; @@ -252,7 +261,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text public void Dispose() { - foreach (KeyValuePair kv in this.glyphData) + foreach (KeyValuePair<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> kv in this.glyphData) { kv.Value.Dispose(); } diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs index 44bb160ce..6d7c86409 100644 --- a/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawTextOnImageTests.cs @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Text private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789"; - public static ImageComparer TextDrawingComparer = ImageComparer.TolerantPercentage(0.01f); - public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(0.5f, 3); + public static ImageComparer TextDrawingComparer = ImageComparer.Exact;//.TolerantPercentage(0.01f); + public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.Exact;// TolerantPercentage(0.5f, 3); [Theory] [WithSolidFilledImages(200, 100, "White", PixelTypes.Rgba32, 50, 0, 0, "SixLaborsSampleAB.woff", AB)] diff --git a/tests/Images/External b/tests/Images/External index c6980db77..5634b8b2a 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit c6980db777e49d5e526b56cb986001d1a191acdf +Subproject commit 5634b8b2affa1158cec31ccbb67f9583e9137234