@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.6 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import"../../../../core/has.js";import{rasterizeDash as t}from"../../../../symbols/cim/rasterizingUtils.js";import i from"./RectangleBinPack.js";import s from"../webgl/Rect.js";import{TextureWrapMode as e}from"../../../webgl/enums.js";import{Texture as h}from"../../../webgl/Texture.js";import{TextureDescriptor as a}from"../../../webgl/TextureDescriptor.js";const r="dasharray-";class o{constructor(t,s,e=0){this._size=[],this._mosaicsData=[],this._textures=[],this._dirties=[],this._maxItemSize=0,this._currentPage=0,this._pageWidth=0,this._pageHeight=0,this._mosaicRects={},this.pixelRatio=1,s<=0&&console.error("Sprites mosaic defaultWidth and defaultHeight must be greater than zero!"),this._pageWidth=t,this._pageHeight=s,e>0&&(this._maxItemSize=e),this._binPack=new i(t-4,s-4)}destroy(){this.dispose()}dispose(){this._binPack=null,this._mosaicsData.length=0,this._mosaicRects={};for(const t of this._textures)t&&t.dispose();this._textures.length=0}getWidth(t){return t>=this._size.length?-1:this._size[t][0]}getHeight(t){return t>=this._size.length?-1:this._size[t][1]}getPageSize(t){return t>=this._size.length?null:this._size[t]}setSpriteSource(t){if(this.dispose(),this.pixelRatio=t.devicePixelRatio,0===this._mosaicsData.length){this._binPack=new i(this._pageWidth-4,this._pageHeight-4);const t=Math.floor(this._pageWidth),s=Math.floor(this._pageHeight),e=new Uint32Array(t*s);this._mosaicsData[0]=e,this._dirties.push(!0),this._size.push([this._pageWidth,this._pageHeight]),this._textures.push(void 0)}this._sprites=t}getSpriteItem(t,i=!1){let s,e,h=this._mosaicRects[t];if(h)return h;if(!this._sprites||"loaded"!==this._sprites.loadStatus)return null;if(t&&t.startsWith(r)?([s,e]=this._rasterizeDash(t),i=!0):s=this._sprites.getSpriteInfo(t),!s?.width||!s.height||s.width<0||s.height<0)return null;const a=s.width,o=s.height,[n,_,g]=this._allocateImage(a,o);return n.width<=0?null:(this._copy(n,s,_,g,i,e),h={type:"sprite",rect:n,width:a,height:o,sdf:s.sdf,simplePattern:!1,rasterizationScale:s.pixelRatio??1,samplingMode:"Linear",page:_},this._mosaicRects[t]=h,h)}getSpriteItems(t){const i={};for(const s of t)i[s.name]=this.getSpriteItem(s.name,s.repeat);return i}getMosaicItemPosition(t,i){const s=this.getSpriteItem(t,i),e=s?.rect;if(!e)return null;e.width=s.width,e.height=s.height;const h=s.width,a=s.height,r=2;return{tl:[e.x+r,e.y+r],br:[e.x+r+h,e.y+r+a],page:s.page}}bind(t,i,s=0,r=0){if(s>=this._size.length||s>=this._mosaicsData.length)return;if(!this._textures[s]){const i=new a;i.wrapMode=e.CLAMP_TO_EDGE,i.width=this._size[s][0],i.height=this._size[s][1],this._textures[s]=new h(t,i,new Uint8Array(this._mosaicsData[s].buffer))}const o=this._textures[s];o.setSamplingMode(i),this._dirties[s]&&o.setData(new Uint8Array(this._mosaicsData[s].buffer)),t.bindTexture(o,r),this._dirties[s]=!1}static _copyBits(t,i,s,e,h,a,r,o,n,_,g){let p=e*i+s,c=o*a+r;if(g){c-=a;for(let r=-1;r<=_;r++,p=((r+_)%_+e)*i+s,c+=a)for(let i=-1;i<=n;i++)h[c+i]=t[p+(i+n)%n]}else for(let l=0;l<_;l++){for(let i=0;i<n;i++)h[c+i]=t[p+i];p+=i,c+=a}}_copy(t,i,s,e,h,a){if(!this._sprites||"loaded"!==this._sprites.loadStatus||s>=this._mosaicsData.length)return;const r=new Uint32Array(a?a.buffer:this._sprites.image.buffer),n=this._mosaicsData[s],_=2,g=a?i.width:this._sprites.width;o._copyBits(r,g,i.x,i.y,n,e[0],t.x+_,t.y+_,i.width,i.height,h),this._dirties[s]=!0}_allocateImage(t,e){t+=2,e+=2;const h=Math.max(t,e);if(this._maxItemSize&&this._maxItemSize<h){const i=new s(0,0,t,e);return this._mosaicsData.push(new Uint32Array(t*e)),this._dirties.push(!0),this._size.push([t,e]),this._textures.push(void 0),[i,this._mosaicsData.length-1,[t,e]]}let a=t%4?4-t%4:4,r=e%4?4-e%4:4;1===a&&(a=5),1===r&&(r=5);const o=this._binPack.allocate(t+a,e+r);return o.width<=0?(this._dirties[this._currentPage]||(this._mosaicsData[this._currentPage]=null),this._currentPage=this._mosaicsData.length,this._mosaicsData.push(new Uint32Array(this._pageWidth*this._pageHeight)),this._dirties.push(!0),this._size.push([this._pageWidth,this._pageHeight]),this._textures.push(void 0),this._binPack=new i(this._pageWidth-4,this._pageHeight-4),this._allocateImage(t,e)):[o,this._currentPage,[this._pageWidth,this._pageHeight]]}_rasterizeDash(i){const s=/\[(.*?)\]/,e=i.match(s);if(!e)return null;const h=e[1].split(",").map(Number),a=i.slice(i.lastIndexOf("-")+1),[r,o,n]=t(h,a);return[{x:0,y:0,width:o,height:n,sdf:!0,pixelRatio:1},new Uint8Array(r.buffer)]}}export{o as default};