import { referenceLayer, REFERENCE_ACI, aciPaper } from './cad-style'; import { LAYERS, type DrawingDocument, type Entity, type Layer, type ViewId } from './types'; import { sheetFrame, viewPaperEntities } from './sheet'; import { entityBox } from './occupancy'; export { paperPoint } from './presentation'; export const escapeXml=(value:string):string=>value.replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!)); function renderEntity(e:Entity,height:number):string { const coord=(p:readonly number[])=>`${p[0].toFixed(4)},${(height-p[1]).toFixed(4)}`; if(e.kind==='text'){ const [x,y]=[e.point[0],height-e.point[1]]; return `${escapeXml(e.text)}`; } if(e.kind==='circle')return ``; if(e.kind==='line')return ``; if(e.kind==='polyline')return `<${e.closed?'polygon':'polyline'} points="${e.points.map(coord).join(' ')}"/>`; if(e.kind==='hatch'){ const fill=e.color&&/^#[0-9a-f]{6}$/i.test(e.color)?e.color:'#cbd1d6'; const d=[e.points,...e.holes??[]].map(loop=>`M${loop.map(coord).join('L')}Z`).join(''); if(e.pattern==='SOLID')return ``; const id=`hz-${Math.abs(Math.round((e.points[0]?.[0]??0)*10000))}-${Math.abs(Math.round((e.points[0]?.[1]??0)*10000))}-${e.source.member}-${e.source.index}`.replace(/[^a-z0-9-]/gi,''); const spacing=Math.max(.1,e.spacing); return ``; } throw new Error('Expand CAD dimensions before paper rendering'); } export function drawingSvg(doc:DrawingDocument,visible:ReadonlySet,interactive=false,selected?:ViewId):string { const {width,height}=doc.paper; const render=(e:Entity,view:string,index:number)=>{ if(!visible.has(e.layer))return''; const style={...LAYERS[e.layer],color:aciPaper(e.cad?.color??REFERENCE_ACI[referenceLayer(e)]??7)}; const issue=interactive&&doc.quality?.issues.some(i=>i.view===view&&i.first===index),b=issue?entityBox(e):undefined; const marker=b?``:''; return `=0?` data-entity="${view}:${index}"`:''}>${escapeXml(`${e.source.pier} / ${e.source.member} ${e.source.index+1} / ${e.layer}`)}${marker}${renderEntity(e,height)}`; }; let body=``; if(!selected)body+=sheetFrame(doc).map(e=>render(e,'sheet',-1)).join(''); for(const view of doc.views){ if(selected?view.id!==selected:['section','heights'].includes(view.id))continue; body+=`${viewPaperEntities(doc,view).map(({entity,index})=>render(entity,view.id,index)).join('')}`; } return `${body}`; }