(spNode: SafeXmlNode)
| 171 | * Parse a shape XML node (`p:sp` or `p:cxnSp`) into ShapeNodeData. |
| 172 | */ |
| 173 | export function parseShapeNode(spNode: SafeXmlNode): ShapeNodeData { |
| 174 | const base = parseBaseProps(spNode) |
| 175 | const spPr = spNode.child('spPr') |
| 176 | |
| 177 | // --- Preset geometry --- |
| 178 | const prstGeom = spPr.child('prstGeom') |
| 179 | const presetGeometry = prstGeom.attr('prst') |
| 180 | const avLst = prstGeom.child('avLst') |
| 181 | const adjustments = parseAdjustments(avLst) |
| 182 | |
| 183 | // --- Custom geometry --- |
| 184 | const custGeom = spPr.child('custGeom') |
| 185 | const customGeometry = custGeom.exists() ? custGeom : undefined |
| 186 | |
| 187 | // --- Fill --- |
| 188 | const fill = findFill(spPr) |
| 189 | |
| 190 | // --- Line --- |
| 191 | const ln = spPr.child('ln') |
| 192 | const line = ln.exists() ? ln : undefined |
| 193 | |
| 194 | // --- Line end markers (arrowheads) --- |
| 195 | let headEnd: LineEndInfo | undefined |
| 196 | let tailEnd: LineEndInfo | undefined |
| 197 | if (ln.exists()) { |
| 198 | const headEndNode = ln.child('headEnd') |
| 199 | if (headEndNode.exists()) { |
| 200 | const t = headEndNode.attr('type') |
| 201 | if (t && t !== 'none') { |
| 202 | headEnd = { type: t, w: headEndNode.attr('w'), len: headEndNode.attr('len') } |
| 203 | } |
| 204 | } |
| 205 | const tailEndNode = ln.child('tailEnd') |
| 206 | if (tailEndNode.exists()) { |
| 207 | const t = tailEndNode.attr('type') |
| 208 | if (t && t !== 'none') { |
| 209 | tailEnd = { type: t, w: tailEndNode.attr('w'), len: tailEndNode.attr('len') } |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | // --- Text body --- |
| 215 | const txBody = spNode.child('txBody') |
| 216 | const textBody = parseTextBody(txBody) |
| 217 | |
| 218 | // --- Text transform (diagram shapes: dsp:txXfrm gives text box position/size in same space as xfrm) |
| 219 | let textBoxBounds: TextBoxBounds | undefined |
| 220 | const txXfrm = spNode.child('txXfrm') |
| 221 | if (txXfrm.exists()) { |
| 222 | const txOff = txXfrm.child('off') |
| 223 | const txExt = txXfrm.child('ext') |
| 224 | const xfrm = spPr.child('xfrm') |
| 225 | const off = xfrm.child('off') |
| 226 | const ext = xfrm.child('ext') |
| 227 | const shapeX = off.numAttr('x') ?? 0 |
| 228 | const shapeY = off.numAttr('y') ?? 0 |
| 229 | const shapeW = ext.numAttr('cx') ?? 0 |
| 230 | const shapeH = ext.numAttr('cy') ?? 0 |
no test coverage detected