{"version":3,"file":"svgParsing.mjs","names":[],"sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type { TBBox, SVGElementName, SupportedSVGUnit } from '../../typedefs';\nimport { escapeXml } from '../lang_string';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n  const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n  switch (type) {\n    case 'linearGradient':\n      return commonAttributes.concat([\n        'x1',\n        'y1',\n        'x2',\n        'y2',\n        'gradientUnits',\n        'gradientTransform',\n      ]);\n    case 'radialGradient':\n      return commonAttributes.concat([\n        'gradientUnits',\n        'gradientTransform',\n        'cx',\n        'cy',\n        'r',\n        'fx',\n        'fy',\n        'fr',\n      ]);\n    case 'stop':\n      return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n  }\n  return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n  const unit = /\\D{0,2}$/.exec(value),\n    number = parseFloat(value);\n  const dpi = config.DPI;\n  switch (unit?.[0] as SupportedSVGUnit) {\n    case 'mm':\n      return (number * dpi) / 25.4;\n\n    case 'cm':\n      return (number * dpi) / 2.54;\n\n    case 'in':\n      return number * dpi;\n\n    case 'pt':\n      return (number * dpi) / 72; // or * 4 / 3\n\n    case 'pc':\n      return ((number * dpi) / 72) * 12; // or * 16\n\n    case 'em':\n      return number * fontSize;\n\n    default:\n      return number;\n  }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n  meetOrSlice: MeetOrSlice;\n  alignX: MinMidMax;\n  alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n  //divide align in alignX and alignY\n  if (align && align !== NONE) {\n    return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n  } else if (align === NONE) {\n    return [align, align];\n  }\n  return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n  attribute: string,\n): TPreserveArParsed => {\n  const [firstPart, secondPart] = attribute.trim().split(' ') as [\n    MinMidMax,\n    MeetOrSlice | undefined,\n  ];\n  const [alignX, alignY] = parseAlign(firstPart);\n  return {\n    meetOrSlice: secondPart || 'meet',\n    alignX,\n    alignY,\n  };\n};\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n  prop: string,\n  value?: any,\n  inlineStyle = true,\n) => {\n  let colorValue;\n  let opacityValue;\n  if (!value) {\n    colorValue = 'none';\n  } else if (value.toLive) {\n    colorValue = `url(#SVGID_${escapeXml(value.id)})`;\n  } else {\n    const color = new Color(value),\n      opacity = color.getAlpha();\n\n    colorValue = color.toRgb();\n    if (opacity !== 1) {\n      opacityValue = opacity.toString();\n    }\n  }\n  if (inlineStyle) {\n    return `${prop}: ${colorValue}; ${\n      opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n    }`;\n  } else {\n    return `${prop}=\"${colorValue}\" ${\n      opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n    }`;\n  }\n};\n\nexport const createSVGRect = (\n  color: string,\n  { left, top, width, height }: TBBox,\n  precision = config.NUM_FRACTION_DIGITS,\n) => {\n  const svgColor = colorPropToSVG(FILL, color, false);\n  const [x, y, w, h] = [left, top, width, height].map((value) =>\n    toFixed(value, precision),\n  );\n  return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,oBAAoB,SAAyB;CACxD,MAAM,mBAAmB;EAAC;EAAuB;EAAS;EAAM;EAAQ;AACxE,SAAQ,MAAR;EACE,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,OACH,QAAO,iBAAiB,OAAO;GAAC;GAAU;GAAc;GAAe,CAAC;;AAE5E,QAAO;;;;;;;;;AAUT,MAAa,aAAa,OAAe,WAAA,OAAqC;CAC5E,MAAM,OAAO,WAAW,KAAK,MAAM,EACjC,SAAS,WAAW,MAAM;CAC5B,MAAM,MAAM,OAAO;AACnB,SAAA,SAAA,QAAA,SAAA,KAAA,IAAA,KAAA,IAAQ,KAAO,IAAf;EACE,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAO,SAAS;EAElB,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAS,SAAS,MAAO,KAAM;EAEjC,KAAK,KACH,QAAO,SAAS;EAElB,QACE,QAAO;;;AAeb,MAAM,cAAc,UAA+B;AAEjD,KAAI,SAAS,UAAA,OACX,QAAO,CAAC,MAAM,MAAM,GAAG,EAAE,EAAe,MAAM,MAAM,GAAG,EAAE,CAAc;UAC9D,UAAA,OACT,QAAO,CAAC,OAAO,MAAM;AAEvB,QAAO,CAAC,OAAO,MAAM;;;;;;;;AASvB,MAAa,qCACX,cACsB;CACtB,MAAM,CAAC,WAAW,cAAc,UAAU,MAAM,CAAC,MAAM,IAAI;CAI3D,MAAM,CAAC,QAAQ,UAAU,WAAW,UAAU;AAC9C,QAAO;EACL,aAAa,cAAc;EAC3B;EACA;EACD;;;;;;;;;;AAWH,MAAa,kBACX,MACA,OACA,cAAc,SACX;CACH,IAAI;CACJ,IAAI;AACJ,KAAI,CAAC,MACH,cAAa;UACJ,MAAM,OACf,cAAa,cAAc,UAAU,MAAM,GAAG,CAAC;MAC1C;EACL,MAAM,QAAQ,IAAI,MAAM,MAAM,EAC5B,UAAU,MAAM,UAAU;AAE5B,eAAa,MAAM,OAAO;AAC1B,MAAI,YAAY,EACd,gBAAe,QAAQ,UAAU;;AAGrC,KAAI,YACF,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;KAGxD,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;;AAK5D,MAAa,iBACX,OACA,EAAE,MAAM,KAAK,OAAO,UACpB,YAAY,OAAO,wBAChB;CACH,MAAM,WAAW,eAAe,MAAM,OAAO,MAAM;CACnD,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK;EAAC;EAAM;EAAK;EAAO;EAAO,CAAC,KAAK,UACnD,QAAQ,OAAO,UAAU,CAC1B;AACD,QAAO,SAAS,SAAS,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE"}