@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.33 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{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{packBitset as p,processColorInput 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,T=[4,4],b=[16,4],k={topLeft:b,topRight:b,bottomLeft:b,bottomRight:b},z=[4,2],B=[4,6],M={topLeft:z,topRight:z,bottomLeft:B,bottomRight:B},R={topLeft:z,topRight:B,bottomLeft:z,bottomRight:B},w={topLeft:B,topRight:B,bottomLeft:T,bottomRight:T},L={topLeft:T,topRight:T,bottomLeft:B,bottomRight:B},I={topLeft:B,topRight:T,bottomLeft:B,bottomRight:T},E={topLeft:T,topRight:B,bottomLeft:T,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})=>A(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]}}},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})=>p([[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},fontSize:{type:_.UNSIGNED_SHORT,count:1,packPrecisionFactor:4,packTessellation:({fontSize:t})=>Math.round(e(t))},referenceSize:{type:_.UNSIGNED_BYTE,count:1,packPrecisionFactor:4,packTessellation:({fontSize:t},{referenceSize:o})=>Math.round(e(o??t))},outlineColor:{type:_.UNSIGNED_BYTE,count:4,normalized:!0,pack:({outlineColor:t})=>m(t)},haloColor:{type:_.UNSIGNED_BYTE,count:4,normalized:!0,pack:({haloColor:t})=>m(t)},outlineAndHaloSize:{type:_.UNSIGNED_SHORT,count:2,packPrecisionFactor:4,packTessellation:({outlineSize:t,haloSize:o})=>[Math.round(e(t)),Math.round(e(o))]}}};class N 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){const l=this.evaluatedMeshParams,h=this._textMeshTransformProps,f=e(h.fontSize),p=h.haloSize,u=h.outlineSize,g=e(h.offsetX),x=e(h.offsetY),[y,S]=d(l.scaleInfo,this.getTileInfo());0!==n&&s.setRotation(n);const _=s.bounds,P=r+_.x+g,T=i+_.y-x,b=2*(l.minPixelBuffer?l.minPixelBuffer/f:1),k=Math.max(_.width,_.height)*b;s.textBox&&(t.recordStart(this.instanceId,this.attributeLayout,s.glyphs[0].textureBinding),t.recordBounds(P,T,k,k),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),t.recordBounds(P,T,k,k);const{texcoords:s,offsets:n}=e;this._writeQuad(t,o,r,i,{texcoords:s,offsets:n,fontSize:f,haloSize:p,outlineSize:u,color:m(l.color),isBackground:!1,referenceBounds:a,minZoom:y,maxZoom:S,...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:p}=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:m(f),...d}),p||(this._writeQuad(t,e,o,r,{texcoords:w,offsets:i.top,color:m(f),...d}),this._writeQuad(t,e,o,r,{texcoords:L,offsets:i.bot,color:m(f),...d}),this._writeQuad(t,e,o,r,{texcoords:I,offsets:i.left,color:m(f),...d}),this._writeQuad(t,e,o,r,{texcoords:E,offsets:i.right,color:m(f),...d}))),p&&(this._writeQuad(t,e,o,r,{texcoords:M,offsets:i.top,color:m(p),...d}),this._writeQuad(t,e,o,r,{texcoords:M,offsets:i.bot,color:m(p),...d}),this._writeQuad(t,e,o,r,{texcoords:R,offsets:i.left,color:m(p),...d}),this._writeQuad(t,e,o,r,{texcoords:R,offsets:i.right,color:m(p),...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 A=t=>Math.round(t*(254/360));export{N as TextMeshWriter,G as TextVertexSpec,P as maxLabelZoom};