fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
1 lines • 7.11 kB
Source Map (JSON)
{"version":3,"file":"textStyles.min.mjs","sources":["../../../../src/util/misc/textStyles.ts"],"sourcesContent":["import { reNewline } from '../../constants';\nimport type {\n TextStyle,\n TextStyleDeclaration,\n} from '../../shapes/Text/StyledText';\nimport { cloneStyles } from '../internals/cloneStyles';\nimport { graphemeSplit } from '../lang_string';\n\nexport type TextStyleArray = {\n start: number;\n end: number;\n style: TextStyleDeclaration;\n}[];\n\n/**\n * @param {Object} prevStyle first style to compare\n * @param {Object} thisStyle second style to compare\n * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties\n * @return {boolean} true if the style changed\n */\nexport const hasStyleChanged = (\n prevStyle: TextStyleDeclaration,\n thisStyle: TextStyleDeclaration,\n forTextSpans = false,\n) =>\n prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.textDecorationThickness !== thisStyle.textDecorationThickness ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.deltaY !== thisStyle.deltaY ||\n (forTextSpans &&\n (prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough));\n\n/**\n * Returns the array form of a text object's inline styles property with styles grouped in ranges\n * rather than per character. This format is less verbose, and is better suited for storage\n * so it is used in serialization (not during runtime).\n * @param {object} styles per character styles for a text object\n * @param {String} text the text string that the styles are applied to\n * @return {{start: number, end: number, style: object}[]}\n */\nexport const stylesToArray = (\n styles: TextStyle,\n text: string,\n): TextStyleArray => {\n const textLines = text.split('\\n'),\n stylesArray = [];\n let charIndex = -1,\n prevStyle = {};\n // clone style structure to prevent mutation\n styles = cloneStyles(styles);\n\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n if (!styles[i]) {\n //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle\n charIndex += chars.length;\n prevStyle = {};\n continue;\n }\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n const thisStyle = styles[i][c];\n //check if style exists for this character\n if (thisStyle && Object.keys(thisStyle).length > 0) {\n if (hasStyleChanged(prevStyle, thisStyle, true)) {\n stylesArray.push({\n start: charIndex,\n end: charIndex + 1,\n style: thisStyle,\n });\n } else {\n //if style is the same as previous character, increase end index\n stylesArray[stylesArray.length - 1].end++;\n }\n }\n prevStyle = thisStyle || {};\n }\n }\n return stylesArray;\n};\n\n/**\n * Returns the object form of the styles property with styles that are assigned per\n * character rather than grouped by range. This format is more verbose, and is\n * only used during runtime (not for serialization/storage)\n * @param {Array} styles the serialized form of a text object's styles\n * @param {String} text the text string that the styles are applied to\n * @return {Object}\n */\nexport const stylesFromArray = (\n styles: TextStyleArray | TextStyle,\n text: string,\n): TextStyle => {\n if (!Array.isArray(styles)) {\n // clone to prevent mutation\n return cloneStyles(styles);\n }\n const textLines = text.split(reNewline),\n stylesObject: TextStyle = {};\n let charIndex = -1,\n styleIndex = 0;\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n //check if there's a style collection that includes the current character\n if (\n styles[styleIndex] &&\n styles[styleIndex].start <= charIndex &&\n charIndex < styles[styleIndex].end\n ) {\n //create object for line index if it doesn't exist\n stylesObject[i] = stylesObject[i] || {};\n //assign a style at this character's index\n stylesObject[i][c] = { ...styles[styleIndex].style };\n //if character is at the end of the current style collection, move to the next\n if (charIndex === styles[styleIndex].end - 1) {\n styleIndex++;\n }\n }\n }\n }\n return stylesObject;\n};\n"],"names":["hasStyleChanged","prevStyle","thisStyle","forTextSpans","arguments","length","undefined","fill","stroke","strokeWidth","fontSize","fontFamily","fontWeight","fontStyle","textDecorationThickness","textBackgroundColor","deltaY","overline","underline","linethrough","stylesToArray","styles","text","textLines","split","stylesArray","charIndex","cloneStyles","i","chars","graphemeSplit","c","Object","keys","push","start","end","style","stylesFromArray","Array","isArray","reNewline","stylesObject","styleIndex","_objectSpread"],"mappings":"oQAoBaA,EAAkB,SAC7BC,EACAC,GAA+B,IAC/BC,EAAYC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GAAQ,OAEpBH,EAAUM,OAASL,EAAUK,MAC7BN,EAAUO,SAAWN,EAAUM,QAC/BP,EAAUQ,cAAgBP,EAAUO,aACpCR,EAAUS,WAAaR,EAAUQ,UACjCT,EAAUU,aAAeT,EAAUS,YACnCV,EAAUW,aAAeV,EAAUU,YACnCX,EAAUY,YAAcX,EAAUW,WAClCZ,EAAUa,0BAA4BZ,EAAUY,yBAChDb,EAAUc,sBAAwBb,EAAUa,qBAC5Cd,EAAUe,SAAWd,EAAUc,QAC9Bb,IACEF,EAAUgB,WAAaf,EAAUe,UAChChB,EAAUiB,YAAchB,EAAUgB,WAClCjB,EAAUkB,cAAgBjB,EAAUiB,YAAa,EAU1CC,EAAgBA,CAC3BC,EACAC,KAEA,MAAMC,EAAYD,EAAKE,MAAM,MAC3BC,EAAc,GAChB,IAAIC,GAAa,EACfzB,EAAY,CAAA,EAEdoB,EAASM,EAAYN,GAGrB,IAAK,IAAIO,EAAI,EAAGA,EAAIL,EAAUlB,OAAQuB,IAAK,CACzC,MAAMC,EAAQC,EAAcP,EAAUK,IACtC,GAAKP,EAAOO,GAOZ,IAAK,IAAIG,EAAI,EAAGA,EAAIF,EAAMxB,OAAQ0B,IAAK,CACrCL,IACA,MAAMxB,EAAYmB,EAAOO,GAAGG,GAExB7B,GAAa8B,OAAOC,KAAK/B,GAAWG,OAAS,IAC3CL,EAAgBC,EAAWC,GAAW,GACxCuB,EAAYS,KAAK,CACfC,MAAOT,EACPU,IAAKV,EAAY,EACjBW,MAAOnC,IAITuB,EAAYA,EAAYpB,OAAS,GAAG+B,OAGxCnC,EAAYC,GAAa,EAC3B,MAtBEwB,GAAaG,EAAMxB,OACnBJ,EAAY,CAAA,CAsBhB,CACA,OAAOwB,CAAW,EAWPa,EAAkBA,CAC7BjB,EACAC,KAEA,IAAKiB,MAAMC,QAAQnB,GAEjB,OAAOM,EAAYN,GAErB,MAAME,EAAYD,EAAKE,MAAMiB,GAC3BC,EAA0B,CAAA,EAC5B,IAAIhB,GAAa,EACfiB,EAAa,EAEf,IAAK,IAAIf,EAAI,EAAGA,EAAIL,EAAUlB,OAAQuB,IAAK,CACzC,MAAMC,EAAQC,EAAcP,EAAUK,IAGtC,IAAK,IAAIG,EAAI,EAAGA,EAAIF,EAAMxB,OAAQ0B,IAChCL,IAGEL,EAAOsB,IACPtB,EAAOsB,GAAYR,OAAST,GAC5BA,EAAYL,EAAOsB,GAAYP,MAG/BM,EAAad,GAAKc,EAAad,IAAM,CAAA,EAErCc,EAAad,GAAGG,GAAEa,EAAA,CAAA,EAAQvB,EAAOsB,GAAYN,OAEzCX,IAAcL,EAAOsB,GAAYP,IAAM,GACzCO,IAIR,CACA,OAAOD,CAAY"}