UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

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