12345 |
- /*
- All material copyright ESRI, All Rights Reserved, unless otherwise specified.
- See https://js.arcgis.com/4.25/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{constructor(t){t&&(this._textRasterizationCanvas=t)}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;const c=s.color??[0,0,0,0],_=s.halo&&s.halo.color?s.halo.color:[0,0,0,0];this._fillStyle=i(c),this._haloStyle=e(_);const g=this._renderedLineHeight,f=this._renderedHaloSize;o.save(),o.clearRect(0,0,r.width,r.height),this._setFontProperties(o,s);const u=n(o.textAlign,this._renderedWidth)+f,p=f,x=f>0;let m=this._lineThroughWidthOffset,b=0;x&&this._renderHalo(o,u,p,m,b,s),b+=p,m+=u;for(const e of this._textLines)x?(o.globalCompositeOperation="destination-out",o.fillStyle="rgb(0, 0, 0)",o.fillText(e,m,b),o.globalCompositeOperation="source-over",o.fillStyle=this._fillStyle,o.fillText(e,m,b)):(o.fillStyle=this._fillStyle,o.fillText(e,m,b)),a&&"none"!==a&&this._renderDecoration(o,m,b,a,l),b+=g;o.restore();const z=this._renderedWidth+2*this._lineThroughWidthOffset,w=this._renderedHeight,v=o.getImageData(0,0,z,w),H=new Uint8Array(v.data);if(s.premultiplyColors){let t;for(let e=0;e<H.length;e+=4)t=H[e+3]/255,H[e]=H[e]*t,H[e+1]=H[e+1]*t,H[e+2]=H[e+2]*t}let y,R;switch(s.horizontalAlignment){case"left":y=-.5;break;case"right":y=.5;break;default:y=0}switch(s.verticalAlignment){case"bottom":R=-.5;break;case"top":R=.5;break;default:R=0}return{size:[z,w],image:new Uint32Array(H.buffer),sdf:!1,simplePattern:!1,anchorX:y,anchorY:R,canvas:r}}_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,l.lineJoin="round",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}_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)*a;t.lineWidth=o,t.strokeText(h,e,i),s&&"none"!==s&&this._renderDecoration(t,e,i,s,n,o)}i+=r}}_setFontProperties(e,i){const s=Math.max(i.size,.5),n=i.font,r=`${n.style} ${n.weight} ${t(s*i.pixelRatio).toFixed(1)}px ${n.family}, sans-serif`;let o;switch(e.font=r,e.textBaseline="top",i.horizontalAlignment){case"left":default:o="left";break;case"right":o="right";break;case"center":o="center"}e.textAlign=o}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,r){const o=.9*this._lineHeight,h="bold"===n?.06:"bolder"===n?.09:.04;switch(t.textAlign){case"center":e-=this._renderedWidth/2;break;case"right":e-=this._renderedWidth}const a=t.textBaseline;if("underline"===s)switch(a){case"top":i+=o;break;case"middle":i+=o/2}else if("line-through"===s)switch(a){case"top":i+=o/1.5;break;case"middle":i+=o/3}const l=r?1.5*r:Math.ceil(o*h);t.save(),t.beginPath(),t.strokeStyle=t.fillStyle,t.lineWidth=l,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}export{s as default};
|