@@ -32,8 +32,13 @@ zvláštní `PlatformTarget` se nenastavuje.
### Zápis DXF – co je potřeba vědět
- **Tloušťka čáry** = `Layer.LineWeight` (enum, hodnota v 1/100 mm – standardní hodnoty:
`0,5,9,13,15,18,20,25,30,35,40,50,53,60,70,80,90,100,106,120,140,158,200,211` ).
- **Tloušťka čáry** je enum v 1/100 mm ( standardní hodnoty
`0,5,9,13,15,18,20,25,30,35,40,50,53,60,70,80,90,100,106,120,140,158,200,211` ); zapisuje se
na hladinu (`Layer.LineWeight` ) i na entitu, která ji přebíjí. Milimetry z kreslicího rozhraní
se přichytí k nejbližší standardní hodnotě.
- **Barva** se zapisuje ve stejném druhu, v jakém přišla ze zdroje: indexovaná číslem (group 62),
přímá jako RGB (group 420), `ByLayer` /`ByBlock` odkazem. Zplošťování na RGB by výkres v CADu
odřízlo od tabulky barev.
- **Diakritika** se do DXF ukládá jako Unicode escape `\U+XXXX` (např. `š` → `\U+0161` ) – AutoCAD
i ostatní čtečky to čtou správně.
- Pole, která byla v šabloně `ATTDEF` , se při vyplnění zapisují jako obyčejné `TEXT` /`MTEXT` entity
@@ -50,13 +55,16 @@ Aplikace je členěná dle vrstev (MVVM + služby):
```
Rozpisky/
├─ Rendering/ ← kreslicí vrstva (nezávislá na cíli)
│ ├─ IProfileRenderer.cs ← kreslicí rozhraní + HAlign/VAlign + TextStyle
│ ├─ IProfileRenderer.cs ← kreslicí rozhraní + HAlign/VAlign + TextStyle + Vypln
│ ├─ SkiaProfileRenderer.cs ← výstup přes SkiaSharp (obrazovka / PNG / PDF)
│ ├─ DxfProfileRenderer.cs ← výstup do DXF (ACadSharp)
│ ├─ BoundsRenderer.cs ← spočítá bbox kresby (fit / umístění na A4)
│ └ ─ TransformRenderer.cs ← dekorátor: měřítko + posun (fit fragmentů/loga )
│ ├ ─ TransformRenderer.cs ← dekorátor: afinní transformace (fit loga, rozvinutí bloku )
│ ├─ KresliciStav.cs ← barva s původem (ACI/RGB/ByLayer), hladina, typ čáry, tloušťka
│ └─ AciPaleta.cs ← indexované barvy AutoCADu (ACI 0– 255) → RGB
├─ Dxf/ ← čtení šablony, mapování hodnot, kódy
│ ├─ DxfTemplate.cs ← načte DXF šablonu a přehraje ji do IProfileRenderer
│ ├─ SrafaVzor.cs ← rozvine vzor šrafy (ANSI31 apod.) na čáry
│ ├─ RozpiskaRenderer.cs ← spojuje šablonu + hodnoty + exportéry (fasáda pro UI)
│ ├─ RozpiskaValues.cs ← „tag DXF → hodnota" z projektu/přílohy/číselníků (reflexí dle mapovani.json)
│ ├─ MapovaniStore.cs ← načtení mapování z mapovani.json (config vedle .exe)
@@ -95,37 +103,94 @@ Vše se kreslí ve **výkresových milimetrech**, osa **Y nahoru** (jako v CAD/D
public enum HAlign { Left , Center , Right }
public enum VAlign { Baseline , Bottom , Middle , Top }
public readonly record struct TextStyle ( string? FontFamily = null , bool Bold = false ,
bool Italic = false , string? FontFile = null ) ;
public enum BarvaDruh { ByLayer , ByBlock , Index , True }
public readonly record struct Barva ( BarvaDruh Druh , byte Index , int Rgb ) ;
public readonly record struct HladinaStav ( string Nazev , Barva Barva , string TypCary = "Continuous" ,
double TloustkaMm = 0 , bool Tisknout = true , bool Zapnuta = true ) ;
public readonly record struct KresliciStav ( HladinaStav Hladina , Barva Barva ,
string? TypCary = null , double? TloustkaMm = null ) ;
public readonly record struct TextStyle ( string? FontFamily = null , bool Bold = false , bool Italic = false ,
string? FontFile = null , double ObliqueDeg = 0 ,
string? Nazev = null , bool JeShx = false ) ;
public readonly record struct Usecka ( double X1 , double Y1 , double X2 , double Y2 ) ;
public readonly record struct Vypln ( string? Vzor = null , double Meritko = 1 , double UhelDeg = 0 ,
IReadOnlyList < Usecka > ? Cary = null ) ;
public interface IProfileRenderer
{
void Layer ( string name , int rgb , double lineWeightMm = 0.25 ) ; // barva 0xRRGGBB, tloušťka ByLayer
void Stav ( in KresliciStav s ) ;
void Line ( double x1 , double y1 , double x2 , double y2 ) ;
void Polyline ( IReadOnlyList < ( double X , double Y ) > pts , bool closed = false ) ;
void Circle ( double cx , double cy , double r ) ;
void Stroke ( Contour c ) ; // obrys se zachovanými oblouky
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 ) ;
void Fill ( IReadOnlyList < IReadOnlyList < ( double X , double Y ) > > loops ) ; // HATCH výplně (even-odd)
void Fill ( IReadOnlyList < Contour > loops , Vypln vypln = default ) ; // HATCH výplně (even-odd)
}
```
- `rgb` je barva `0xRRGGBB` rozbalená z DXF (ByLayer i index/true-color). Bílá se kreslí čer ně
(bílá na bílém papíře by zmizela).
**Proč `KresliciStav` a ne `int rgb`. ** Šablona i všech 9 log jsou zapsané výhrad ně
**indexovanými barvami AutoCADu ** (group 62). Kdyby rozhraní neslo jen výsledné RGB, export by
z nich udělal natvrdo true color (group 420), výkres by v CADu přestal reagovat na tabulku barev
a `ByLayer` by se rozpadlo na kopie barvy hladiny. Barva proto nese **původ ** , ne jen hodnotu:
rastrové renderery si vyžádají hotové RGB přes `RgbProKresbu()` , DXF export zapíše původní druh.
Ze stejného důvodu se přenáší celý popis hladiny – ve výstupu se staví z tabulky hladin, ne
z první entity, která na ní přistála.
- **Paleta ACI** ([`AciPaleta` ](../Rozpisky/Rendering/AciPaleta.cs )) je vlastní, ne z ACadSharp:
ta se od AutoCADu liší u 33 indexů, mimo jiné u 8 (v šabloně použitý) a u posledního indexu
většiny desítek odstínů, kde vrací barvu ze sousední skupiny (29 a 39 mají dokonce tutéž).
Rozsah 10– 249 se dopočítává, ne vypisuje: 24 odstínů × 5 jasů × 2 sytosti.
- `TextStyle.Nazev` = jméno stylu ve zdroji („Popis základní"). Nese se dál, aby ho export zapsal
beze změny – jeden zdrojový styl = jeden styl ve výstupu.
- `widthFactor` = horizontální měřítko písma (DXF width factor). `maxWidthMm` = šířka pro zalomení
víceřádkového textu (0 = jen explicitní zlomy).
- **Bílá se kreslí černě** (bílá na bílém papíře by zmizela) – jen v rastrových rendererech;
do DXF jde barva beze změny.
Implementace:
- **`SkiaProfileRenderer` ** – kreslí na `SKCanvas` . Dostane funkci `Map(mmX, mmY) → bod plátna`
a `pxPerMm` . Text vzpřímeně (rotace opačně, plátno má Y dolů), fonty ze stylu/souboru s fallbackem.
Je `IDisposable` (uvolní typefaces) – používat přes `using` .
- **`DxfProfileRenderer` ** – pro každou hladinu založí `Layer` (barva + tloušťka), entity přidává do
`Document` . Výsledek zapíše `DxfWriter.Write(path, renderer.Document, binary: true)` .
- **`DxfProfileRenderer` ** – staví ACadSharp entity do `Document` ; hladiny, textové styly i barvy
podle zdroje. Verze výstupu je zafixovaná ( `VerzeVystupu` ), ať ji neurčí default balíčku .
Výsledek zapíše `DxfWriter.Write(path, renderer.Document, binary: true)` .
- **`BoundsRenderer` ** – nic nekreslí, jen sčítá min/max souřadnic (fit / vystředění na A4).
- **`TransformRenderer` ** – dekorátor: na souřadnice aplikuje uniformní měřítko + posun. Slouží
k umístění vkládaného DXF fragmentu (logo / schéma) do vymezeného rámečku.
- **`TransformRenderer` ** – dekorátor s afinní transformací: měřítko + posun (umístění loga do
rámečku), nebo měřítko os + natočení + posun (rozvinutí bloku, `ProBlok` ). Oblouk zůstane
obloukem jen u podobnosti bez zrcadlení – jinak by z kružnice byla elipsa, kterou rozhraní nezná,
a tvar se rozloží na lomenou čáru.
### Které DXF entity se čtou
| Entita | Jak se kreslí |
|---|---|
| `LINE` , `CIRCLE` , `ARC` | přímo; oblouk analyticky, hladký v každém přiblížení |
| `LWPOLYLINE` , `POLYLINE` (2D) | lomená čára, s `bulge` jako obrys s kruhovými oblouky |
| `POLYLINE` (3D) | promítnuto do roviny XY |
| `SPLINE` | lomená čára, dílek ≈ 0,3 mm podle délky řídicího polygonu |
| `ELLIPSE` | lomená čára (rozhraní zná jen kruhové oblouky) |
| `TEXT` , `MTEXT` , `ATTDEF` | text se stylem, zarovnáním, sklonem a šířkovým faktorem |
| `HATCH` | plná výplň, nebo vzor rozvinutý na čáry ([`SrafaVzor` ](../Rozpisky/Dxf/SrafaVzor.cs )) |
| `SOLID` , `3DFACE` | vyplněný čtyřúhelník (v DXF jsou 3. a 4. roh prohozené) |
| `POINT` | tečka |
| `INSERT` | rekurzivně rozvinutý blok: vztažný bod, měřítko os, natočení, `ByBlock` barvy |
| ostatní | nekreslí se, ale **spočítá se ** do `DxfTemplate.NezpracovaneEntity` ; souhrn exportu to vypíše |
### Známá omezení
- **Vnitřní formátovací kódy MTEXTu** (`\H` výška, `\C` barva, `\f` font, `\S` zlomek) se ztrácejí –
čte se `MText.PlainText` , který je odstraňuje. Zvlášť se čte jen `\W` (šířkový faktor), protože
ho ACadSharp v `PlainText` nechává a jinak by se vykreslil jako text.
- **Zarovnání textu `Aligned` / `Fit` ** se aproximuje na `Left` – text se neroztáhne na cílovou délku.
- **Typ čáry** se přenáší jako název, ale rastrové renderery kreslí vždy plnou čáru; čárkované styly
se projeví až v DXF (v dodávaných souborech je stejně všude `Continuous` ).
- **Šrafy** se do DXF zapisují se jménem vzoru, měřítkem a úhlem, ale bez definice čar vzoru – CAD
si ji dohledá ve svých `.pat` . Vzor, který cílový CAD nezná, se v něm nevykreslí.
---