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/>
public override int ScanY(int y, float[] buffer, int length, int offset)
{
Vector2 start = new Vector2(float.MinValue, y);
Vector2 end = new Vector2(float.MaxValue, y);
Vector2 start = new Vector2(this.Bounds.Left - 1, y);
Vector2 end = new Vector2(this.Bounds.Right + 1, y);
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length);
try
{

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

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

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

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

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

@ -57,7 +57,7 @@ namespace ImageSharp.Drawing.Processors
/// <inheritdoc/>
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 polyEndY = sourceRectangle.Bottom + DrawPadding;
@ -102,6 +102,13 @@ namespace ImageSharp.Drawing.Processors
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)
{
// we seem to have just clipped a corner lets just skip it
@ -246,6 +253,13 @@ namespace ImageSharp.Drawing.Processors
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)
{
// 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 Xunit;
using ImageSharp.Drawing.Brushes;
using SixLabors.Shapes;
public class SolidPolygonTests : FileTestBase
{
@ -151,7 +152,7 @@ namespace ImageSharp.Tests.Drawing
{
image
.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);
}
@ -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