12345 |
- /*
- All material copyright ESRI, All Rights Reserved, unless otherwise specified.
- See https://js.arcgis.com/4.24/esri/copyright.txt for details.
- */
- import{pt2px as t}from"../../core/screenUtils.js";function e(t){return`rgb(${t.slice(0,3).toString()})`}function i(t){return`rgba(${t.slice(0,3).toString()},${t[3]})`}class s{rasterizeText(t,s){this._textRasterizationCanvas||(this._textRasterizationCanvas=document.createElement("canvas"));const r=this._textRasterizationCanvas,o=r.getContext("2d");this._setFontProperties(o,s),this.parameters=s,this.textLines=t.split(/\r?\n/),this.lineHeight=this._computeLineHeight();const h=this._computeTextWidth(o,s),{decoration:a,weight:l}=s.font;this.lineThroughWidthOffset=a&&"line-through"===a?.1*this.lineHeight:0;const d=this.lineHeight*this.textLines.length;r.width=h+2*this.lineThroughWidthOffset,r.height=d,this.renderedLineHeight=Math.round(this.lineHeight*s.pixelRatio),this.renderedHaloSize=s.halo.size*s.pixelRatio,this.renderedWidth=h*s.pixelRatio,this.renderedHeight=d*s.pixelRatio,this.lineThroughWidthOffset*=s.pixelRatio,this.fillStyle=i(s.color),this.haloStyle=e(s.halo.color);const c=this.renderedLineHeight,g=this.renderedHaloSize;this._setFontProperties(o,s);const f=n(o.textAlign,this.renderedWidth)+g,u=g,p=g>0;let x=this.lineThroughWidthOffset,m=0;p&&this._renderHalo(o,f,u,x,m,s),m+=u,x+=f;for(const e of this.textLines)o.globalCompositeOperation="destination-out",o.fillStyle="rgb(0, 0, 0)",o.fillText(e,x,m),o.globalCompositeOperation="source-over",o.fillStyle=this.fillStyle,o.fillText(e,x,m),a&&"none"!==a&&this._renderDecoration(o,x,m,a,l),m+=c;const _=this.renderedWidth+2*this.lineThroughWidthOffset,H=this.renderedHeight,z=o.getImageData(0,0,_,H),w=new Uint8Array(z.data);if(s.premultiplyColors){let t;for(let e=0;e<w.length;e+=4)t=w[e+3]/255,w[e]=w[e]*t,w[e+1]=w[e+1]*t,w[e+2]=w[e+2]*t}return{size:[_,H],image:new Uint32Array(w.buffer),sdf:!1,simplePattern:!1,anchorX:0,anchorY:0}}_renderHalo(t,e,i,s,n,r){const o=this.renderedWidth,h=this.renderedHeight;this._haloRasterizationCanvas||(this._haloRasterizationCanvas=document.createElement("canvas")),this._haloRasterizationCanvas.width=o,this._haloRasterizationCanvas.height=h;const a=this._haloRasterizationCanvas,l=a.getContext("2d");l.clearRect(0,0,o,h),this._setFontProperties(l,r);const{decoration:d,weight:c}=r.font;l.fillStyle=this.haloStyle,l.strokeStyle=this.haloStyle;const g=this.renderedHaloSize<3;l.lineJoin=g?"miter":"round",g?this._renderHaloEmulated(l,e,i,d,c):this._renderHaloNative(l,e,i,d,c),t.globalAlpha=this.parameters.halo.color[3],t.drawImage(a,0,0,o,h,s,n,o,h),t.globalAlpha=1}_renderHaloEmulated(t,e,i,s,n){const o=this.renderedLineHeight,h=this.renderedHaloSize;for(const a of this.textLines){for(const[s,n]of r)t.fillText(a,e+h*s,i+h*n);s&&"none"!==s&&this._renderDecoration(t,e,i,s,n),i+=o}}_renderHaloNative(t,e,i,s,n){const r=this.renderedLineHeight,o=this.renderedHaloSize;for(const h of this.textLines){const a=2*o,l=5,d=.1;for(let r=0;r<l;r++){const o=1-(l-1)*d+r*d;t.lineWidth=o*a,t.strokeText(h,e,i),s&&"none"!==s&&this._renderDecoration(t,e,i,s,n)}i+=r}}_setFontProperties(e,i){const s=i.font,n=`${s.style} ${s.weight} ${t(i.size*i.pixelRatio)}px ${s.family}, sans-serif`;let r;switch(e.font=n,e.textBaseline="top",i.horizontalAlignment){case"left":default:r="left";break;case"right":r="right";break;case"center":r="center"}e.textAlign=r}computeTextSize(t,e){this._textRasterizationCanvas||(this._textRasterizationCanvas=document.createElement("canvas"));const i=this._textRasterizationCanvas,s=i.getContext("2d");this._setFontProperties(s,e),this.parameters=e,this.textLines=t.split(/\r?\n/),this.lineHeight=this._computeLineHeight();const n=this._computeTextWidth(s,e),r=this.lineHeight*this.textLines.length;return i.width=n,i.height=r,[n*e.pixelRatio,r*e.pixelRatio]}_computeTextWidth(t,e){let i=0;for(const n of this.textLines)i=Math.max(i,t.measureText(n).width);const s=e.font;return("italic"===s.style||"oblique"===s.style||"string"==typeof s.weight&&("bold"===s.weight||"bolder"===s.weight)||"number"==typeof s.weight&&s.weight>600)&&(i+=.3*t.measureText("w").width),i+=2*this.parameters.halo.size,Math.round(i)}_computeLineHeight(){let t=1.275*this.parameters.size;const e=this.parameters.font.decoration;return e&&"underline"===e&&(t*=1.3),Math.round(t+2*this.parameters.halo.size)}_renderDecoration(t,e,i,s,n){const r=.9*this.lineHeight,o="bold"===n?.06:"bolder"===n?.09:.04;switch(t.textAlign){case"center":e-=this.renderedWidth/2;break;case"right":e-=this.renderedWidth}const h=t.textBaseline;if("underline"===s)switch(h){case"top":i+=r;break;case"middle":i+=r/2}else if("line-through"===s)switch(h){case"top":i+=r/1.5;break;case"middle":i+=r/3}t.save(),t.beginPath(),t.strokeStyle=t.fillStyle,t.lineWidth=Math.ceil(r*o),t.moveTo(e-this.lineThroughWidthOffset,i),t.lineTo(e+this.renderedWidth+2*this.lineThroughWidthOffset,i),t.stroke(),t.restore()}}function n(t,e){return"center"===t?.5*e:"right"===t?e:0}const r=[];{const t=16;for(let e=0;e<360;e+=360/t)r.push([Math.cos(Math.PI*e/180),Math.sin(Math.PI*e/180)])}export{s as default};
|