@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 3.08 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import t from"./RectangleBinPack.js";import e from"../webgl/Rect.js";import{PixelFormat as s,TextureWrapMode as i}from"../../../webgl/enums.js";import{Texture as h}from"../../../webgl/Texture.js";import{TextureDescriptor as r}from"../../../webgl/TextureDescriptor.js";class n{constructor(e,s,i){this.width=0,this.height=0,this._dirties=[],this._glyphData=[],this._currentPage=0,this._glyphIndex={},this._textures=[],this._rangePromises=new Map,this.width=e,this.height=s,this._glyphSource=i,this._binPack=new t(e-4,s-4),this._glyphData.push(new Uint8Array(e*s)),this._dirties.push(!0),this._textures.push(void 0)}getGlyphItems(s,i){const h=[],r=this._glyphSource,n=new Set,o=1/256;for(const t of i){const e=Math.floor(t*o);n.add(e)}const a=[];return n.forEach((t=>{const e=s+t;if(this._rangePromises.has(e))a.push(this._rangePromises.get(e));else{const i=r.getRange(s,t).then((()=>{this._rangePromises.delete(e)}),(()=>{this._rangePromises.delete(e)}));this._rangePromises.set(e,i),a.push(i)}})),Promise.all(a).then((()=>{let n=this._glyphIndex[s];n||(n={},this._glyphIndex[s]=n);for(const o of i){const i=n[o];if(i){h[o]={sdf:!0,rect:i.rect,metrics:i.metrics,page:i.page,code:o};continue}const a=r.getGlyph(s,o);if(!a?.metrics)continue;const l=a.metrics;let c;if(0===l.width)c=new e(0,0,0,0);else{const e=3,s=l.width+2*e,i=l.height+2*e;let h=s%4?4-s%4:4,r=i%4?4-i%4:4;1===h&&(h=5),1===r&&(r=5),c=this._binPack.allocate(s+h,i+r),c.isEmpty&&(this._dirties[this._currentPage]||(this._glyphData[this._currentPage]=null),this._currentPage=this._glyphData.length,this._glyphData.push(new Uint8Array(this.width*this.height)),this._dirties.push(!0),this._textures.push(void 0),this._binPack=new t(this.width-4,this.height-4),c=this._binPack.allocate(s+h,i+r));const n=this._glyphData[this._currentPage],o=a.bitmap;let g,_;if(o)for(let t=0;t<i;t++){g=s*t,_=this.width*(c.y+t+1)+c.x;for(let t=0;t<s;t++)n[_+t+1]=o.at(g+t)}}n[o]={rect:c,metrics:l,tileIDs:null,page:this._currentPage},h[o]={sdf:!0,rect:c,metrics:l,page:this._currentPage,code:o},this._dirties[this._currentPage]=!0}return h}))}removeGlyphs(t){for(const e in this._glyphIndex){const s=this._glyphIndex[e];if(!s)continue;let i;for(const e in s)if(i=s[e],i.tileIDs.delete(t),0===i.tileIDs.size){const t=this._glyphData[i.page],h=i.rect;let r,n;for(let e=0;e<h.height;e++)for(r=this.width*(h.y+e)+h.x,n=0;n<h.width;n++)t[r+n]=0;delete s[e],this._dirties[i.page]=!0}}}bind(t,e,n,o=0){if(!this._textures[n]){const e=new r;e.pixelFormat=s.ALPHA,e.wrapMode=i.CLAMP_TO_EDGE,e.width=this.width,e.height=this.height,this._textures[n]=new h(t,e,new Uint8Array(this.width*this.height))}const a=this._textures[n];a.setSamplingMode(e),this._dirties[n]&&a.setData(this._glyphData[n]),t.bindTexture(a,o),this._dirties[n]=!1}destroy(){this.dispose()}dispose(){this._glyphData.length=0,this._binPack=null;for(const t of this._textures)t&&t.dispose();this._textures.length=0}}export{n as default};