Browse Source

fixes some corner clipping issues

af/merge-core
Scott Williams 9 years ago
parent
commit
8c2a840f4d
  1. 4
      src/ImageSharp.Drawing.Paths/ShapePath.cs
  2. 4
      src/ImageSharp.Drawing.Paths/ShapeRegion.cs
  3. 2
      src/ImageSharp.Drawing.Paths/project.json
  4. 16
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  5. 76
      tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs

4
src/ImageSharp.Drawing.Paths/ShapePath.cs

@ -101,8 +101,8 @@ namespace ImageSharp.Drawing
/// <inheritdoc/> /// <inheritdoc/>
public override int ScanY(int y, float[] buffer, int length, int offset) public override int ScanY(int y, float[] buffer, int length, int offset)
{ {
Vector2 start = new Vector2(float.MinValue, y); Vector2 start = new Vector2(this.Bounds.Left - 1, y);
Vector2 end = new Vector2(float.MaxValue, y); Vector2 end = new Vector2(this.Bounds.Right + 1, y);
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length);
try try
{ {

4
src/ImageSharp.Drawing.Paths/ShapeRegion.cs

@ -81,8 +81,8 @@ namespace ImageSharp.Drawing
/// <inheritdoc/> /// <inheritdoc/>
public override int ScanY(int y, float[] buffer, int length, int offset) public override int ScanY(int y, float[] buffer, int length, int offset)
{ {
Vector2 start = new Vector2(float.MinValue, y); Vector2 start = new Vector2(this.Bounds.Left - 1, y);
Vector2 end = new Vector2(float.MaxValue, y); Vector2 end = new Vector2(this.Bounds.Right + 1, y);
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length);
try try
{ {

2
src/ImageSharp.Drawing.Paths/project.json

@ -44,7 +44,7 @@
"ImageSharp.Drawing": { "ImageSharp.Drawing": {
"target": "project" "target": "project"
}, },
"SixLabors.Shapes": "0.1.0-alpha0002", "SixLabors.Shapes": "0.1.0-alpha0003",
"StyleCop.Analyzers": { "StyleCop.Analyzers": {
"version": "1.0.0", "version": "1.0.0",
"type": "build" "type": "build"

16
src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs

@ -57,7 +57,7 @@ namespace ImageSharp.Drawing.Processors
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<TColor> source, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor> source, Rectangle sourceRectangle)
{ {
Rectangle rect = RectangleF.Ceiling(this.Region.Bounds); // rounds the points out away from the center Rectangle rect = this.Region.Bounds;
int polyStartY = sourceRectangle.Y - DrawPadding; int polyStartY = sourceRectangle.Y - DrawPadding;
int polyEndY = sourceRectangle.Bottom + DrawPadding; int polyEndY = sourceRectangle.Bottom + DrawPadding;
@ -102,6 +102,13 @@ namespace ImageSharp.Drawing.Processors
return; return;
} }
if (pointsFound == 1 && maxIntersections > 1)
{
// we must have clipped a corner lets just duplicate it into point 2 and continue :)
buffer[1] = buffer[0];
pointsFound++;
}
if (pointsFound % 2 == 1) if (pointsFound % 2 == 1)
{ {
// we seem to have just clipped a corner lets just skip it // we seem to have just clipped a corner lets just skip it
@ -246,6 +253,13 @@ namespace ImageSharp.Drawing.Processors
return; return;
} }
if (pointsFound == 1 && maxIntersections > 1)
{
// we must have clipped a corner lets just duplicate it into point 2 and continue :)
buffer[1] = buffer[0];
pointsFound++;
}
if (pointsFound % 2 == 1) if (pointsFound % 2 == 1)
{ {
// we seem to have just clipped a corner lets just skip it // we seem to have just clipped a corner lets just skip it

76
tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs

@ -13,6 +13,7 @@ namespace ImageSharp.Tests.Drawing
using System.Numerics; using System.Numerics;
using Xunit; using Xunit;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
using SixLabors.Shapes;
public class SolidPolygonTests : FileTestBase public class SolidPolygonTests : FileTestBase
{ {
@ -151,7 +152,7 @@ namespace ImageSharp.Tests.Drawing
{ {
image image
.BackgroundColor(Color.Blue) .BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new SixLabors.Shapes.Rectangle(10,10, 190, 140)) .Fill(Color.HotPink, new SixLabors.Shapes.Rectangle(10, 10, 190, 140))
.Save(output); .Save(output);
} }
@ -169,5 +170,78 @@ namespace ImageSharp.Tests.Drawing
} }
} }
} }
[Fact]
public void ImageShouldBeOverlayedByFilledTriangle()
{
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
using (Image image = new Image(100, 100))
{
using (FileStream output = File.OpenWrite($"{path}/Triangle.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new RegularPolygon(50, 50, 3, 30))
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[25, 35]);
Assert.Equal(Color.HotPink, sourcePixels[50, 79]);
Assert.Equal(Color.HotPink, sourcePixels[75, 35]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[28, 60]);
Assert.Equal(Color.Blue, sourcePixels[67, 67]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledSeptagon()
{
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
var config = Configuration.CreateDefaultInstance();
config.ParallelOptions.MaxDegreeOfParallelism = 1;
using (Image image = new Image(100, 100, config))
{
using (FileStream output = File.OpenWrite($"{path}/Septagon.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new RegularPolygon(50, 50, 7, 30, -(float)Math.PI))
.Save(output);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledEllipse()
{
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
var config = Configuration.CreateDefaultInstance();
config.ParallelOptions.MaxDegreeOfParallelism = 1;
using (Image image = new Image(100, 100, config))
{
using (FileStream output = File.OpenWrite($"{path}/ellipse.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new Ellipse(50, 50, 30, 50)
.Rotate((float)(Math.PI / 3)))
.Save(output);
}
}
}
} }
} }

Loading…
Cancel
Save