Šablona i všech 9 log jsou zapsané výhradně indexovanými barvami AutoCADu (group 62) – true color v nich není ani jednou. Kreslicí rozhraní přitom neslo jen `int rgb`, takže se index i ByLayer ztratily už při čtení a export zapisoval všechno jako natvrdo RGB (group 420). Výkres v CADu pak přestal reagovat na tabulku barev a barva hladiny se rozpadla na kopie na entitách. `IProfileRenderer.Layer(name, rgb, mm)` se mění na `Stav(in KresliciStav)`. Stav nese barvu i s původem (`Barva`: ACI index / true color / ByLayer / ByBlock), typ čáry, tloušťku a celý popis hladiny (`HladinaStav`) – hladina se ve výstupu staví z tabulky hladin, ne z první entity, která na ní přistála. Rámeček `!!NOPRINT` proto zůstane netisknutelný. Paleta ACI je vlastní (`AciPaleta`), ne z ACadSharp: ta se od AutoCADu liší u 33 indexů, mimo jiné u 8 (použitý v šabloně) a u posledního indexu většiny desítek odstínů, kde vrací barvu ze sousední skupiny – 29 a 39 tam dokonce dostanou tutéž barvu. Rozsah 10–249 se dopočítává, ne vypisuje. Co ověřují nové testy (93 zelených): - paleta proti AutoCADu i proti ACadSharp, se seznamem známých odchylek, - rozřešení ByLayer/ByBlock, tloušťky a typu čáry, - kolečko šablona → export → načtení: žádná entita není true color, indexy odpovídají zdroji, ByLayer zůstane ByLayer, hladiny mají barvu i příznak tisku ze zdrojové tabulky. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
3.4 KiB
C#
68 lines
3.4 KiB
C#
using Rozpisky.Rendering;
|
||
|
||
namespace Rozpisky.Tests;
|
||
|
||
/// <summary>
|
||
/// Testovací <see cref="IProfileRenderer"/>: nic nekreslí, jen zaznamenává volání primitiv,
|
||
/// aby testy mohly assertovat, co přesně parser (<c>DxfTemplate.Replay</c>) vyprodukoval.
|
||
/// Obrysy (<see cref="Contour"/>) se pro pohodlné assertování bboxů zaznamenávají jak analyticky
|
||
/// (<see cref="FillContours"/>, <see cref="StrokeContours"/>), tak jemně zploštěné na body
|
||
/// (<see cref="Fills"/>, <see cref="Polylines"/>) – zpětně kompatibilní s dřívějšími testy.
|
||
/// </summary>
|
||
public sealed class RecordingRenderer : IProfileRenderer
|
||
{
|
||
public sealed record TextCall(double X, double Y, string Text, double HeightMm, HAlign H, VAlign V,
|
||
double RotationDeg, TextStyle Style, double WidthFactor, double MaxWidthMm);
|
||
|
||
/// <summary>Každé volání Fill = smyčky jednoho HATCH, zploštěné na body.</summary>
|
||
public List<IReadOnlyList<IReadOnlyList<(double X, double Y)>>> Fills { get; } = new();
|
||
/// <summary>Analytické obrysy jednotlivých volání Fill (se zachovanými oblouky).</summary>
|
||
public List<IReadOnlyList<Contour>> FillContours { get; } = new();
|
||
/// <summary>Analytické obrysy z volání Stroke (bulge polylinie, samostatné oblouky).</summary>
|
||
public List<Contour> StrokeContours { get; } = new();
|
||
public List<TextCall> Texts { get; } = new();
|
||
/// <summary>Zploštěné polylinie i obrysy ze Stroke (kvůli zpětné kompatibilitě testů).</summary>
|
||
public List<IReadOnlyList<(double X, double Y)>> Polylines { get; } = new();
|
||
public int LineCount { get; private set; }
|
||
public int CircleCount { get; private set; }
|
||
|
||
/// <summary>Stavy kresby v pořadí, jak přišly – testy tak můžou tvrdit i o barvě a hladině.</summary>
|
||
public List<KresliciStav> Stavy { get; } = new();
|
||
/// <summary>Stav platný pro naposledy zaznamenanou entitu.</summary>
|
||
public KresliciStav PosledniStav => Stavy.Count > 0 ? Stavy[^1] : KresliciStav.Vychozi;
|
||
|
||
public void Stav(in KresliciStav s) => Stavy.Add(s);
|
||
|
||
public void Line(double x1, double y1, double x2, double y2) => LineCount++;
|
||
|
||
public void Polyline(IReadOnlyList<(double X, double Y)> pts, bool closed = false) => Polylines.Add(pts);
|
||
|
||
public void Circle(double cx, double cy, double r) => CircleCount++;
|
||
|
||
public void Stroke(Contour c)
|
||
{
|
||
StrokeContours.Add(c);
|
||
Polylines.Add(Zplosti(c));
|
||
}
|
||
|
||
public void Text(double x, double y, string text, double heightMm,
|
||
HAlign h = HAlign.Left, VAlign v = VAlign.Baseline, double rotationDeg = 0,
|
||
TextStyle style = default, double widthFactor = 1, double maxWidthMm = 0)
|
||
=> Texts.Add(new TextCall(x, y, text, heightMm, h, v, rotationDeg, style, widthFactor, maxWidthMm));
|
||
|
||
public void Fill(IReadOnlyList<Contour> loops)
|
||
{
|
||
FillContours.Add(loops);
|
||
Fills.Add(loops.Select(Zplosti).ToList());
|
||
}
|
||
|
||
/// <summary>Zploští obrys na body (jemně, sagitta ≤ 0,02 mm) – pro bbox asserty v testech.</summary>
|
||
private static IReadOnlyList<(double X, double Y)> Zplosti(Contour c)
|
||
{
|
||
var pts = new List<(double X, double Y)>();
|
||
foreach (var e in c.Edges) e.AppendPoints(pts, maxSagitta: 0.02);
|
||
if (c.Edges.Count > 0) pts.Add((c.Edges[^1].EX, c.Edges[^1].EY));
|
||
return pts;
|
||
}
|
||
}
|