|   | 
| import Path, { DEFAULT_PATH_STYLE, PathStyleProps } from '../graphic/Path'; | 
| import ZRImage, { ImageStyleProps } from '../graphic/Image'; | 
| import TSpan, { TSpanStyleProps } from '../graphic/TSpan'; | 
| import { getLineDash } from '../canvas/dashStyle'; | 
| import { map } from '../core/util'; | 
| import { normalizeColor } from './helper'; | 
|   | 
| type AllStyleOption = PathStyleProps | TSpanStyleProps | ImageStyleProps; | 
|   | 
| const NONE = 'none'; | 
| const mathRound = Math.round; | 
|   | 
| function pathHasFill(style: AllStyleOption): style is PathStyleProps { | 
|     const fill = (style as PathStyleProps).fill; | 
|     return fill != null && fill !== NONE; | 
| } | 
|   | 
| function pathHasStroke(style: AllStyleOption): style is PathStyleProps { | 
|     const stroke = (style as PathStyleProps).stroke; | 
|     return stroke != null && stroke !== NONE; | 
| } | 
|   | 
| const strokeProps = ['lineCap', 'miterLimit', 'lineJoin'] as const; | 
| const svgStrokeProps = map(strokeProps, prop => `stroke-${prop.toLowerCase()}`); | 
|   | 
| export default function mapStyleToAttrs( | 
|     updateAttr: (key: string, val: string | number) => void, | 
|     style: AllStyleOption, | 
|     el: Path | TSpan | ZRImage, | 
|     /** | 
|      * Will try not to set the attribute if it's using default value if not using forceUpdate. | 
|      * Mainly for reduce the generated size in svg-ssr mode. | 
|      */ | 
|     forceUpdate: boolean | 
| ): void { | 
|     const opacity = style.opacity == null ? 1 : style.opacity; | 
|   | 
|     // only set opacity. stroke and fill cannot be applied to svg image | 
|     if (el instanceof ZRImage) { | 
|         updateAttr('opacity', opacity); | 
|         return; | 
|     } | 
|   | 
|     if (pathHasFill(style)) { | 
|         const fill = normalizeColor(style.fill as string); | 
|         updateAttr('fill', fill.color); | 
|         const fillOpacity = style.fillOpacity != null | 
|             ? style.fillOpacity * fill.opacity * opacity | 
|             : fill.opacity * opacity; | 
|         if (forceUpdate || fillOpacity < 1) { | 
|             updateAttr('fill-opacity', fillOpacity); | 
|         } | 
|     } | 
|     else { | 
|         updateAttr('fill', NONE); | 
|     } | 
|   | 
|     if (pathHasStroke(style)) { | 
|         const stroke = normalizeColor(style.stroke as string); | 
|         updateAttr('stroke', stroke.color); | 
|         const strokeScale = style.strokeNoScale | 
|             ? (el as Path).getLineScale() | 
|             : 1; | 
|         const strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0); | 
|         const strokeOpacity = style.strokeOpacity != null | 
|             ? style.strokeOpacity * stroke.opacity * opacity | 
|             : stroke.opacity * opacity; | 
|         const strokeFirst = style.strokeFirst; | 
|   | 
|         if (forceUpdate || strokeWidth !== 1) { | 
|             updateAttr('stroke-width', strokeWidth); | 
|         } | 
|         // stroke then fill for text; fill then stroke for others | 
|         if (forceUpdate || strokeFirst) { | 
|             updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill'); | 
|         } | 
|         if (forceUpdate || strokeOpacity < 1) { | 
|             updateAttr('stroke-opacity', strokeOpacity); | 
|         } | 
|   | 
|         if (style.lineDash) { | 
|             let [lineDash, lineDashOffset] = getLineDash(el); | 
|             if (lineDash) { | 
|                 lineDashOffset = mathRound(lineDashOffset || 0); | 
|                 updateAttr('stroke-dasharray', lineDash.join(',')); | 
|                 if (lineDashOffset || forceUpdate) { | 
|                     updateAttr('stroke-dashoffset', lineDashOffset); | 
|                 } | 
|             } | 
|         } | 
|         else if (forceUpdate) { | 
|             // Reset if force update. | 
|             updateAttr('stroke-dasharray', NONE); | 
|         } | 
|   | 
|         // PENDING reset | 
|         for (let i = 0; i < strokeProps.length; i++) { | 
|             const propName = strokeProps[i]; | 
|             if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) { | 
|                 const val = style[propName] || DEFAULT_PATH_STYLE[propName]; | 
|                 // TODO reset | 
|                 val && updateAttr(svgStrokeProps[i], val); | 
|             } | 
|         } | 
|     } | 
|     else if (forceUpdate) { | 
|         updateAttr('stroke', NONE); | 
|     } | 
| } |