UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

1 lines 6.59 kB
{"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"}