using Rozpisky.Dxf;
using Rozpisky.Rendering;
using Xunit;
namespace Rozpisky.Tests;
///
/// Šrafy se vzorem. Logo md_sfdi.dxf má 3× vzor ANSI31 (šikmé čáry); dřív se každá
/// šrafa kreslila jako plná výplň, takže z něj byl v náhledu, PNG, PDF i DXF černý blok.
///
public class SrafaVzorTesty
{
private static RecordingRenderer Prehraj(string logo)
{
var g = new RecordingRenderer();
new DxfTemplate(TestData.Logo(logo)).Replay(g);
return g;
}
[Fact]
public void Ansi31SeRozvineNaCary()
{
var g = Prehraj("md_sfdi.dxf");
var vzorovane = g.Vyplne.Where(v => !v.JeSolid).ToList();
Assert.Equal(3, vzorovane.Count);
foreach (var v in vzorovane)
{
Assert.Equal("ANSI31", v.Vzor);
Assert.NotNull(v.Cary);
Assert.NotEmpty(v.Cary!);
}
}
[Fact]
public void CaryLeziUvnitrObrysuSrafy()
{
var g = Prehraj("md_sfdi.dxf");
for (int i = 0; i < g.Vyplne.Count; i++)
{
if (g.Vyplne[i].JeSolid) continue;
var (minX, minY, maxX, maxY) = Bbox(g.Fills[i]);
foreach (var u in g.Vyplne[i].Cary!)
{
Assert.InRange(u.X1, minX - 0.01, maxX + 0.01);
Assert.InRange(u.Y1, minY - 0.01, maxY + 0.01);
Assert.InRange(u.X2, minX - 0.01, maxX + 0.01);
Assert.InRange(u.Y2, minY - 0.01, maxY + 0.01);
}
}
}
[Fact]
public void CaryAnsi31JsouRovnobezneA45Stupnu()
{
var g = Prehraj("md_sfdi.dxf");
var cary = g.Vyplne.Where(v => !v.JeSolid).SelectMany(v => v.Cary!).ToList();
Assert.NotEmpty(cary);
foreach (var u in cary)
{
double dx = u.X2 - u.X1, dy = u.Y2 - u.Y1;
if (Math.Abs(dx) + Math.Abs(dy) < 1e-9) continue;
// ANSI31 je 45° (v tomhle logu 45,007° – tak to má zapsané zdroj).
double uhel = Math.Atan2(dy, dx) * 180 / Math.PI;
Assert.InRange(uhel, 44.9, 45.1);
}
}
[Fact]
public void PlnaSrafaZustavaPlna()
{
// Ostatní loga mají výhradně SOLID – nesmí se z nich stát čárová šrafa.
var g = Prehraj("exprojekt.dxf");
Assert.NotEmpty(g.Vyplne);
Assert.All(g.Vyplne, v =>
{
Assert.True(v.JeSolid);
Assert.Null(v.Cary);
});
}
[Fact]
public void VychoziVyplnJePlna()
{
// Pojistka: `default(Vypln)` musí být plná výplň, jinak by volání Fill(loops) bez
// druhého parametru přestalo cokoli kreslit.
Assert.True(default(Vypln).JeSolid);
}
[Fact]
public void BezDefiniceVzoruSeNevrationZadneCary()
{
var ctverec = new[]
{
new Contour(new[]
{
Edge.Line(0, 0, 10, 0), Edge.Line(10, 0, 10, 10),
Edge.Line(10, 10, 0, 10), Edge.Line(0, 10, 0, 0),
}, Closed: true),
};
Assert.Empty(SrafaVzor.Cary(null, ctverec));
}
private static (double MinX, double MinY, double MaxX, double MaxY) Bbox(
IReadOnlyList> smycky)
{
double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue;
foreach (var s in smycky)
foreach (var (x, y) in s)
{
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
return (minX, minY, maxX, maxY);
}
}