{"version":3,"file":"SVGParser.mjs","sources":["../../../../../src/scene/graphics/shared/svg/SVGParser.ts"],"sourcesContent":["import { warn } from '../../../../utils/logging/warn';\nimport { GraphicsPath } from '../path/GraphicsPath';\nimport { parseSVGDefinitions } from './parseSVGDefinitions';\nimport { parseSVGFloatAttribute } from './parseSVGFloatAttribute';\nimport { parseSVGStyle } from './parseSVGStyle';\nimport { checkForNestedPattern } from './utils/fillOperations';\nimport { appendSVGPath, calculatePathArea, extractSubpaths } from './utils/pathOperations';\n\nimport type { FillGradient } from '../fill/FillGradient';\nimport type { FillStyle, StrokeStyle } from '../FillTypes';\nimport type {\n    GraphicsContext,\n} from '../GraphicsContext';\n\n/**\n * Represents a session for SVG parsing. Contains the current state and resources needed during parsing.\n * @internal\n */\nexport interface Session\n{\n    /** The graphics context to render to */\n    context: GraphicsContext;\n    /** The current path being constructed */\n    path: GraphicsPath;\n    /** Map of definitions by id */\n    defs: Record<string, FillGradient>;\n}\n\n/**\n * Parses an SVG element or string and renders it to a graphics context.\n * Handles both SVG strings and SVG DOM elements as input.\n * @param svg - The SVG content to parse, either as a string or element\n * @param graphicsContext - Optional graphics context to render to\n * @returns The graphics context with the SVG rendered into it\n * @internal\n */\nexport function SVGParser(\n    svg: string | SVGElement | SVGSVGElement,\n    graphicsContext?: GraphicsContext\n): GraphicsContext\n{\n    // Convert string input to SVG element\n    if (typeof svg === 'string')\n    {\n        // eslint-disable-next-line no-restricted-globals\n        const div = document.createElement('div');\n\n        div.innerHTML = svg.trim();\n        svg = div.querySelector('svg') as SVGElement;\n    }\n\n    // Initialize parsing session\n    const session = {\n        context: graphicsContext,\n        defs: {},\n        path: new GraphicsPath(),\n    };\n\n    // Parse definitions (gradients, etc) first\n    parseSVGDefinitions(svg, session);\n\n    // Process all child elements except defs\n    const children = svg.children;\n\n    const { fillStyle, strokeStyle } = parseSVGStyle(svg, session);\n\n    for (let i = 0; i < children.length; i++)\n    {\n        const child = children[i] as SVGElement;\n\n        if (child.nodeName.toLowerCase() === 'defs') continue;\n        renderChildren(child, session, fillStyle, strokeStyle);\n    }\n\n    return graphicsContext;\n}\n\n/**\n * Recursively renders SVG elements and their children.\n * Handles styling inheritance and different SVG shape types.\n * @param svg - The SVG element to render\n * @param session - The current parsing session\n * @param fillStyle - The inherited fill style\n * @param strokeStyle - The inherited stroke style\n */\nfunction renderChildren(svg: SVGElement, session: Session, fillStyle: FillStyle, strokeStyle: StrokeStyle): void\n{\n    const children = svg.children;\n\n    // Parse element's style and merge with inherited styles\n    const { fillStyle: f1, strokeStyle: s1 } = parseSVGStyle(svg, session);\n\n    if (f1 && fillStyle)\n    {\n        fillStyle = { ...fillStyle, ...f1 };\n    }\n    else if (f1)\n    {\n        fillStyle = f1;\n    }\n\n    if (s1 && strokeStyle)\n    {\n        strokeStyle = { ...strokeStyle, ...s1 };\n    }\n    else if (s1)\n    {\n        strokeStyle = s1;\n    }\n\n    const noStyle = !fillStyle && !strokeStyle;\n\n    // Default to black fill if no styles specified\n    if (noStyle)\n    {\n        fillStyle = { color: 0 };\n    }\n\n    // Variables for shape attributes\n    let x;\n    let y;\n    let x1;\n    let y1;\n    let x2;\n    let y2;\n    let cx;\n    let cy;\n    let r;\n    let rx;\n    let ry;\n    let points;\n    let pointsString;\n    let d;\n    let graphicsPath;\n    let width;\n    let height;\n\n    // Handle different SVG element types\n    switch (svg.nodeName.toLowerCase())\n    {\n        case 'path':\n        {\n            d = svg.getAttribute('d') as string;\n\n            const fillRule = svg.getAttribute('fill-rule') as string;\n\n            const subpaths = extractSubpaths(d);\n            const hasExplicitEvenodd = fillRule === 'evenodd';\n            const hasMultipleSubpaths = subpaths.length > 1;\n\n            const shouldProcessHoles = hasExplicitEvenodd && hasMultipleSubpaths;\n\n            if (shouldProcessHoles)\n            {\n                const subpathsWithArea = subpaths.map((subpath) => ({\n                    path: subpath,\n                    area: calculatePathArea(subpath)\n                }));\n\n                subpathsWithArea.sort((a, b) => b.area - a.area);\n\n                // For complex cases, prefer multiple holes approach\n                const useMultipleHolesApproach = subpaths.length > 3 || !checkForNestedPattern(subpathsWithArea);\n\n                if (useMultipleHolesApproach)\n                {\n                    // Multiple holes approach: first (largest) is fill, rest are holes\n                    for (let i = 0; i < subpathsWithArea.length; i++)\n                    {\n                        const subpath = subpathsWithArea[i];\n                        const isMainShape = i === 0;\n\n                        session.context.beginPath();\n                        const newPath = new GraphicsPath(undefined, true); // Always use evenodd for hole processing\n\n                        appendSVGPath(subpath.path, newPath);\n                        session.context.path(newPath);\n\n                        if (isMainShape)\n                        {\n                            if (fillStyle) session.context.fill(fillStyle);\n                            if (strokeStyle) session.context.stroke(strokeStyle);\n                        }\n                        else\n                        {\n                            session.context.cut();\n                        }\n                    }\n                }\n                else\n                {\n                    // Nested holes approach: alternate between fill and cut\n                    for (let i = 0; i < subpathsWithArea.length; i++)\n                    {\n                        const subpath = subpathsWithArea[i];\n                        const isHole = i % 2 === 1; // Odd indices are holes\n\n                        session.context.beginPath();\n                        const newPath = new GraphicsPath(undefined, true); // Always use evenodd for hole processing\n\n                        appendSVGPath(subpath.path, newPath);\n                        session.context.path(newPath);\n\n                        if (isHole)\n                        {\n                            session.context.cut();\n                        }\n                        else\n                        {\n                            if (fillStyle) session.context.fill(fillStyle);\n                            if (strokeStyle) session.context.stroke(strokeStyle);\n                        }\n                    }\n                }\n            }\n            else\n            {\n                const useEvenoddForGraphicsPath = fillRule ? (fillRule === 'evenodd') : true;\n\n                graphicsPath = new GraphicsPath(d, useEvenoddForGraphicsPath);\n                session.context.path(graphicsPath);\n                if (fillStyle) session.context.fill(fillStyle);\n                if (strokeStyle) session.context.stroke(strokeStyle);\n            }\n            break;\n        }\n\n        case 'circle':\n            cx = parseSVGFloatAttribute(svg, 'cx', 0);\n            cy = parseSVGFloatAttribute(svg, 'cy', 0);\n            r = parseSVGFloatAttribute(svg, 'r', 0);\n            session.context.ellipse(cx, cy, r, r);\n            if (fillStyle) session.context.fill(fillStyle);\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        case 'rect':\n            x = parseSVGFloatAttribute(svg, 'x', 0);\n            y = parseSVGFloatAttribute(svg, 'y', 0);\n            width = parseSVGFloatAttribute(svg, 'width', 0);\n            height = parseSVGFloatAttribute(svg, 'height', 0);\n            rx = parseSVGFloatAttribute(svg, 'rx', 0);\n            ry = parseSVGFloatAttribute(svg, 'ry', 0);\n\n            if (rx || ry)\n            {\n                session.context.roundRect(x, y, width, height, rx || ry);\n            }\n            else\n            {\n                session.context.rect(x, y, width, height);\n            }\n\n            if (fillStyle) session.context.fill(fillStyle);\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        case 'ellipse':\n            cx = parseSVGFloatAttribute(svg, 'cx', 0);\n            cy = parseSVGFloatAttribute(svg, 'cy', 0);\n            rx = parseSVGFloatAttribute(svg, 'rx', 0);\n            ry = parseSVGFloatAttribute(svg, 'ry', 0);\n\n            session.context.beginPath();\n            session.context.ellipse(cx, cy, rx, ry);\n\n            if (fillStyle) session.context.fill(fillStyle);\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        case 'line':\n            x1 = parseSVGFloatAttribute(svg, 'x1', 0);\n            y1 = parseSVGFloatAttribute(svg, 'y1', 0);\n            x2 = parseSVGFloatAttribute(svg, 'x2', 0);\n            y2 = parseSVGFloatAttribute(svg, 'y2', 0);\n\n            session.context.beginPath();\n            session.context.moveTo(x1, y1);\n            session.context.lineTo(x2, y2);\n\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        case 'polygon':\n            pointsString = svg.getAttribute('points') as string;\n            points = pointsString.match(/-?\\d+/g).map((n) => parseInt(n, 10));\n            session.context.poly(points, true);\n            if (fillStyle) session.context.fill(fillStyle);\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        case 'polyline':\n            pointsString = svg.getAttribute('points') as string;\n            points = pointsString.match(/-?\\d+/g).map((n) => parseInt(n, 10));\n            session.context.poly(points, false);\n            if (strokeStyle) session.context.stroke(strokeStyle);\n            break;\n\n        // Group elements - just process children\n        case 'g':\n        case 'svg':\n            break;\n\n        default: {\n            // Log unsupported elements\n            warn(`[SVG parser] <${svg.nodeName}> elements unsupported`);\n            break;\n        }\n    }\n\n    if (noStyle)\n    {\n        fillStyle = null;\n    }\n\n    // Recursively process child elements\n    for (let i = 0; i < children.length; i++)\n    {\n        renderChildren(children[i] as SVGElement, session, fillStyle, strokeStyle);\n    }\n}\n"],"names":[],"mappings":"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"}