using System.IO; using ACadSharp.Entities; using ACadSharp.IO; using Rozpisky.Dxf; using Rozpisky.Rendering; using Xunit; namespace Rozpisky.Tests; /// /// Textové styly a MTEXT tam a zpět. Šablona má styly pojmenované česky („Popis základní", /// „Název stavby"); export je dřív zahodil a vyrobil náhradní jména podle fontu (Verdana_1), /// takže ve správci stylů v CADu nešlo nic najít ani hromadně změnit. /// public class TextStylyRoundTripTesty : IDisposable { private readonly string _soubor = Path.Combine(Path.GetTempPath(), "rozpisky-styly-" + Guid.NewGuid().ToString("N") + ".dxf"); public void Dispose() { try { File.Delete(_soubor); } catch (IOException) { } GC.SuppressFinalize(this); } private ACadSharp.CadDocument Kolecko(Action kresba) { var dxf = new DxfProfileRenderer(); kresba(dxf); DxfWriter.Write(_soubor, dxf.Document, binary: true); return DxfReader.Read(_soubor); } [Fact] public void StylySiDrziJmenaZeZdroje() { var doc = Kolecko(g => new DxfTemplate(TestData.Sablona).Replay(g)); var jmena = doc.TextStyles.Select(s => s.Name).ToList(); Assert.Contains("Popis základní", jmena); Assert.Contains("Název stavby", jmena); // Náhradní jména podle fontu nesmí vzniknout, když zdroj styl pojmenovaný má. Assert.DoesNotContain(jmena, j => j.StartsWith("Verdana", StringComparison.OrdinalIgnoreCase)); } [Fact] public void JedenZdrojovyStylDaJedenStylVeVystupu() { // Dřív vznikal nový styl pro každou kombinaci fontu a sklonu, takže jich ve výstupu // bylo víc než ve zdroji a texty se rozpadly mezi ně. var zdroj = DxfReader.Read(TestData.Sablona); var doc = Kolecko(g => new DxfTemplate(TestData.Sablona).Replay(g)); var pouzite = doc.Entities.OfType().Select(t => t.Style?.Name) .Concat(doc.Entities.OfType().Select(m => m.Style?.Name)) .Where(n => n is not null).Distinct().ToList(); Assert.NotEmpty(pouzite); foreach (var n in pouzite) Assert.True(zdroj.TextStyles.Contains(n!), $"styl {n} ve zdroji není"); } [Fact] public void MtextSiDrziNatoceni() { var doc = Kolecko(g => g.Text(0, 0, "dva\nřádky", 3, maxWidthMm: 40, rotationDeg: 30)); var mt = Assert.Single(doc.Entities.OfType()); Assert.Equal(30, mt.Rotation * 180 / Math.PI, 3); } [Fact] public void MtextSiDrziSirkovyFaktor() { var doc = Kolecko(g => g.Text(0, 0, "text", 3, maxWidthMm: 40, widthFactor: 0.8)); var mt = Assert.Single(doc.Entities.OfType()); Assert.StartsWith(@"\W0.8;", mt.Value); // A vlastní čtečka ho musí zase odloupnout, jinak by se „W0.8;" vykreslilo jako text. var (cisty, wf) = DxfTemplate.MTextSirka(mt.Value, mt.PlainText); Assert.Equal("text", cisty); Assert.Equal(0.8, wf!.Value, 3); } [Fact] public void ZpetneLomitkoAZavorkyNerozbijiMtext() { // Reálná hodnota z pole: cesta nebo poznámka se zpětným lomítkem. Bez escapování // by ji CAD přečetl jako formátovací kód a část textu by zmizela. const string hodnota = @"C:\projekt {2025} \P"; var doc = Kolecko(g => g.Text(0, 0, hodnota, 3, maxWidthMm: 60)); var mt = Assert.Single(doc.Entities.OfType()); Assert.Equal(hodnota, mt.PlainText); } [Fact] public void ZlomRadkuSePreloziNaMtextovyKod() { var doc = Kolecko(g => g.Text(0, 0, "první\ndruhý", 3, maxWidthMm: 60)); var mt = Assert.Single(doc.Entities.OfType()); Assert.Contains(@"\P", mt.Value); Assert.Equal("první\ndruhý", mt.PlainText.Replace("\r\n", "\n")); } }