@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 7.81 kB
JavaScript
import e from"../../../../config.js";import t from"../../../../request.js";import{bidiText as i}from"../../../../core/BidiText.js";import s from"../../../../core/Error.js";import{getFullyQualifiedFontName as r}from"../../../../core/fontUtils.js";import o from"../../../../core/Logger.js";import{nextPowerOfTwo as n}from"../../../../core/mathUtils.js";import{isNone as a,isSome as h}from"../../../../core/maybe.js";import{throwIfAborted as c,isAbortError as u}from"../../../../core/promiseUtils.js";import{pt2px as d}from"../../../../core/screenUtils.js";import{s as m}from"../../../../chunks/vec2.js";import{c as l}from"../../../../chunks/vec2f32.js";import g from"../../../../symbols/cim/Rasterizer.js";import{TEXTURE_BINDING_GLYPH_ATLAS as p,TEXTURE_BINDING_SPRITE_ATLAS as f,SPRITE_PADDING as _,PATTERN_FILL_RASTERIZATION_SCALE as w}from"./definitions.js";import{MosaicType as y}from"./enums.js";import M from"./GlyphMosaic.js";import I from"./GlyphSource.js";import z from"./SDFConverter.js";import T from"./SpriteMosaic.js";import{is3D as R,charCodes as v,isSimple as j,isSVGResource as x,isImageResource as S,isMarkerPlacementInsidePolygon as b,shouldRepeat as P,getUrl as U,getPMSResourceSize as B,isGIF as G,isPNG as q,isSVGImage as A}from"./Utils.js";import{AnimatableTextureResource as C}from"./animatedFormats/AnimatableTextureResource.js";import{resize as E}from"./animatedFormats/utils.js";import{ok as F}from"./util/Result.js";import{keyFromSymbol as L}from"./util/symbolUtils.js";import{QueueProcessor as N}from"../../../support/QueueProcessor.js";import{TextureSamplingMode as $}from"../../../webgl/enums.js";const k=l(),H="arial-unicode-ms-regular",O=126,Q=o.getLogger("esri.views.2d.engine.webgl.TextureManager");function V(e,t){const i=Math.round(d(t)*window.devicePixelRatio),s=i>=128?2:4;return Math.min(e,i*s)}const Y=(e,t,i)=>Q.error(new s(e,t,i));class D{static fromMosaic(e,t){return new D(e,t.page,t.sdf)}constructor(e,t,i){this.mosaicType=e,this.page=t,this.sdf=i}}class J{constructor(i,r,o){this._requestRender=i,this.resourceManager=r,this._allowNonPowerOfTwo=o,this._invalidFontsMap=new Map,this._sdfConverter=new z(O),this._bindingInfos=new Array,this._hashToBindingIndex=new Map,this._ongoingRasterizations=new Map,this._imageRequestQueue=new N({concurrency:10,process:async(e,i)=>{c(i);try{return await t(e,{responseType:"image",signal:i})}catch(r){if(!u(r))throw new s("mapview-invalid-resource",`Could not fetch requested resource at ${e}`,r);throw r}}}),this._spriteMosaic=new T(2048,2048,500),this._glyphSource=new I(`${e.fontsUrl}/{fontstack}/{range}.pbf`),this._glyphMosaic=new M(1024,1024,this._glyphSource),this._rasterizer=new g(r)}dispose(){this._spriteMosaic.dispose(),this._glyphMosaic.dispose(),this._rasterizer.dispose(),this._sdfConverter.dispose(),this._spriteMosaic=null,this._glyphMosaic=null,this._sdfConverter=null,this._hashToBindingIndex.clear(),this._hashToBindingIndex=null,this._bindingInfos=null,this._ongoingRasterizations.clear(),this._ongoingRasterizations=null,this._imageRequestQueue.clear(),this._imageRequestQueue=null}get sprites(){return this._spriteMosaic}get glyphs(){return this._glyphMosaic}async rasterizeItem(e,t,i,s){if(a(e))return Y("mapview-null-resource","Unable to rasterize null resource"),null;switch(e.type){case"text":case"esriTS":{const t=await this._rasterizeText(e,i,s);return t.forEach((e=>this._setTextureBinding(y.GLYPH,e))),{glyphMosaicItems:t}}default:{if(R(e))return Y("mapview-invalid-type",`MapView does not support symbol type: ${e.type}`,e),null;const i=await this._rasterizeSpriteSymbol(e,t,s);return F(i)&&i&&this._setTextureBinding(y.SPRITE,i),{spriteMosaicItem:i}}}}bindTextures(e,t,i,s=!1){if(0===i.textureBinding)return;const r=this._bindingInfos[i.textureBinding-1],o=r.page,n=s?$.LINEAR_MIPMAP_LINEAR:$.LINEAR;switch(r.mosaicType){case y.SPRITE:{const i=this.sprites.getWidth(o),s=this.sprites.getHeight(o),r=m(k,i,s);return this._spriteMosaic.bind(e,n,o,f),t.setUniform1i("u_texture",f),void t.setUniform2fv("u_mosaicSize",r)}case y.GLYPH:{const i=this.glyphs.width,s=this.glyphs.height,r=m(k,i,s);return this._glyphMosaic.bind(e,n,o,p),t.setUniform1i("u_texture",p),void t.setUniform2fv("u_mosaicSize",r)}default:Q.error("mapview-texture-manager",`Cannot handle unknown type ${r.mosaicType}`)}}_hashMosaic(e,t){return 1|e<<1|(t.sdf?1:0)<<2|t.page<<3}_setTextureBinding(e,t){const i=this._hashMosaic(e,t);if(!this._hashToBindingIndex.has(i)){const s=D.fromMosaic(e,t),r=this._bindingInfos.length+1;this._hashToBindingIndex.set(i,r),this._bindingInfos.push(s)}t.textureBinding=this._hashToBindingIndex.get(i)}async _rasterizeText(e,t,s){let o,n;if("cim"in e){const t=e;o=t.fontName,n=t.text}else{const t=e;o=r(t.font),n=t.text}const a=this._invalidFontsMap.has(o),h=t||v(i(n)[0]);try{return await this._glyphMosaic.getGlyphItems(a?H:o,h,s)}catch(c){return Y("mapview-invalid-resource",`Couldn't find font ${o}. Falling back to Arial Unicode MS Regular`),this._invalidFontsMap.set(o,!0),this._glyphMosaic.getGlyphItems(H,h,s)}}async _rasterizeSpriteSymbol(e,t,i){if(j(e))return;const r=L(e);if(this._spriteMosaic.has(r))return this._spriteMosaic.getSpriteItem(r);if(x(e)||S(e)&&!b(e))return this._handleAsyncResource(r,e,i);const o=w,n=this._rasterizer.rasterizeJSONResource(e,o);if(n){const{size:t,image:i,sdf:s,simplePattern:o,rasterizationScale:a}=n;return this._addItemToMosaic(r,t,{type:"static",data:i},P(e),s,o,a)}return new s("TextureManager","unrecognized or null rasterized image")}async _handleAsyncResource(e,t,i){if(this._ongoingRasterizations.has(e))return this._ongoingRasterizations.get(e);let s;s=x(t)?this._handleSVG(t,e,i):this._handleImage(t,e,i),this._ongoingRasterizations.set(e,s);try{await s,this._ongoingRasterizations.delete(e)}catch{this._ongoingRasterizations.delete(e)}return s}async _handleSVG(e,t,i){const s=[O,O],r=await this._sdfConverter.draw(e.path,i);return this._addItemToMosaic(t,s,{type:"static",data:new Uint32Array(r.buffer)},!1,!0,!0)}async _handleGIFOrPNG(e,t,i){const r=U(e);await this.resourceManager.fetchResource(r,i);let o=this.resourceManager.getResource(r);if(a(o))return new s("mapview-invalid-resource",`Could not fetch requested resource at ${r}.`);let h=o.width,c=o.height;if(o instanceof HTMLImageElement){"esriPMS"===e.type&&(h=Math.round(V(o.width,B(e))),c=Math.round(o.height*(h/o.width)));const i="cim"in e?e.cim.colorSubstitutions:void 0,{size:s,sdf:r,image:n}=this._rasterizer.rasterizeImageResource(h,c,o,i);return this._addItemToMosaic(t,s,{type:"static",data:n},P(e),r,!1)}this._allowNonPowerOfTwo||(h=n(o.width+2*_)-2*_,c=n(o.height+2*_)-2*_),h===o.width&&c===o.height||(o=E(o,h,c));const u=e.animatedSymbolProperties||{},d=e.objectId,m=new C(o,this._requestRender,u,d);return this._addItemToMosaic(t,[m.width,m.height],{type:"animated",data:m},P(e),!1,!1)}async _handleImage(e,t,i){if(G(e)||q(e))return this._handleGIFOrPNG(e,t,i);const r=U(e);try{let s;const o=this.resourceManager.getResource(r);if(h(o)&&o instanceof HTMLImageElement)s=o;else{const{data:e}=await this._imageRequestQueue.push(r,{...i});s=e}if(A(r))if("width"in e&&"height"in e)s.width=d(e.width),s.height=d(e.height);else if("cim"in e){const t=e.cim;s.width=d(t.width??t.scaleX*t.size),s.height=d(t.size)}if(!s.width||!s.height)return null;let n=s.width,a=s.height;"esriPMS"===e.type&&(n=Math.round(V(s.width,B(e))),a=Math.round(s.height*(n/s.width)));const c="cim"in e?e.cim.colorSubstitutions:void 0,{size:u,sdf:m,image:l}=this._rasterizer.rasterizeImageResource(n,a,s,c);return this._addItemToMosaic(t,u,{type:"static",data:l},P(e),m,!1)}catch(o){if(!u(o))return new s("mapview-invalid-resource",`Could not fetch requested resource at ${r}. ${o.message}`)}}_addItemToMosaic(e,t,i,s,r,o,n){return this._spriteMosaic.addSpriteItem(e,t,i,s,r,o,n)}}export{J as default};