UNPKG

fabric

Version:

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

3 lines (2 loc) 4.88 kB
import{config as t}from"../../config.min.mjs";import{escapeXml as e}from"../../util/lang_string.min.mjs";import{colorPropToSVG as i,createSVGRect as n}from"../../util/misc/svgParsing.min.mjs";import{hasStyleChanged as s}from"../../util/misc/textStyles.min.mjs";import{toFixed as o}from"../../util/misc/toFixed.min.mjs";import{FabricObjectSVGExportMixin as r}from"../Object/FabricObjectSVGExportMixin.min.mjs";import{JUSTIFY as h}from"./constants.min.mjs";import{STROKE as l,FILL as a}from"../../constants.min.mjs";import{createRotateMatrix as c}from"../../util/misc/matrix.min.mjs";import{radiansToDegrees as g}from"../../util/misc/radiansDegreesConversion.min.mjs";import{Point as m}from"../../Point.min.mjs";import{matrixToSVG as f}from"../../util/misc/svgExport.min.mjs";const d=/ +/g,p=/"/g;function S(t,e,i,s,o){return`\t\t${n(t,{left:e,top:i,width:s,height:o})}\n`}class x extends r{_toSVG(){const t=this._getSVGLeftTopOffsets(),e=this._getSVGTextAndBg(t.textTop,t.textLeft);return this._wrapSVGTextAndBg(e)}toSVG(t){const e=this._createBaseSVGMarkup(this._toSVG(),{reviver:t,noStyle:!0,withShadow:!0}),i=this.path;return i?e+i._createBaseSVGMarkup(i._toSVG(),{reviver:t,withShadow:!0,additionalTransform:f(this.calcOwnMatrix())}):e}_getSVGLeftTopOffsets(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}}_wrapSVGTextAndBg(t){let{textBgRects:e,textSpans:i}=t;const n=this.getSvgTextDecoration(this);return[e.join(""),'\t\t<text xml:space="preserve" ',`font-family="${this.fontFamily.replace(p,"'")}" `,`font-size="${this.fontSize}" `,this.fontStyle?`font-style="${this.fontStyle}" `:"",this.fontWeight?`font-weight="${this.fontWeight}" `:"",n?`text-decoration="${n}" `:"","rtl"===this.direction?`direction="${this.direction}" `:"",'style="',this.getSvgStyles(!0),'"',this.addPaintOrder()," >",i.join(""),"</text>\n"]}_getSVGTextAndBg(t,e){const i=[],n=[];let s,o=t;this.backgroundColor&&n.push(...S(this.backgroundColor,-this.width/2,-this.height/2,this.width,this.height));for(let t=0,r=this._textLines.length;t<r;t++)s=this._getLineLeftOffset(t),"rtl"===this.direction&&(s+=this.width),(this.textBackgroundColor||this.styleHas("textBackgroundColor",t))&&this._setSVGTextLineBg(n,t,e+s,o),this._setSVGTextLineText(i,t,e+s,o),o+=this.getHeightOfLine(t);return{textSpans:i,textBgRects:n}}_createTextCharSpan(i,n,s,r,h){const l=t.NUM_FRACTION_DIGITS,a=this.getSvgSpanStyles(n,i!==i.trim()||!!i.match(d)),f=a?`style="${a}"`:"",p=n.deltaY,S=p?` dy="${o(p,l)}" `:"",{angle:x,renderLeft:u,renderTop:_,width:T}=h;let y="";if(void 0!==u){const t=T/2;x&&(y=` rotate="${o(g(x),l)}"`);const e=c({angle:g(x)});e[4]=u,e[5]=_;const i=new m(-t,0).transform(e);s=i.x,r=i.y}return`<tspan x="${o(s,l)}" y="${o(r,l)}" ${S}${y}${f}>${e(i)}</tspan>`}_setSVGTextLineText(t,e,i,n){const o=this.getHeightOfLine(e),r=this.textAlign.includes(h),l=this._textLines[e];let a,c,g,m,f,d="",p=0;n+=o*(1-this._fontSizeFraction)/this.lineHeight;for(let o=0,h=l.length-1;o<=h;o++)f=o===h||this.charSpacing||this.path,d+=l[o],g=this.__charBounds[e][o],0===p?(i+=g.kernedWidth-g.width,p+=g.width):p+=g.kernedWidth,r&&!f&&this._reSpaceAndTab.test(l[o])&&(f=!0),f||(a=a||this.getCompleteStyleDeclaration(e,o),c=this.getCompleteStyleDeclaration(e,o+1),f=s(a,c,!0)),f&&(m=this._getStyleDeclaration(e,o),t.push(this._createTextCharSpan(d,m,i,n,g)),d="",a=c,"rtl"===this.direction?i-=p:i+=p,p=0)}_setSVGTextLineBg(t,e,i,n){const s=this._textLines[e],o=this.getHeightOfLine(e)/this.lineHeight;let r,h=0,l=0,a=this.getValueOfPropertyAt(e,0,"textBackgroundColor");for(let c=0;c<s.length;c++){const{left:s,width:g,kernedWidth:m}=this.__charBounds[e][c];r=this.getValueOfPropertyAt(e,c,"textBackgroundColor"),r!==a?(a&&t.push(...S(a,i+l,n,h,o)),l=s,h=g,a=r):h+=m}r&&t.push(...S(a,i+l,n,h,o))}getSvgStyles(e){return`${super.getSvgStyles(e)} text-decoration-thickness: ${o(this.textDecorationThickness*this.getObjectScaling().y/10,t.NUM_FRACTION_DIGITS)}%; white-space: pre;`}getSvgSpanStyles(e,n){const{fontFamily:s,strokeWidth:r,stroke:h,fill:c,fontSize:g,fontStyle:m,fontWeight:f,textDecorationThickness:d,linethrough:p,overline:S,underline:x}=e,u=this.getSvgTextDecoration({underline:null!=x?x:this.underline,overline:null!=S?S:this.overline,linethrough:null!=p?p:this.linethrough}),_=d||this.textDecorationThickness;return[h?i(l,h):"",r?`stroke-width: ${r}; `:"",s?`font-family: ${s.includes("'")||s.includes('"')?s:`'${s}'`}; `:"",g?`font-size: ${g}px; `:"",m?`font-style: ${m}; `:"",f?`font-weight: ${f}; `:"",u?`text-decoration: ${u}; text-decoration-thickness: ${o(_*this.getObjectScaling().y/10,t.NUM_FRACTION_DIGITS)}%; `:"",c?i(a,c):"",n?"white-space: pre; ":""].join("")}getSvgTextDecoration(t){return["overline","underline","line-through"].filter(e=>t[e.replace("-","")]).join(" ")}}export{x as TextSVGExportMixin}; //# sourceMappingURL=TextSVGExportMixin.min.mjs.map