UNPKG

fabric

Version:

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

3 lines (2 loc) 4.4 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 o}from"../../util/misc/textStyles.min.mjs";import{toFixed as s}from"../../util/misc/toFixed.min.mjs";import{FabricObjectSVGExportMixin as h}from"../Object/FabricObjectSVGExportMixin.min.mjs";import{JUSTIFY as r}from"./constants.min.mjs";import{STROKE as c,FILL as a}from"../../constants.min.mjs";const l=/ +/g,g=/"/g;function f(t,e,i,o,s){return"\t\t".concat(n(t,{left:e,top:i,width:o,height:s}),"\n")}class S extends h{_toSVG(){const t=this._getSVGLeftTopOffsets(),e=this._getSVGTextAndBg(t.textTop,t.textLeft);return this._wrapSVGTextAndBg(e)}toSVG(t){return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,noStyle:!0,withShadow:!0})}_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" ',this.fontFamily?'font-family="'.concat(this.fontFamily.replace(g,"'"),'" '):"",this.fontSize?'font-size="'.concat(this.fontSize,'" '):"",this.fontStyle?'font-style="'.concat(this.fontStyle,'" '):"",this.fontWeight?'font-weight="'.concat(this.fontWeight,'" '):"",n?'text-decoration="'.concat(n,'" '):"","rtl"===this.direction?'direction="'.concat(this.direction,'" '):"",'style="',this.getSvgStyles(!0),'"',this.addPaintOrder()," >",i.join(""),"</text>\n"]}_getSVGTextAndBg(t,e){const i=[],n=[];let o,s=t;this.backgroundColor&&n.push(...f(this.backgroundColor,-this.width/2,-this.height/2,this.width,this.height));for(let t=0,h=this._textLines.length;t<h;t++)o=this._getLineLeftOffset(t),"rtl"===this.direction&&(o+=this.width),(this.textBackgroundColor||this.styleHas("textBackgroundColor",t))&&this._setSVGTextLineBg(n,t,e+o,s),this._setSVGTextLineText(i,t,e+o,s),s+=this.getHeightOfLine(t);return{textSpans:i,textBgRects:n}}_createTextCharSpan(i,n,o,h){const r=this.getSvgSpanStyles(n,i!==i.trim()||!!i.match(l)),c=r?'style="'.concat(r,'"'):"",a=n.deltaY,g=a?' dy="'.concat(s(a,t.NUM_FRACTION_DIGITS),'" '):"";return'<tspan x="'.concat(s(o,t.NUM_FRACTION_DIGITS),'" y="').concat(s(h,t.NUM_FRACTION_DIGITS),'" ').concat(g).concat(c,">").concat(e(i),"</tspan>")}_setSVGTextLineText(t,e,i,n){const s=this.getHeightOfLine(e),h=this.textAlign.includes(r),c=this._textLines[e];let a,l,g,f,S,d="",p=0;n+=s*(1-this._fontSizeFraction)/this.lineHeight;for(let s=0,r=c.length-1;s<=r;s++)S=s===r||this.charSpacing,d+=c[s],g=this.__charBounds[e][s],0===p?(i+=g.kernedWidth-g.width,p+=g.width):p+=g.kernedWidth,h&&!S&&this._reSpaceAndTab.test(c[s])&&(S=!0),S||(a=a||this.getCompleteStyleDeclaration(e,s),l=this.getCompleteStyleDeclaration(e,s+1),S=o(a,l,!0)),S&&(f=this._getStyleDeclaration(e,s),t.push(this._createTextCharSpan(d,f,i,n)),d="",a=l,"rtl"===this.direction?i-=p:i+=p,p=0)}_setSVGTextLineBg(t,e,i,n){const o=this._textLines[e],s=this.getHeightOfLine(e)/this.lineHeight;let h,r=0,c=0,a=this.getValueOfPropertyAt(e,0,"textBackgroundColor");for(let l=0;l<o.length;l++){const{left:o,width:g,kernedWidth:S}=this.__charBounds[e][l];h=this.getValueOfPropertyAt(e,l,"textBackgroundColor"),h!==a?(a&&t.push(...f(a,i+c,n,r,s)),c=o,r=g,a=h):r+=S}h&&t.push(...f(a,i+c,n,r,s))}_getSVGLineTopOffset(t){let e,i=0;for(e=0;e<t;e++)i+=this.getHeightOfLine(e);const n=this.getHeightOfLine(e);return{lineTop:i,offset:(this._fontSizeMult-this._fontSizeFraction)*n/(this.lineHeight*this._fontSizeMult)}}getSvgStyles(t){return"".concat(super.getSvgStyles(t)," white-space: pre;")}getSvgSpanStyles(t,e){const{fontFamily:n,strokeWidth:o,stroke:s,fill:h,fontSize:r,fontStyle:l,fontWeight:g,deltaY:f}=t,S=this.getSvgTextDecoration(t);return[s?i(c,s):"",o?"stroke-width: ".concat(o,"; "):"",n?"font-family: ".concat(n.includes("'")||n.includes('"')?n:"'".concat(n,"'"),"; "):"",r?"font-size: ".concat(r,"px; "):"",l?"font-style: ".concat(l,"; "):"",g?"font-weight: ".concat(g,"; "):"",S?"text-decoration: ".concat(S,"; "):S,h?i(a,h):"",f?"baseline-shift: ".concat(-f,"; "):"",e?"white-space: pre; ":""].join("")}getSvgTextDecoration(t){return["overline","underline","line-through"].filter((e=>t[e.replace("-","")])).join(" ")}}export{S as TextSVGExportMixin}; //# sourceMappingURL=TextSVGExportMixin.min.mjs.map