using Rozpisky.Rendering; using SkiaSharp; using Xunit; namespace Rozpisky.Tests; /// /// Skutečný render Skií (ne jen zplošťení obrysu): plná kružnice tvořená jedinou obloukovou /// hranou (sweep 360°) se musí vykreslit, ne „propadnout" degenerovaným ArcTo. /// public class SkiaRenderTesty { /// Vykreslí kresbu na 200×200 px bitmapu (mm 1:1, střed plátna = mm (0,0)) a vrátí /// počet nebílých pixelů. private static int PocetVyplnenych(Action draw) { const int S = 200; using var bmp = new SKBitmap(S, S); using var canvas = new SKCanvas(bmp); canvas.Clear(SKColors.White); SKPoint Map(double x, double y) => new((float)(S / 2 + x * 10), (float)(S / 2 - y * 10)); // 10 px/mm, Y nahoru using (var r = new SkiaProfileRenderer(canvas, Map, pxPerMm: 10)) draw(r); int n = 0; for (int y = 0; y < S; y++) for (int x = 0; x < S; x++) if (bmp.GetPixel(x, y) != SKColors.White) n++; return n; } [Fact] public void PlnaKruznice_JakoJednaObloukovaHrana_SeVyplni() { // Kruh r=5 mm ze středu (0,0), jediná Arc hrana se sweepem 360°. var edge = Edge.Arc(5, 0, 5, 0, 0, 0, r: 5, a0: 0, sweep: 2 * Math.PI); var contour = new Contour(new[] { edge }, Closed: true); int filled = PocetVyplnenych(g => { g.Layer("0", 0); g.Fill(new[] { contour }); }); // Plocha kruhu r=5 mm × (10 px/mm)² = π·2500 ≈ 7854 px; tolerantně > 5000. Assert.True(filled > 5000, $"plná kružnice se nevykreslila (vyplněno {filled} px)"); } [Fact] public void ObloukovyOblouk_SeVykresli_Stroke() { // Kontrolní: běžný oblouk (< 360°) přes Stroke musí něco nakreslit. var edge = Edge.Arc(5, 0, 0, 5, 0, 0, r: 5, a0: 0, sweep: Math.PI / 2); int filled = PocetVyplnenych(g => { g.Layer("0", 0); g.Stroke(new Contour(new[] { edge }, Closed: false)); }); Assert.True(filled > 50, $"oblouk se nevykreslil (vyplněno {filled} px)"); } }