UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 4.39 kB
import{rasterizeDash as t}from"../../../../symbols/cim/rasterizingUtils.js";import i from"./RectangleBinPack.js";import e from"../webgl/Rect.js";import{PixelFormat as s,PixelType as h,TextureWrapMode as a}from"../../../webgl/enums.js";import{Texture as r}from"../../../webgl/Texture.js";const o="dasharray-";class n{constructor(t,e,s=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,(t<=0||e<=0)&&console.error("Sprites mosaic defaultWidth and defaultHeight must be greater than zero!"),this._pageWidth=t,this._pageHeight=e,s>0&&(this._maxItemSize=s),this._binPack=new i(t-4,e-4)}dispose(){this._binPack=null,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),e=Math.floor(this._pageHeight),s=new Uint32Array(t*e);this._mosaicsData[0]=s,this._dirties.push(!0),this._size.push([this._pageWidth,this._pageHeight]),this._textures.push(void 0)}this._sprites=t}getSpriteItem(t,i=!1){let e,s,h=this._mosaicRects[t];if(h)return h;if(!this._sprites||"loaded"!==this._sprites.loadStatus)return null;if(t&&t.startsWith(o)?([e,s]=this._rasterizeDash(t),i=!0):e=this._sprites.getSpriteInfo(t),!e||!e.width||!e.height||e.width<0||e.height<0)return null;const a=e.width,r=e.height,[n,_,g]=this._allocateImage(a,r);return n.width<=0?null:(this._copy(n,e,_,g,i,s),h={rect:n,width:a,height:r,sdf:e.sdf,simplePattern:!1,pixelRatio:e.pixelRatio,page:_},this._mosaicRects[t]=h,h)}getSpriteItems(t){const i={};for(const e of t)i[e.name]=this.getSpriteItem(e.name,e.repeat);return i}getMosaicItemPosition(t,i){const e=this.getSpriteItem(t,i),s=e&&e.rect;if(!s)return null;s.width=e.width,s.height=e.height;const h=e.width,a=e.height,r=2;return{tl:[s.x+r,s.y+r],br:[s.x+r+h,s.y+r+a],page:e.page}}bind(t,i,e=0,o=0){if(e>=this._size.length||e>=this._mosaicsData.length)return;this._textures[e]||(this._textures[e]=new r(t,{pixelFormat:s.RGBA,dataType:h.UNSIGNED_BYTE,wrapMode:a.CLAMP_TO_EDGE,width:this._size[e][0],height:this._size[e][1]},new Uint8Array(this._mosaicsData[e].buffer)));const n=this._textures[e];n.setSamplingMode(i),this._dirties[e]&&n.setData(new Uint8Array(this._mosaicsData[e].buffer)),t.bindTexture(n,o),this._dirties[e]=!1}static _copyBits(t,i,e,s,h,a,r,o,n,_,g){let c=s*i+e,l=o*a+r;if(g){l-=a;for(let r=-1;r<=_;r++,c=((r+_)%_+s)*i+e,l+=a)for(let i=-1;i<=n;i++)h[l+i]=t[c+(i+n)%n]}else for(let p=0;p<_;p++){for(let i=0;i<n;i++)h[l+i]=t[c+i];c+=i,l+=a}}_copy(t,i,e,s,h,a){if(!this._sprites||"loaded"!==this._sprites.loadStatus||e>=this._mosaicsData.length)return;const r=new Uint32Array(a?a.buffer:this._sprites.image.buffer),o=this._mosaicsData[e];o&&r||console.error("Source or target images are uninitialized!");const _=2,g=a?i.width:this._sprites.width;n._copyBits(r,g,i.x,i.y,o,s[0],t.x+_,t.y+_,i.width,i.height,h),this._dirties[e]=!0}_allocateImage(t,s){t+=2,s+=2;const h=Math.max(t,s);if(this._maxItemSize&&this._maxItemSize<h){const i=new e(0,0,t,s);return this._mosaicsData.push(new Uint32Array(t*s)),this._dirties.push(!0),this._size.push([t,s]),this._textures.push(void 0),[i,this._mosaicsData.length-1,[t,s]]}let a=t%4?4-t%4:4,r=s%4?4-s%4:4;1===a&&(a=5),1===r&&(r=5);const o=this._binPack.allocate(t+a,s+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,s)):[o,this._currentPage,[this._pageWidth,this._pageHeight]]}_rasterizeDash(i){const e=/\[(.*?)\]/,s=i.match(e);if(!s)return null;const h=s[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{n as default};