@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 7.51 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{clamp as t}from"../../../../../../../core/mathUtils.js";import{pt2px as e}from"../../../../../../../core/screenUtils.js";import{GeometryCursor as o}from"../../../../../../../geometry/GeometryCursor.js";import{CIMMarkerPlacementHelper as i}from"../../../../../../../symbols/cim/placements/CIMMarkerPlacementHelper.js";import{getXDirection as s,getYDirection as r}from"../../../alignmentUtils.js";import{minMaxZoomPrecisionFactor as n,maxTextLineWidth as a,minTextLineWidth as l,magicLabelLineHeight as c}from"../../../definitions.js";import{shapeGlyphs as d}from"../../../mesh/templates/shapingUtils.js";import{getMinMaxZoom as h,processColorInput as f,packBitset as p}from"../fill/meshWriterUtils.js";import{MeshWriter as m}from"../mesh/MeshWriter.js";import{bitsetTextIsBackground as u,bitsetTextIsMapAligned as g}from"../shaders/constants.js";import{TextMeshTransformProps as x}from"./TextParams.js";import{DataType as y}from"../../../../../../webgl/enums.js";const S=28,_=[4,4],z=[16,4],P={topLeft:z,topRight:z,bottomLeft:z,bottomRight:z},b=[4,2],R=[4,6],T={topLeft:b,topRight:b,bottomLeft:R,bottomRight:R},k={topLeft:b,topRight:R,bottomLeft:b,bottomRight:R},B={topLeft:R,topRight:R,bottomLeft:_,bottomRight:_},M={topLeft:_,topRight:_,bottomLeft:R,bottomRight:R},L={topLeft:R,topRight:_,bottomLeft:R,bottomRight:_},w={topLeft:_,topRight:R,bottomLeft:_,bottomRight:R},A={createComputedParams:t=>t,optionalAttributes:{zoomRange:{type:y.UNSIGNED_SHORT,count:2,packPrecisionFactor:n,packTessellation:({minZoom:t,maxZoom:e})=>[t||0,e||S]},clipAngle:{type:y.UNSIGNED_BYTE,count:1,packTessellation:({clipAngle:t})=>I(t||0)},referenceSymbol:{type:y.BYTE,count:4,packPrecisionFactor:1,packTessellation:(t,o)=>{const i=t.isLineLabel||!t.referenceBounds,n=s(i?"center":o.horizontalAlignment),a=r(i?"middle":o.verticalAlignment),{offsetX:l,offsetY:c,size:d}=i?{offsetX:0,offsetY:0,size:0}:t.referenceBounds;return[e(l),-e(c),Math.round(e(d)),n+1<<2|a+1]}},visibility:{type:y.FLOAT,count:1,otherSource:!0}},attributes:{pos:{type:y.SHORT,count:2,pack:"position",packPrecisionFactor:10},id:{type:y.UNSIGNED_BYTE,count:3,pack:"id"},bitset:{type:y.UNSIGNED_BYTE,count:1,packTessellation:({isBackground:t,mapAligned:e})=>p([[u,t],[g,!!e]])},offset:{type:y.SHORT,count:2,packPrecisionFactor:8,packAlternating:{count:4,packTessellation:({offsets:t})=>{const{bottomLeft:e,bottomRight:o,topLeft:i,topRight:s}=t;return[i,s,e,o]}}},textureUV:{type:y.SHORT,count:2,packPrecisionFactor:4,packAlternating:{count:4,packTessellation:({texcoords:t})=>{const{bottomLeft:e,bottomRight:o,topLeft:i,topRight:s}=t;return[i,s,e,o]}}},color:{type:y.UNSIGNED_BYTE,count:4,normalized:!0,packTessellation:({color:t})=>t},fontAndReferenceSize:{type:y.UNSIGNED_SHORT,count:4,packPrecisionFactor:4,packTessellation:({fontSize:t,sdfSize:o,sdfRadius:i},{referenceSize:s})=>[Math.round(e(t)),Math.round(e(s??t)),o,i]},outlineColor:{type:y.UNSIGNED_BYTE,count:4,normalized:!0,pack:({outlineColor:t})=>f(t)},haloColor:{type:y.UNSIGNED_BYTE,count:4,normalized:!0,pack:({haloColor:t})=>f(t)},outlineAndHaloSize:{type:y.UNSIGNED_SHORT,count:2,packPrecisionFactor:4,packTessellation:({outlineSize:t,haloSize:o})=>[Math.round(e(t)),Math.round(e(o))]}}};class v extends m{constructor(){super(...arguments),this.vertexSpec=A,this._textMeshParamsPropsInitialized=!1}ensurePacked(t,e,o){super.ensurePacked(t,e,o),this._textMeshParamsPropsInitialized&&!this._evaluator.hasDynamicProperties||(this._textMeshTransformProps=new x(this.evaluatedMeshParams),this._textMeshParamsPropsInitialized=!0)}_write(t,e,o){const i=this._getShaping();if(!i)return;const s=1===this.evaluatedMeshParams.alignment,r=e.getDisplayId();if(null!=this.evaluatedMeshParams.placement)return this._writePlacedTextMarkers(t,e,i,o);if(o?.nextPath())return o.nextPoint(),this._writeGlyphs(t,r,o.x,o.y,i,0,void 0,{mapAligned:s});if("esriGeometryPolygon"===e.geometryType){const o=e.readCentroidForDisplay();if(!o)return;const[n,a]=o.coords;return this._writeGlyphs(t,r,n,a,i,0,void 0,{mapAligned:s})}if("esriGeometryMultipoint"===e.geometryType){const o=e.readGeometryForDisplay();return void o?.forEachVertex((e,o)=>this._writeGlyphs(t,r,e,o,i,0,void 0,{mapAligned:s}))}const n=e.readXForDisplay(),a=e.readYForDisplay();return this._writeGlyphs(t,r,n,a,i,0,void 0,{mapAligned:s})}_writePlacedTextMarkers(t,s,r,n){const a=n??o.fromFeatureSetReaderCIM(s);if(!a)return;const l=-1,c=i.getPlacement(a,l,this.evaluatedMeshParams.placement,e(1),t.id);if(!c)return;const d=s.getDisplayId();let h=c.next();for(;null!=h;){const e=h.tx,o=-h.ty,i=-h.getAngle();this._writeGlyphs(t,d,e,o,r,i,void 0,{mapAligned:1===this.evaluatedMeshParams.alignment}),h=c.next()}}_getShaping(o){const i=this._textMeshTransformProps,s=this.evaluatedMeshParams;if(!s.glyphs?.glyphs.length)return null;const r=e(i.fontSize),n=e(i.offsetX),h=e(i.offsetY),f=s.glyphs.sdfSize,p=t(e(s.lineWidth),l,a),m=f/24*c*t(s.lineHeightRatio,.25,4);return d(s.glyphs,{scale:r/f,angle:i.postAngle,xOffset:n,yOffset:h,horizontalAlignment:s.horizontalAlignment,verticalAlignment:o||s.verticalAlignment,maxLineWidth:p,lineHeight:m,decoration:s.decoration,borderLineSizePx:e(s.boxBorderLineSize),hasBackground:!!s.boxBackgroundColor,useCIMAngleBehavior:s.useCIMAngleBehavior})}_writeGlyphs(t,o,i,s,r,n,a,l,c=!0){const d=this.evaluatedMeshParams,p=this._textMeshTransformProps,m=e(p.fontSize),u=p.haloSize,g=p.outlineSize,x=e(p.offsetX),y=e(p.offsetY),{sdfSize:S,sdfRadius:_}=d.glyphs,[z,P]=h(d.scaleInfo,this.getTileInfo());0!==n&&r.setRotation(n);const b=r.bounds,R=i+b.x+x,T=s+b.y-y,k=2*(d.minPixelBuffer?d.minPixelBuffer/m:1),B=Math.max(b.width,b.height)*k;r.textBox&&(t.recordStart(this.instanceId,this.attributeLayout,r.glyphs[0].textureBinding),c&&t.recordBounds(R,T,B,B),this._writeTextBox(t,o,i,s,r.textBox,a,l),t.recordEnd());for(const e of r.glyphs){t.recordStart(this.instanceId,this.attributeLayout,e.textureBinding),c&&t.recordBounds(R,T,B,B);const{texcoords:r,offsets:n}=e;this._writeQuad(t,o,i,s,{texcoords:r,offsets:n,fontSize:m,haloSize:u,outlineSize:g,sdfSize:S,sdfRadius:_,color:f(d.color),isBackground:!1,referenceBounds:a,minZoom:z,maxZoom:P,...l}),t.recordEnd()}0!==n&&r.setRotation(-n)}_writeTextBox(t,e,o,i,s,r,n){const a=this.evaluatedMeshParams,{fontSize:l,haloSize:c,outlineSize:d}=this._textMeshTransformProps,{boxBackgroundColor:h,boxBorderLineColor:p,boxBorderLineSize:m}=a,{sdfSize:u,sdfRadius:g}=a.glyphs,x=!!p&&m>0,y={isBackground:!0,fontSize:l,haloSize:c,outlineSize:d,referenceBounds:r,sdfSize:u,sdfRadius:g,...n};h&&(this._writeQuad(t,e,o,i,{texcoords:P,offsets:s.main,color:f(h),...y}),x||(this._writeQuad(t,e,o,i,{texcoords:B,offsets:s.top,color:f(h),...y}),this._writeQuad(t,e,o,i,{texcoords:M,offsets:s.bot,color:f(h),...y}),this._writeQuad(t,e,o,i,{texcoords:L,offsets:s.left,color:f(h),...y}),this._writeQuad(t,e,o,i,{texcoords:w,offsets:s.right,color:f(h),...y}))),x&&(this._writeQuad(t,e,o,i,{texcoords:T,offsets:s.top,color:f(p),...y}),this._writeQuad(t,e,o,i,{texcoords:T,offsets:s.bot,color:f(p),...y}),this._writeQuad(t,e,o,i,{texcoords:k,offsets:s.left,color:f(p),...y}),this._writeQuad(t,e,o,i,{texcoords:k,offsets:s.right,color:f(p),...y}))}_writeQuad(t,e,o,i,s){const r=t.vertexCount();this._writeVertex(t,e,o,i,s),t.indexWrite(r+0),t.indexWrite(r+1),t.indexWrite(r+2),t.indexWrite(r+1),t.indexWrite(r+3),t.indexWrite(r+2)}}const I=t=>Math.round(t*(254/360));export{v as TextMeshWriter,A as TextVertexSpec,S as maxLabelZoom};