fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
3 lines • 16.2 kB
JavaScript
import{_defineProperty as e}from"../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/defineProperty.min.mjs";import{cache as t}from"../../cache.min.mjs";import{BOTTOM as n,CENTER as r,FILL as i,LEFT as a,RIGHT as o}from"../../constants.min.mjs";import{classRegistry as s}from"../../ClassRegistry.min.mjs";import{createCanvasElementFor as c}from"../../util/misc/dom.min.mjs";import{isFiller as l}from"../../util/typeAssertions.min.mjs";import{graphemeSplit as u}from"../../util/lang_string.min.mjs";import{normalizeWs as d}from"../../util/internals/normalizeWhiteSpace.min.mjs";import{JUSTIFY as f,TEXT_DECORATION_THICKNESS as p,additionalProps as m,textDefaultValues as h,textLayoutProperties as g}from"./constants.min.mjs";import{cacheProperties as _}from"../Object/defaultValues.min.mjs";import{applyMixins as v}from"../../util/applyMixins.min.mjs";import{hasStyleChanged as y,stylesFromArray as b,stylesToArray as x}from"../../util/misc/textStyles.min.mjs";import{SHARED_ATTRIBUTES as S}from"../../parser/attributes.min.mjs";import{parseAttributes as C}from"../../parser/parseAttributes.min.mjs";import{getPathSegmentsInfo as w,getPointOnPath as T}from"../../util/path/index.min.mjs";import{StyledText as E}from"./StyledText.min.mjs";import{TextSVGExportMixin as D}from"./TextSVGExportMixin.min.mjs";let O;var k=class s extends E{static getDefaults(){return{...super.getDefaults(),...s.ownDefaults}}constructor(t,n){super(),e(this,`__charBounds`,[]),Object.assign(this,s.ownDefaults),this.setOptions(n),this.styles||(this.styles={}),this.text=t,this.initialized=!0,this.path&&this.setPathInfo(),this.initDimensions(),this.setCoords()}setPathInfo(){let e=this.path;e&&(e.segmentsInfo=w(e.path))}_splitText(){let e=this._splitTextIntoLines(this.text);return this.textLines=e.lines,this._textLines=e.graphemeLines,this._unwrappedTextLines=e._unwrappedLines,this._text=e.graphemeText,e}initDimensions(){this._splitText(),this._clearCache(),this.dirty=!0,this.path?(this.width=this.path.width,this.height=this.path.height):(this.width=this.calcTextWidth()||this.cursorWidth||this.MIN_TEXT_WIDTH,this.height=this.calcTextHeight()),this.textAlign.includes(`justify`)&&this.enlargeSpaces()}enlargeSpaces(){let e,t,n,r,i,a,o;for(let s=0,c=this._textLines.length;s<c;s++)if((this.textAlign===`justify`||s!==c-1&&!this.isEndOfWrapping(s))&&(r=0,i=this._textLines[s],t=this.getLineWidth(s),t<this.width&&(o=this.textLines[s].match(this._reSpacesAndTabs)))){n=o.length,e=(this.width-t)/n;for(let t=0;t<=i.length;t++)a=this.__charBounds[s][t],this._reSpaceAndTab.test(i[t])?(a.width+=e,a.kernedWidth+=e,a.left+=r,r+=e):a.left+=r}}isEndOfWrapping(e){return e===this._textLines.length-1}missingNewlineOffset(e){return 1}get2DCursorLocation(e,t){let n=t?this._unwrappedTextLines:this._textLines,r;for(r=0;r<n.length;r++){if(e<=n[r].length)return{lineIndex:r,charIndex:e};e-=n[r].length+this.missingNewlineOffset(r,t)}return{lineIndex:r-1,charIndex:n[r-1].length<e?n[r-1].length:e}}toString(){return`#<Text (${this.complexity()}): { "text": "${this.text}", "fontFamily": "${this.fontFamily}" }>`}_getCacheCanvasDimensions(){let e=super._getCacheCanvasDimensions(),t=this.fontSize;return e.width+=t*e.zoomX,e.height+=t*e.zoomY,e}_render(e){let t=this.path;t&&!t.isNotVisible()&&t._render(e),this._setTextStyles(e),this._renderTextLinesBackground(e),this._renderTextDecoration(e,`underline`),this._renderText(e),this._renderTextDecoration(e,`overline`),this._renderTextDecoration(e,`linethrough`)}_renderText(e){this.paintFirst===`stroke`?(this._renderTextStroke(e),this._renderTextFill(e)):(this._renderTextFill(e),this._renderTextStroke(e))}_setTextStyles(e,t,i){if(e.textBaseline=`alphabetic`,this.path)switch(this.pathAlign){case r:e.textBaseline=`middle`;break;case`ascender`:e.textBaseline=`top`;break;case`descender`:e.textBaseline=n}e.font=this._getFontDeclaration(t,i)}calcTextWidth(){let e=this.getLineWidth(0);for(let t=1,n=this._textLines.length;t<n;t++){let n=this.getLineWidth(t);n>e&&(e=n)}return e}_renderTextLine(e,t,n,r,i,a){this._renderChars(e,t,n,r,i,a)}_renderTextLinesBackground(e){if(!this.textBackgroundColor&&!this.styleHas(`textBackgroundColor`))return;let t=e.fillStyle,n=this._getLeftOffset(),r=this._getTopOffset();for(let t=0,i=this._textLines.length;t<i;t++){let i=this.getHeightOfLine(t);if(!this.textBackgroundColor&&!this.styleHas(`textBackgroundColor`,t)){r+=i;continue}let a=this._textLines[t].length,o=this._getLineLeftOffset(t),s,c,l=0,u=0,d=this.getValueOfPropertyAt(t,0,`textBackgroundColor`),f=this.getHeightOfLineImpl(t);for(let i=0;i<a;i++){let a=this.__charBounds[t][i];c=this.getValueOfPropertyAt(t,i,`textBackgroundColor`),this.path?(e.save(),e.translate(a.renderLeft,a.renderTop),e.rotate(a.angle),e.fillStyle=c,c&&e.fillRect(-a.width/2,-f*(1-this._fontSizeFraction),a.width,f),e.restore()):c===d?l+=a.kernedWidth:(s=n+o+u,this.direction===`rtl`&&(s=this.width-s-l),e.fillStyle=d,d&&e.fillRect(s,r,l,f),u=a.left,l=a.width,d=c)}c&&!this.path&&(s=n+o+u,this.direction===`rtl`&&(s=this.width-s-l),e.fillStyle=c,e.fillRect(s,r,l,f)),r+=i}e.fillStyle=t,this._removeShadow(e)}_measureChar(e,n,r,i){let a=t.getFontCache(n),o=this._getFontDeclaration(n),s=r?r+e:e,l=r&&o===this._getFontDeclaration(i),u=n.fontSize/this.CACHE_FONT_SIZE,d,f,p,m;if(r&&a.has(r)&&(p=a.get(r)),a.has(e)&&(m=d=a.get(e)),l&&a.has(s)&&(f=a.get(s),m=f-p),d===void 0||p===void 0||f===void 0){let t=(O||(O=c({width:0,height:0}).getContext(`2d`)),O);this._setTextStyles(t,n,!0),d===void 0&&(m=d=t.measureText(e).width,a.set(e,d)),p===void 0&&l&&r&&(p=t.measureText(r).width,a.set(r,p)),l&&f===void 0&&(f=t.measureText(s).width,a.set(s,f),m=f-p)}return{width:d*u,kernedWidth:m*u}}getHeightOfChar(e,t){return this.getValueOfPropertyAt(e,t,`fontSize`)}measureLine(e){let t=this._measureLine(e);return this.charSpacing!==0&&(t.width-=this._getWidthOfCharSpacing()),t.width<0&&(t.width=0),t}_measureLine(e){let t,n,i=0,s=this.pathSide===o,c=this.path,l=this._textLines[e],u=l.length,d=Array(u);this.__charBounds[e]=d;for(let r=0;r<u;r++){let a=l[r];n=this._getGraphemeBox(a,e,r,t),d[r]=n,i+=n.kernedWidth,t=a}if(d[u]={left:n?n.left+n.width:0,width:0,kernedWidth:0,height:this.fontSize,deltaY:0},c&&c.segmentsInfo){let e=0,t=c.segmentsInfo[c.segmentsInfo.length-1].length;switch(this.textAlign){case a:e=s?t-i:0;break;case r:e=(t-i)/2;break;case o:e=s?0:t-i}e+=this.pathStartOffset*(s?-1:1);for(let r=s?u-1:0;s?r>=0:r<u;s?r--:r++)n=d[r],e>t?e%=t:e<0&&(e+=t),this._setGraphemeOnPath(e,n),e+=n.kernedWidth}return{width:i,numOfSpaces:0}}_setGraphemeOnPath(e,t){let n=e+t.kernedWidth/2,r=this.path,i=T(r.path,n,r.segmentsInfo);t.renderLeft=i.x-r.pathOffset.x,t.renderTop=i.y-r.pathOffset.y,t.angle=i.angle+(this.pathSide===`right`?Math.PI:0)}_getGraphemeBox(e,t,n,r,i){let a=this.getCompleteStyleDeclaration(t,n),o=r?this.getCompleteStyleDeclaration(t,n-1):{},s=this._measureChar(e,a,r,o),c,l=s.kernedWidth,u=s.width;this.charSpacing!==0&&(c=this._getWidthOfCharSpacing(),u+=c,l+=c);let d={width:u,left:0,height:a.fontSize,kernedWidth:l,deltaY:a.deltaY};if(n>0&&!i){let e=this.__charBounds[t][n-1];d.left=e.left+e.width+s.kernedWidth-s.width}return d}getHeightOfLineImpl(e){let t=this.__lineHeights;if(t[e])return t[e];let n=this.getHeightOfChar(e,0);for(let t=1,r=this._textLines[e].length;t<r;t++)n=Math.max(this.getHeightOfChar(e,t),n);return t[e]=n*this._fontSizeMult}getHeightOfLine(e){return this.getHeightOfLineImpl(e)*this.lineHeight}calcTextHeight(){let e=0;for(let t=0,n=this._textLines.length;t<n;t++)e+=t===n-1?this.getHeightOfLineImpl(t):this.getHeightOfLine(t);return e}_getLeftOffset(){return this.direction===`ltr`?-this.width/2:this.width/2}_getTopOffset(){return-this.height/2}_renderTextCommon(e,t){e.save();let n=0,r=this._getLeftOffset(),i=this._getTopOffset();for(let a=0,o=this._textLines.length;a<o;a++)this._renderTextLine(t,e,this._textLines[a],r+this._getLineLeftOffset(a),i+n+this.getHeightOfLineImpl(a),a),n+=this.getHeightOfLine(a);e.restore()}_renderTextFill(e){(this.fill||this.styleHas(`fill`))&&this._renderTextCommon(e,`fillText`)}_renderTextStroke(e){(this.stroke&&this.strokeWidth!==0||!this.isEmptyStyles())&&(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e),e.save(),this._setLineDash(e,this.strokeDashArray),e.beginPath(),this._renderTextCommon(e,`strokeText`),e.closePath(),e.restore())}_renderChars(e,t,n,r,i,s){let c=this.textAlign.includes(f),l=this.path,u=!c&&this.charSpacing===0&&this.isEmptyStyles(s)&&!l,d=this.direction===`ltr`,p=this.direction===`ltr`?1:-1,m=t.direction,h,g,_,v,b,x=``,S=0;if(t.save(),m!==this.direction&&(t.canvas.setAttribute(`dir`,d?`ltr`:`rtl`),t.direction=d?`ltr`:`rtl`,t.textAlign=d?a:o),i-=this.getHeightOfLineImpl(s)*this._fontSizeFraction,u)return this._renderChar(e,t,s,0,n.join(``),r,i),void t.restore();for(let a=0,o=n.length-1;a<=o;a++)v=a===o||this.charSpacing||l,x+=n[a],_=this.__charBounds[s][a],S===0?(r+=p*(_.kernedWidth-_.width),S+=_.width):S+=_.kernedWidth,c&&!v&&this._reSpaceAndTab.test(n[a])&&(v=!0),v||(h=h||this.getCompleteStyleDeclaration(s,a),g=this.getCompleteStyleDeclaration(s,a+1),v=y(h,g,!1)),v&&(l?(t.save(),t.translate(_.renderLeft,_.renderTop),t.rotate(_.angle),this._renderChar(e,t,s,a,x,-S/2,0),t.restore()):(b=r,this._renderChar(e,t,s,a,x,b,i)),x=``,h=g,r+=p*S,S=0);t.restore()}_applyPatternGradientTransformText(e){let t=this.width+this.strokeWidth,n=this.height+this.strokeWidth,r=c({width:t,height:n}),i=r.getContext(`2d`);return r.width=t,r.height=n,i.beginPath(),i.moveTo(0,0),i.lineTo(t,0),i.lineTo(t,n),i.lineTo(0,n),i.closePath(),i.translate(t/2,n/2),i.fillStyle=e.toLive(i),this._applyPatternGradientTransform(i,e),i.fill(),i.createPattern(r,`no-repeat`)}handleFiller(e,t,n){let r,i;return l(n)?n.gradientUnits===`percentage`||n.gradientTransform||n.patternTransform?(r=-this.width/2,i=-this.height/2,e.translate(r,i),e[t]=this._applyPatternGradientTransformText(n),{offsetX:r,offsetY:i}):(e[t]=n.toLive(e),this._applyPatternGradientTransform(e,n)):(e[t]=n,{offsetX:0,offsetY:0})}_setStrokeStyles(e,{stroke:t,strokeWidth:n}){return e.lineWidth=n,e.lineCap=this.strokeLineCap,e.lineDashOffset=this.strokeDashOffset,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,this.handleFiller(e,`strokeStyle`,t)}_setFillStyles(e,{fill:t}){return this.handleFiller(e,`fillStyle`,t)}_renderChar(e,t,n,r,i,a,o){let s=this._getStyleDeclaration(n,r),c=this.getCompleteStyleDeclaration(n,r),l=e===`fillText`&&c.fill,u=e===`strokeText`&&c.stroke&&c.strokeWidth;if(u||l){if(t.save(),t.font=this._getFontDeclaration(c),s.textBackgroundColor&&this._removeShadow(t),s.deltaY&&(o+=s.deltaY),l){let e=this._setFillStyles(t,c);t.fillText(i,a-e.offsetX,o-e.offsetY)}if(u){let e=this._setStrokeStyles(t,c);t.strokeText(i,a-e.offsetX,o-e.offsetY)}t.restore()}}setSuperscript(e,t){this._setScript(e,t,this.superscript)}setSubscript(e,t){this._setScript(e,t,this.subscript)}_setScript(e,t,n){let r=this.get2DCursorLocation(e,!0),i=this.getValueOfPropertyAt(r.lineIndex,r.charIndex,`fontSize`),a=this.getValueOfPropertyAt(r.lineIndex,r.charIndex,`deltaY`),o={fontSize:i*n.size,deltaY:a+i*n.baseline};this.setSelectionStyles(o,e,t)}_getLineLeftOffset(e){let t=this.getLineWidth(e),n=this.width-t,r=this.textAlign,i=this.direction,a=this.isEndOfWrapping(e),o=0;return r===`justify`||r===`justify-center`&&!a||r===`justify-right`&&!a||r===`justify-left`&&!a?0:(r===`center`&&(o=n/2),r===`right`&&(o=n),r===`justify-center`&&(o=n/2),r===`justify-right`&&(o=n),i===`rtl`&&(r===`right`||r===`justify-right`?o=0:r===`left`||r===`justify-left`?o=-n:r!==`center`&&r!==`justify-center`||(o=-n/2)),o)}_clearCache(){this._forceClearCache=!1,this.__lineWidths=[],this.__lineHeights=[],this.__charBounds=[]}getLineWidth(e){if(this.__lineWidths[e]!==void 0)return this.__lineWidths[e];let{width:t}=this.measureLine(e);return this.__lineWidths[e]=t,t}_getWidthOfCharSpacing(){return this.charSpacing===0?0:this.fontSize*this.charSpacing/1e3}getValueOfPropertyAt(e,t,n){var r;return(r=this._getStyleDeclaration(e,t)[n])==null?this[n]:r}_renderTextDecoration(e,t){if(!this[t]&&!this.styleHas(t))return;let n=this._getTopOffset(),r=this._getLeftOffset(),a=this.path,o=this._getWidthOfCharSpacing(),s=t===`linethrough`?.5:t===`overline`?1:0,c=this.offsets[t];for(let l=0,u=this._textLines.length;l<u;l++){let u=this.getHeightOfLine(l);if(!this[t]&&!this.styleHas(t,l)){n+=u;continue}let d=this._textLines[l],f=u/this.lineHeight,m=this._getLineLeftOffset(l),h=0,g=0,_=this.getValueOfPropertyAt(l,0,t),v=this.getValueOfPropertyAt(l,0,i),y=this.getValueOfPropertyAt(l,0,`textDecorationColor`)||v,b=this.getValueOfPropertyAt(l,0,p),x=_,S=v,C=y,w=b,T=n+f*(1-this._fontSizeFraction),E=this.getHeightOfChar(l,0),D=this.getValueOfPropertyAt(l,0,`deltaY`);for(let n=0,o=d.length;n<o;n++){let o=this.__charBounds[l][n];x=this.getValueOfPropertyAt(l,n,t),S=this.getValueOfPropertyAt(l,n,i),C=this.getValueOfPropertyAt(l,n,`textDecorationColor`)||S,w=this.getValueOfPropertyAt(l,n,p);let u=this.getHeightOfChar(l,n),d=this.getValueOfPropertyAt(l,n,`deltaY`);if(a&&x&&S){let t=this.fontSize*w/1e3;e.save(),e.fillStyle=C,e.translate(o.renderLeft,o.renderTop),e.rotate(o.angle),e.fillRect(-o.kernedWidth/2,c*u+d-s*t,o.kernedWidth,t),e.restore()}else if((x!==_||S!==v||C!==y||u!==E||w!==b||d!==D)&&g>0){let t=this.fontSize*b/1e3,n=r+m+h;this.direction===`rtl`&&(n=this.width-n-g),_&&y&&b&&(e.fillStyle=y,e.fillRect(n,T+c*E+D-s*t,g,t)),h=o.left,g=o.width,_=x,y=C,b=w,v=S,E=u,D=d}else g+=o.kernedWidth}let O=r+m+h;this.direction===`rtl`&&(O=this.width-O-g),e.fillStyle=C;let k=this.fontSize*w/1e3;x&&C&&w&&e.fillRect(O,T+c*E+D-s*k,g-o,k),n+=u}this._removeShadow(e)}_getFontDeclaration({fontFamily:e=this.fontFamily,fontStyle:t=this.fontStyle,fontWeight:n=this.fontWeight,fontSize:r=this.fontSize}={},i){let a=e.includes(`'`)||e.includes(`"`)||e.includes(`,`)||s.genericFonts.includes(e.toLowerCase())?e:`"${e}"`;return[t,n,`${i?this.CACHE_FONT_SIZE:r}px`,a].join(` `)}render(e){this.visible&&(this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(this._forceClearCache&&this.initDimensions(),super.render(e)))}graphemeSplit(e){return u(e)}_splitTextIntoLines(e){let t=e.split(this._reNewline),n=Array(t.length),r=[`
`],i=[];for(let e=0;e<t.length;e++)n[e]=this.graphemeSplit(t[e]),i=i.concat(n[e],r);return i.pop(),{_unwrappedLines:n,lines:t,graphemeText:i,graphemeLines:n}}toObject(e=[]){return{...super.toObject([...m,...e]),styles:x(this.styles,this.text),...this.path?{path:this.path.toObject()}:{}}}set(e,t){let{textLayoutProperties:n}=this.constructor;super.set(e,t);let r=!1,i=!1;if(typeof e==`object`)for(let t in e)t===`path`&&this.setPathInfo(),r=r||n.includes(t),i=i||t===`path`;else r=n.includes(e),i=e===`path`;return i&&this.setPathInfo(),r&&this.initialized&&(this.initDimensions(),this.setCoords()),this}complexity(){return 1}static async fromElement(e,t,n){let r=C(e,s.ATTRIBUTE_NAMES,n),{textAnchor:i=a,textDecoration:o=``,dx:c=0,dy:l=0,top:u=0,left:f=0,fontSize:p=16,strokeWidth:m=1,...h}={...t,...r},g=new this(d(e.textContent||``).trim(),{left:f+c,top:u+l,underline:o.includes(`underline`),overline:o.includes(`overline`),linethrough:o.includes(`line-through`),strokeWidth:0,fontSize:p,...h}),_=g.getScaledHeight()/g.height,v=((g.height+g.strokeWidth)*g.lineHeight-g.height)*_,y=g.getScaledHeight()+v,b=0;return i===`center`&&(b=g.getScaledWidth()/2),i===`right`&&(b=g.getScaledWidth()),g.set({left:g.left-b,top:g.top-(y-g.fontSize*(.07+g._fontSizeFraction))/g.lineHeight,strokeWidth:m}),g}static fromObject(e){return this._fromObject({...e,styles:b(e.styles||{},e.text)},{extraParam:`text`})}};e(k,`textLayoutProperties`,g),e(k,`cacheProperties`,[..._,...m]),e(k,`ownDefaults`,h),e(k,`type`,`Text`),e(k,`genericFonts`,[`serif`,`sans-serif`,`monospace`,`cursive`,`fantasy`,`system-ui`,`ui-serif`,`ui-sans-serif`,`ui-monospace`,`ui-rounded`,`math`,`emoji`,`fangsong`]),e(k,`ATTRIBUTE_NAMES`,S.concat(`x`,`y`,`dx`,`dy`,`font-family`,`font-style`,`font-weight`,`font-size`,`letter-spacing`,`text-decoration`,`text-decoration-thickness`,`text-decoration-color`,`text-anchor`)),v(k,[D]),s.setClass(k),s.setSVGClass(k);export{k as FabricText};
//# sourceMappingURL=Text.min.mjs.map