{"version":3,"file":"svgParsing.min.mjs","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 {\n  TBBox,\n  TMat2D,\n  SVGElementName,\n  SupportedSVGUnit,\n} from '../../typedefs';\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 * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n  'matrix(' +\n  transform\n    .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n    .join(' ') +\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_${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"],"names":["getSvgAttributes","type","commonAttributes","concat","parseUnit","value","fontSize","arguments","length","undefined","DEFAULT_SVG_FONT_SIZE","unit","exec","number","parseFloat","dpi","config","DPI","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","split","alignX","alignY","align","NONE","slice","meetOrSlice","matrixToSVG","transform","map","toFixed","NUM_FRACTION_DIGITS","join","colorPropToSVG","prop","colorValue","opacityValue","inlineStyle","toLive","id","color","Color","opacity","getAlpha","toRgb","toString","createSVGRect","_ref","left","top","width","height","precision","svgColor","FILL","x","y","w","h"],"mappings":"gOAgBaA,MAAAA,EAAoBC,IAC/B,MAAMC,EAAmB,CAAC,sBAAuB,QAAS,KAAM,SAChE,OAAQD,GACN,IAAK,iBACH,OAAOC,EAAiBC,OAAO,CAC7B,KACA,KACA,KACA,KACA,gBACA,sBAEJ,IAAK,iBACH,OAAOD,EAAiBC,OAAO,CAC7B,gBACA,oBACA,KACA,KACA,IACA,KACA,KACA,OAEJ,IAAK,OACH,OAAOD,EAAiBC,OAAO,CAAC,SAAU,aAAc,iBAE5D,OAAOD,CAAgB,EAUZE,EAAY,SAACC,GAAoD,IAArCC,EAAQC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAGG,EAClD,MAAMC,EAAO,WAAWC,KAAKP,GAC3BQ,EAASC,WAAWT,GAChBU,EAAMC,EAAOC,IACnB,OAAQN,eAAAA,EAAO,IACb,IAAK,KACH,OAAQE,EAASE,EAAO,KAE1B,IAAK,KACH,OAAQF,EAASE,EAAO,KAE1B,IAAK,KACH,OAAOF,EAASE,EAElB,IAAK,KACH,OAAQF,EAASE,EAAO,GAE1B,IAAK,KACH,OAASF,EAASE,EAAO,GAAM,GAEjC,IAAK,KACH,OAAOF,EAASP,EAElB,QACE,OAAOO,EAEb,EA6BaK,EACXC,IAEA,MAAOC,EAAWC,GAAcF,EAAUG,OAAOC,MAAM,MAIhDC,EAAQC,IAvBGC,EAuBkBN,IArBvBM,IAAUC,EACd,CAACD,EAAME,MAAM,EAAG,GAAiBF,EAAME,MAAM,EAAG,IAC9CF,IAAUC,EACZ,CAACD,EAAOA,GAEV,CAAC,MAAO,OAPGA,MAwBlB,MAAO,CACLG,YAAaR,GAAc,OAC3BG,SACAC,SACD,EAQUK,EAAeC,GAC1B,UACAA,EACGC,KAAK3B,GAAU4B,EAAQ5B,EAAOW,EAAOkB,uBACrCC,KAAK,KACR,IAUWC,EAAiB,SAC5BC,EACAhC,GAEG,IACCiC,EACAC,EAHJC,IAAWjC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAIX,GAAKF,EAEE,GAAIA,EAAMoC,OACfH,gBAAUnC,OAAiBE,EAAMqC,GAAK,SACjC,CACL,MAAMC,EAAQ,IAAIC,EAAMvC,GACtBwC,EAAUF,EAAMG,WAElBR,EAAaK,EAAMI,QACH,IAAZF,IACFN,EAAeM,EAAQG,WAE3B,MAXEV,EAAa,OAYf,OAAIE,EACFrC,GAAAA,OAAUkC,EAAI,MAAAlC,OAAKmC,QAAUnC,OAC3BoC,EAAYpC,GAAAA,OAAMkC,EAAI,cAAAlC,OAAaoC,QAAmB,IAGxDpC,GAAAA,OAAUkC,EAAI,MAAAlC,OAAKmC,QAAUnC,OAC3BoC,EAAYpC,GAAAA,OAAMkC,EAAI,cAAAlC,OAAaoC,QAAmB,GAG5D,EAEaU,EAAgB,SAC3BN,EAAaO,GAGV,IAFHC,KAAEA,EAAIC,IAAEA,EAAGC,MAAEA,EAAKC,OAAEA,GAAeJ,EACnCK,EAAShD,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAGS,GAAAA,EAAOkB,oBAEnB,MAAMsB,EAAWpB,EAAeqB,EAAMd,GAAO,IACtCe,EAAGC,EAAGC,EAAGC,GAAK,CAACV,EAAMC,EAAKC,EAAOC,GAAQtB,KAAK3B,GACnD4B,EAAQ5B,EAAOkD,KAEjB,MAAA,SAAApD,OAAgBqD,UAAQrD,OAAOuD,EAACvD,SAAAA,OAAQwD,eAACxD,OAAYyD,EAACzD,cAAAA,OAAa0D,EAAC,YACtE"}