@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 33.1 kB
JavaScript
import{string as t}from"../../../core/string.js";import{math as s}from"../../../core/math/math.js";import{Color as e}from"../../../core/math/color.js";import{Vec2 as i}from"../../../core/math/vec2.js";import{BoundingBox as o}from"../../../core/shape/bounding-box.js";import{SEMANTIC_POSITION as h,SEMANTIC_TEXCOORD0 as n,SEMANTIC_COLOR as a,SEMANTIC_ATTR8 as r,SEMANTIC_ATTR9 as l,TYPE_FLOAT32 as _}from"../../../platform/graphics/constants.js";import{VertexIterator as m}from"../../../platform/graphics/vertex-iterator.js";import{GraphNode as f}from"../../../scene/graph-node.js";import{MeshInstance as u}from"../../../scene/mesh-instance.js";import{Model as d}from"../../../scene/model.js";import{Mesh as c}from"../../../scene/mesh.js";import{LocalizedAsset as g}from"../../asset/asset-localized.js";import{FONT_MSDF as p,FONT_BITMAP as w}from"../../font/constants.js";import{Markup as b}from"./markup.js";class y{constructor(){this.count=0,this.quad=0,this.lines={},this.positions=[],this.normals=[],this.uvs=[],this.colors=[],this.indices=[],this.outlines=[],this.shadows=[],this.meshInstance=null}}function C(t,s){const e=new c(t);return e.setPositions(s.positions),e.setNormals(s.normals),e.setColors32(s.colors),e.setUvs(0,s.uvs),e.setIndices(s.indices),e.setVertexStream(r,s.outlines,3,void 0,_,!1),e.setVertexStream(l,s.shadows,3,void 0,_,!1),e.update(),e}const x=/^[\r\n]$/,I=/^[ \t]$/,S=/^[ \t\-]|\u200b$/,P=/^[a-z0-9]$/i,M=/^[\u1100-\u11ff]|[\u3000-\u9fff\ua960-\ua97f]|[\uac00-\ud7ff]$/,F=/^[〕〉》」』】〙〗〟ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻]$/,z=["","","","","","","","","","","","",""],v={width:0,height:0,xadvance:0,xoffset:0,yoffset:0},O=new e,T=new i;class U{constructor(t){this._element=t,this._system=t.system,this._entity=t.entity,this._text="",this._symbols=[],this._colorPalette=[],this._outlinePalette=[],this._shadowPalette=[],this._symbolColors=null,this._symbolOutlineParams=null,this._symbolShadowParams=null,this._i18nKey=null,this._fontAsset=new g(this._system.app),this._fontAsset.disableLocalization=!0,this._fontAsset.on("load",this._onFontLoad,this),this._fontAsset.on("change",this._onFontChange,this),this._fontAsset.on("remove",this._onFontRemove,this),this._font=null,this._color=new e(1,1,1,1),this._colorUniform=new Float32Array(3),this._spacing=1,this._fontSize=32,this._fontMinY=0,this._fontMaxY=0,this._originalFontSize=32,this._maxFontSize=32,this._minFontSize=8,this._autoFitWidth=!1,this._autoFitHeight=!1,this._maxLines=-1,this._lineHeight=32,this._scaledLineHeight=32,this._wrapLines=!1,this._drawOrder=0,this._alignment=new i(.5,.5),this._autoWidth=!0,this._autoHeight=!0,this.width=0,this.height=0,this._node=new f,this._model=new d,this._model.graph=this._node,this._entity.addChild(this._node),this._meshInfo=[],this._material=null,this._aabbDirty=!0,this._aabb=new o,this._noResize=!1,this._currentMaterialType=null,this._maskedMaterialSrc=null,this._rtlReorder=!1,this._unicodeConverter=!1,this._rtl=!1,this._outlineColor=new e(0,0,0,1),this._outlineColorUniform=new Float32Array(4),this._outlineThicknessScale=.2,this._outlineThickness=0,this._shadowColor=new e(0,0,0,1),this._shadowColorUniform=new Float32Array(4),this._shadowOffsetScale=.005,this._shadowOffset=new i(0,0),this._shadowOffsetUniform=new Float32Array(2),this._enableMarkup=!1,this._onScreenChange(this._element.screen),t.on("resize",this._onParentResize,this),t.on("set:screen",this._onScreenChange,this),t.on("screen:set:screenspace",this._onScreenSpaceChange,this),t.on("set:draworder",this._onDrawOrderChange,this),t.on("set:pivot",this._onPivotChange,this),this._system.app.i18n.on("set:locale",this._onLocaleSet,this),this._system.app.i18n.on("data:add",this._onLocalizationData,this),this._system.app.i18n.on("data:remove",this._onLocalizationData,this),this._rangeStart=0,this._rangeEnd=0}destroy(){this._setMaterial(null),this._model&&(this._element.removeModelFromLayers(this._model),this._model.destroy(),this._model=null),this._fontAsset.destroy(),this.font=null,this._element.off("resize",this._onParentResize,this),this._element.off("set:screen",this._onScreenChange,this),this._element.off("screen:set:screenspace",this._onScreenSpaceChange,this),this._element.off("set:draworder",this._onDrawOrderChange,this),this._element.off("set:pivot",this._onPivotChange,this),this._system.app.i18n.off("set:locale",this._onLocaleSet,this),this._system.app.i18n.off("data:add",this._onLocalizationData,this),this._system.app.i18n.off("data:remove",this._onLocalizationData,this)}_onParentResize(t,s){this._noResize||this._font&&this._updateText()}_onScreenChange(t){t?this._updateMaterial(t.screen.screenSpace):this._updateMaterial(!1)}_onScreenSpaceChange(t){this._updateMaterial(t)}_onDrawOrderChange(t){if(this._drawOrder=t,this._model)for(let s=0,e=this._model.meshInstances.length;s<e;s++)this._model.meshInstances[s].drawOrder=t}_onPivotChange(t){this._font&&this._updateText()}_onLocaleSet(t){if(this._i18nKey){if(this.fontAsset){const t=this._system.app.assets.get(this.fontAsset);t&&t.resource&&t.resource===this._font||(this.font=null)}this._resetLocalizedText()}}_onLocalizationData(t,s){this._i18nKey&&s[this._i18nKey]&&this._resetLocalizedText()}_resetLocalizedText(){this._setText(this._system.app.i18n.getText(this._i18nKey))}_setText(t){if(this.unicodeConverter){const s=this._system.getUnicodeConverter();s?t=s(t):console.warn("Element created with unicodeConverter option but no unicodeConverter function registered")}this._text!==t&&(this._font&&this._updateText(t),this._text=t)}_updateText(s){let e;if(void 0===s&&(s=this._text),this._symbols=t.getSymbols(s.normalize?s.normalize("NFC"):s),0===this._symbols.length&&(this._symbols=[" "]),this._enableMarkup){const t=b.evaluate(this._symbols);this._symbols=t.symbols,e=t.tags||[]}if(this._rtlReorder){const t=this._system.app.systems.element.getRtlReorder();if(t){const s=t(this._symbols);this._rtl=s.rtl,this._symbols=s.mapping.map((function(t){return this._symbols[t]}),this),e&&(e=s.mapping.map((t=>e[t])))}else console.warn("Element created with rtlReorder option but no rtlReorder function registered")}else this._rtl=!1;const i=(t,s)=>`${t.toString(!0).toLowerCase()}:${s.toFixed(2)}`,o=(t,s)=>`${t.toString(!0).toLowerCase()}:${s.x.toFixed(2)}:${s.y.toFixed(2)}`;if(e){const t={},s={},h={};this._colorPalette=[Math.round(255*this._color.r),Math.round(255*this._color.g),Math.round(255*this._color.b)],this._outlinePalette=[Math.round(255*this._outlineColor.r),Math.round(255*this._outlineColor.g),Math.round(255*this._outlineColor.b),Math.round(255*this._outlineColor.a),Math.round(255*this._outlineThickness)],this._shadowPalette=[Math.round(255*this._shadowColor.r),Math.round(255*this._shadowColor.g),Math.round(255*this._shadowColor.b),Math.round(255*this._shadowColor.a),Math.round(127*this._shadowOffset.x),Math.round(127*this._shadowOffset.y)],this._symbolColors=[],this._symbolOutlineParams=[],this._symbolShadowParams=[],t[this._color.toString(!1).toLowerCase()]=0,s[i(this._outlineColor,this._outlineThickness)]=0,h[o(this._shadowColor,this._shadowOffset)]=0;for(let n=0,a=this._symbols.length;n<a;++n){const a=e[n];let r=0;if(a&&a.color&&a.color.value){const s=a.color.value;if(7===s.length&&"#"===s[0]){const e=s.substring(1).toLowerCase();t.hasOwnProperty(e)?r=t[e]:/^[0-9a-f]{6}$/.test(e)&&(r=this._colorPalette.length/3,t[e]=r,this._colorPalette.push(parseInt(e.substring(0,2),16)),this._colorPalette.push(parseInt(e.substring(2,4),16)),this._colorPalette.push(parseInt(e.substring(4,6),16)))}}this._symbolColors.push(r);let l=0;if(a&&a.outline&&(a.outline.attributes.color||a.outline.attributes.thickness)){let t=a.outline.attributes.color?O.fromString(a.outline.attributes.color):this._outlineColor,e=Number(a.outline.attributes.thickness);(Number.isNaN(t.r)||Number.isNaN(t.g)||Number.isNaN(t.b)||Number.isNaN(t.a))&&(t=this._outlineColor),Number.isNaN(e)&&(e=this._outlineThickness);const o=i(t,e);s.hasOwnProperty(o)?l=s[o]:(l=this._outlinePalette.length/5,s[o]=l,this._outlinePalette.push(Math.round(255*t.r),Math.round(255*t.g),Math.round(255*t.b),Math.round(255*t.a),Math.round(255*e)))}this._symbolOutlineParams.push(l);let _=0;if(a&&a.shadow&&(a.shadow.attributes.color||a.shadow.attributes.offset||a.shadow.attributes.offsetX||a.shadow.attributes.offsetY)){let t=a.shadow.attributes.color?O.fromString(a.shadow.attributes.color):this._shadowColor;const s=Number(a.shadow.attributes.offset),e=Number(a.shadow.attributes.offsetX),i=Number(a.shadow.attributes.offsetY);(Number.isNaN(t.r)||Number.isNaN(t.g)||Number.isNaN(t.b)||Number.isNaN(t.a))&&(t=this._shadowColor);const n=T.set(Number.isNaN(e)?Number.isNaN(s)?this._shadowOffset.x:s:e,Number.isNaN(i)?Number.isNaN(s)?this._shadowOffset.y:s:i),r=o(t,n);h.hasOwnProperty(r)?_=h[r]:(_=this._shadowPalette.length/6,h[r]=_,this._shadowPalette.push(Math.round(255*t.r),Math.round(255*t.g),Math.round(255*t.b),Math.round(255*t.a),Math.round(127*n.x),Math.round(127*n.y)))}this._symbolShadowParams.push(_)}}else this._colorPalette=[],this._symbolColors=null,this._symbolOutlineParams=null,this._symbolShadowParams=null;this._updateMaterialEmissive(),this._updateMaterialOutline(),this._updateMaterialShadow();const h=this._calculateCharsPerTexture();let n=!1;const a=this._element,r=a._isScreenSpace(),l=a._isScreenCulled(),_=function(t){return a.isVisibleForCamera(t)};for(let t=0,s=this._meshInfo.length;t<s;t++){const s=h[t]||0,e=this._meshInfo[t];if(e.count!==s){if(n||(a.removeModelFromLayers(this._model),n=!0),e.count=s,e.positions.length=e.normals.length=3*s*4,e.indices.length=3*s*2,e.uvs.length=2*s*4,e.colors.length=4*s*4,e.outlines.length=4*s*3,e.shadows.length=4*s*3,e.meshInstance&&this._removeMeshInstance(e.meshInstance),0===s){e.meshInstance=null;continue}for(let t=0;t<s;t++)e.indices[3*t*2+0]=4*t,e.indices[3*t*2+1]=4*t+1,e.indices[3*t*2+2]=4*t+3,e.indices[3*t*2+3]=4*t+2,e.indices[3*t*2+4]=4*t+3,e.indices[3*t*2+5]=4*t+1,e.normals[4*t*3+0]=0,e.normals[4*t*3+1]=0,e.normals[4*t*3+2]=-1,e.normals[4*t*3+3]=0,e.normals[4*t*3+4]=0,e.normals[4*t*3+5]=-1,e.normals[4*t*3+6]=0,e.normals[4*t*3+7]=0,e.normals[4*t*3+8]=-1,e.normals[4*t*3+9]=0,e.normals[4*t*3+10]=0,e.normals[4*t*3+11]=-1;const i=C(this._system.app.graphicsDevice,e),o=new u(i,this._material,this._node);if(o.name=`Text Element: ${this._entity.name}`,o.castShadow=!1,o.receiveShadow=!1,o.cull=!r,o.screenSpace=r,o.drawOrder=this._drawOrder,l&&(o.cull=!0,o.isVisibleFunc=_),this._setTextureParams(o,this._font.textures[t]),o.setParameter("material_emissive",this._colorUniform),o.setParameter("material_opacity",this._color.a),o.setParameter("font_sdfIntensity",this._font.intensity),o.setParameter("font_pxrange",this._getPxRange(this._font)),o.setParameter("font_textureWidth",this._font.data.info.maps[t].width),o.setParameter("outline_color",this._outlineColorUniform),o.setParameter("outline_thickness",this._outlineThicknessScale*this._outlineThickness),o.setParameter("shadow_color",this._shadowColorUniform),this._symbolShadowParams)this._shadowOffsetUniform[0]=0,this._shadowOffsetUniform[1]=0;else{const s=-this._font.data.info.maps[t].width/this._font.data.info.maps[t].height;this._shadowOffsetUniform[0]=this._shadowOffsetScale*this._shadowOffset.x,this._shadowOffsetUniform[1]=s*this._shadowOffsetScale*this._shadowOffset.y}o.setParameter("shadow_offset",this._shadowOffsetUniform),e.meshInstance=o,this._model.meshInstances.push(o)}}this._element.maskedBy&&this._element._setMaskedBy(this._element.maskedBy),n&&this._element.enabled&&this._entity.enabled&&this._element.addModelToLayers(this._model),this._updateMeshes(),this._rangeStart=0,this._rangeEnd=this._symbols.length,this._updateRenderRange()}_removeMeshInstance(t){t.destroy();const s=this._model.meshInstances.indexOf(t);-1!==s&&this._model.meshInstances.splice(s,1)}_setMaterial(t){if(this._material=t,this._model)for(let s=0,e=this._model.meshInstances.length;s<e;s++){this._model.meshInstances[s].material=t}}_updateMaterial(t){const s=this._element,e=s._isScreenCulled(),i=function(t){return s.isVisibleForCamera(t)},o=this._font&&this._font.type===p;if(this._material=this._system.getTextElementMaterial(t,o,this._enableMarkup),this._model)for(let s=0,o=this._model.meshInstances.length;s<o;s++){const o=this._model.meshInstances[s];o.cull=!t,o.material=this._material,o.screenSpace=t,e?(o.cull=!0,o.isVisibleFunc=i):o.isVisibleFunc=null}}_updateMaterialEmissive(){this._symbolColors?(this._colorUniform[0]=1,this._colorUniform[1]=1,this._colorUniform[2]=1):(this._colorUniform[0]=this._color.r,this._colorUniform[1]=this._color.g,this._colorUniform[2]=this._color.b)}_updateMaterialOutline(){this._symbolOutlineParams?(this._outlineColorUniform[0]=0,this._outlineColorUniform[1]=0,this._outlineColorUniform[2]=0,this._outlineColorUniform[3]=1):(this._outlineColorUniform[0]=this._outlineColor.r,this._outlineColorUniform[1]=this._outlineColor.g,this._outlineColorUniform[2]=this._outlineColor.b,this._outlineColorUniform[3]=this._outlineColor.a)}_updateMaterialShadow(){this._symbolOutlineParams?(this._shadowColorUniform[0]=0,this._shadowColorUniform[1]=0,this._shadowColorUniform[2]=0,this._shadowColorUniform[3]=0):(this._shadowColorUniform[0]=this._shadowColor.r,this._shadowColorUniform[1]=this._shadowColor.g,this._shadowColorUniform[2]=this._shadowColor.b,this._shadowColorUniform[3]=this._shadowColor.a)}_isWordBoundary(t){return S.test(t)}_isValidNextChar(t){return null!==t&&!F.test(t)}_isNextCJKBoundary(t,s){return M.test(t)&&(S.test(s)||P.test(s))}_isNextCJKWholeWord(t){return M.test(t)}_updateMeshes(){const e=this._font.data,i=this,o=Math.min(this._minFontSize,this._maxFontSize),_=this._maxFontSize,f=this._shouldAutoFit();f&&(this._fontSize=this._maxFontSize);const u=this._symbols.length;let d=0,c=0,g=0,p=0,w=1,b=0,y=0,C=0,S=0,P=0,M=0;const F=Math.abs(this._element.anchor.x-this._element.anchor.z)>=1e-4;let O=this._element.calculatedWidth;(this.autoWidth&&!F||!this._wrapLines)&&(O=Number.POSITIVE_INFINITY);let T,U,N,L,k=0,A=0;function W(t,s,e){i._lineWidths.push(Math.abs(e));const o=C>s?s+1:C,h=C>s?C+1:s,n=t.slice(o,h);if(M){let t=n.length;for(;t--&&M>0;)x.test(n[t])&&(n.splice(t,1),M--)}i._lineContents.push(n.join("")),d=0,c-=i._scaledLineHeight,w++,S=0,P=0,M=0,b=0,C=s}let H=!0;for(;H;){H=!1,this._scaledLineHeight=f?this._lineHeight*this._fontSize/(this._maxFontSize||1e-4):this._lineHeight,this.width=0,this.height=0,this._lineWidths=[],this._lineContents=[],d=0,c=0,g=0,p=0,w=1,b=0,y=0,C=0,S=0,P=0,M=0;const i=this._fontSize/32;k=this._fontMinY*i,A=this._fontMaxY*i;for(let t=0;t<this._meshInfo.length;t++)this._meshInfo[t].quad=0,this._meshInfo[t].lines={};let h=255,n=255,a=255,r=65535,l=65535,m=0,F=65535,R=65535,j=32639;for(let f=0;f<u;f++){T=this._symbols[f],L=f+1>=u?null:this._symbols[f+1];if(x.test(T)){M++,(!this._wrapLines||this._maxLines<0||w<this._maxLines)&&(W(this._symbols,f,p),y=f+1,C=f+1);continue}let E,D,$=0,K=0,Y=0,V=1;if(U=e.chars[T],!U)if(-1!==z.indexOf(T))U=v;else if(e.chars[" "])U=e.chars[" "];else for(const t in e.chars){U=e.chars[t];break}if(U){let s=0;if(P>0){const e=this._font.data.kerning;if(e){const i=e[t.getCodePoint(this._symbols[f-1])||0];i&&(s=i[t.getCodePoint(this._symbols[f])||0]||0)}}E=U.scale||1,D=(U.width+U.height)/2,V=i*D/E,Y=(U.xadvance+s)*i,$=(U.xoffset-s)*i,K=U.yoffset*i}else console.error(`Couldn't substitute missing character: '${T}'`);const B=I.test(T),q=U&&U.map||0,J=-this._font.data.info.maps[q].width/this._font.data.info.maps[q].height,X=this._meshInfo[q],G=d+this._spacing*Y;if(G>O&&P>0&&!B&&(this._maxLines<0||w<this._maxLines)){if(0!==S){const t=Math.max(f-y,0);if(this._meshInfo.length<=1)X.lines[w-1]-=t,X.quad-=t;else{const t=f;for(let s=y;s<t;s++){const t=this._symbols[s],i=e.chars[t],o=this._meshInfo[i&&i.map||0];o.lines[w-1]-=1,o.quad-=1}}f-=t+1,W(this._symbols,y,b);continue}y=f,W(this._symbols,f,p)}N=X.quad,X.lines[w-1]=N;let Q=d-$,Z=Q+V;const tt=c-K,st=tt+V;if(this._rtl){const t=V-$-this._spacing*Y-$;Q-=t,Z-=t}let et;if(X.positions[4*N*3+0]=Q,X.positions[4*N*3+1]=tt,X.positions[4*N*3+2]=g,X.positions[4*N*3+3]=Z,X.positions[4*N*3+4]=tt,X.positions[4*N*3+5]=g,X.positions[4*N*3+6]=Z,X.positions[4*N*3+7]=st,X.positions[4*N*3+8]=g,X.positions[4*N*3+9]=Q,X.positions[4*N*3+10]=st,X.positions[4*N*3+11]=g,this.width=Math.max(this.width,G),this._shouldAutoFitWidth()&&this.width>this._element.calculatedWidth&&(et=Math.floor(this._element.fontSize*this._element.calculatedWidth/(this.width||1e-4)),et=s.clamp(et,o,_),et!==this._element.fontSize)){this._fontSize=et,H=!0;break}if(this.height=Math.max(this.height,A-(c+k)),this._shouldAutoFitHeight()&&this.height>this._element.calculatedHeight&&(et=s.clamp(this._fontSize-1,o,_),et!==this._element.fontSize)){this._fontSize=et,H=!0;break}d+=this._spacing*Y,B||(p=d),(this._isWordBoundary(T)||this._isValidNextChar(L)&&(this._isNextCJKBoundary(T,L)||this._isNextCJKWholeWord(L)))&&(S++,b=p,y=f+1),P++;const it=this._getUv(T);if(X.uvs[4*N*2+0]=it[0],X.uvs[4*N*2+1]=1-it[1],X.uvs[4*N*2+2]=it[2],X.uvs[4*N*2+3]=1-it[1],X.uvs[4*N*2+4]=it[2],X.uvs[4*N*2+5]=1-it[3],X.uvs[4*N*2+6]=it[0],X.uvs[4*N*2+7]=1-it[3],this._symbolColors){const t=3*this._symbolColors[f];h=this._colorPalette[t],n=this._colorPalette[t+1],a=this._colorPalette[t+2]}if(X.colors[4*N*4+0]=h,X.colors[4*N*4+1]=n,X.colors[4*N*4+2]=a,X.colors[4*N*4+3]=255,X.colors[4*N*4+4]=h,X.colors[4*N*4+5]=n,X.colors[4*N*4+6]=a,X.colors[4*N*4+7]=255,X.colors[4*N*4+8]=h,X.colors[4*N*4+9]=n,X.colors[4*N*4+10]=a,X.colors[4*N*4+11]=255,X.colors[4*N*4+12]=h,X.colors[4*N*4+13]=n,X.colors[4*N*4+14]=a,X.colors[4*N*4+15]=255,this._symbolOutlineParams){const t=5*this._symbolOutlineParams[f];r=this._outlinePalette[t]+256*this._outlinePalette[t+1],l=this._outlinePalette[t+2]+256*this._outlinePalette[t+3],m=this._outlinePalette[t+4]}if(X.outlines[4*N*3+0]=r,X.outlines[4*N*3+1]=l,X.outlines[4*N*3+2]=m,X.outlines[4*N*3+3]=r,X.outlines[4*N*3+4]=l,X.outlines[4*N*3+5]=m,X.outlines[4*N*3+6]=r,X.outlines[4*N*3+7]=l,X.outlines[4*N*3+8]=m,X.outlines[4*N*3+9]=r,X.outlines[4*N*3+10]=l,X.outlines[4*N*3+11]=m,this._symbolShadowParams){const t=6*this._symbolShadowParams[f];F=this._shadowPalette[t]+256*this._shadowPalette[t+1],R=this._shadowPalette[t+2]+256*this._shadowPalette[t+3],j=this._shadowPalette[t+4]+127+256*Math.round(J*this._shadowPalette[t+5]+127)}X.shadows[4*N*3+0]=F,X.shadows[4*N*3+1]=R,X.shadows[4*N*3+2]=j,X.shadows[4*N*3+3]=F,X.shadows[4*N*3+4]=R,X.shadows[4*N*3+5]=j,X.shadows[4*N*3+6]=F,X.shadows[4*N*3+7]=R,X.shadows[4*N*3+8]=j,X.shadows[4*N*3+9]=F,X.shadows[4*N*3+10]=R,X.shadows[4*N*3+11]=j,X.quad++}H||C<u&&W(this._symbols,u,d)}this._noResize=!0,this.autoWidth=this._autoWidth,this.autoHeight=this._autoHeight,this._noResize=!1;const R=this._element.pivot.x,j=this._element.pivot.y,E=this._alignment.x,D=this._alignment.y;for(let t=0;t<this._meshInfo.length;t++){if(0===this._meshInfo[t].count)continue;let s=0;for(const e in this._meshInfo[t].lines){const i=this._meshInfo[t].lines[e],o=this._lineWidths[parseInt(e,10)],h=-R*this._element.calculatedWidth+E*(this._element.calculatedWidth-o)*(this._rtl?-1:1),n=(1-j)*this._element.calculatedHeight-A-(1-D)*(this._element.calculatedHeight-this.height);for(let e=s;e<=i;e++)this._meshInfo[t].positions[4*e*3]+=h,this._meshInfo[t].positions[4*e*3+3]+=h,this._meshInfo[t].positions[4*e*3+6]+=h,this._meshInfo[t].positions[4*e*3+9]+=h,this._meshInfo[t].positions[4*e*3+1]+=n,this._meshInfo[t].positions[4*e*3+4]+=n,this._meshInfo[t].positions[4*e*3+7]+=n,this._meshInfo[t].positions[4*e*3+10]+=n;if(this._rtl)for(let e=s;e<=i;e++){const s=4*e*3;for(let e=0;e<4;++e)this._meshInfo[t].positions[s+3*e]=this._element.calculatedWidth-this._meshInfo[t].positions[s+3*e]+2*h;const i=this._meshInfo[t].positions[s+3],o=this._meshInfo[t].positions[s+6];this._meshInfo[t].positions[s+3]=this._meshInfo[t].positions[s+0],this._meshInfo[t].positions[s+6]=this._meshInfo[t].positions[s+9],this._meshInfo[t].positions[s+0]=i,this._meshInfo[t].positions[s+9]=o}s=i+1}const e=4*this._meshInfo[t].count,i=4*this._meshInfo[t].quad,o=new m(this._meshInfo[t].meshInstance.mesh.vertexBuffer);for(let s=0;s<e;s++)s>=i?(o.element[h].set(0,0,0),o.element[n].set(0,0),o.element[a].set(0,0,0,0),o.element[r].set(0,0,0,0),o.element[l].set(0,0,0,0)):(o.element[h].set(this._meshInfo[t].positions[3*s+0],this._meshInfo[t].positions[3*s+1],this._meshInfo[t].positions[3*s+2]),o.element[n].set(this._meshInfo[t].uvs[2*s+0],this._meshInfo[t].uvs[2*s+1]),o.element[a].set(this._meshInfo[t].colors[4*s+0],this._meshInfo[t].colors[4*s+1],this._meshInfo[t].colors[4*s+2],this._meshInfo[t].colors[4*s+3]),o.element[r].set(this._meshInfo[t].outlines[3*s+0],this._meshInfo[t].outlines[3*s+1],this._meshInfo[t].outlines[3*s+2]),o.element[l].set(this._meshInfo[t].shadows[3*s+0],this._meshInfo[t].shadows[3*s+1],this._meshInfo[t].shadows[3*s+2])),o.next();o.end(),this._meshInfo[t].meshInstance.mesh.aabb.compute(this._meshInfo[t].positions),this._meshInfo[t].meshInstance._aabbVer=-1}this._aabbDirty=!0}_onFontRender(){this.font=this._font}_onFontLoad(t){this.font!==t.resource&&(this.font=t.resource)}_onFontChange(t,s,e,i){if("data"===s){this._font.data=e;const t=this._font.data.info.maps.length;for(let s=0;s<t;s++){if(!this._meshInfo[s])continue;const t=this._meshInfo[s].meshInstance;t&&(t.setParameter("font_sdfIntensity",this._font.intensity),t.setParameter("font_pxrange",this._getPxRange(this._font)),t.setParameter("font_textureWidth",this._font.data.info.maps[s].width))}}}_onFontRemove(t){}_setTextureParams(t,s){this._font&&(this._font.type===p?(t.deleteParameter("texture_emissiveMap"),t.deleteParameter("texture_opacityMap"),t.setParameter("texture_msdfMap",s)):this._font.type===w&&(t.deleteParameter("texture_msdfMap"),t.setParameter("texture_emissiveMap",s),t.setParameter("texture_opacityMap",s)))}_getPxRange(t){const s=Object.keys(this._font.data.chars);for(let t=0;t<s.length;t++){const e=this._font.data.chars[s[t]];if(e.range)return(e.scale||1)*e.range}return 2}_getUv(t){const s=this._font.data;if(!s.chars[t]){const t=" ";return s.chars[t]?this._getUv(t):[0,0,0,0]}const e=s.chars[t].map,i=s.info.maps[e].width,o=s.info.maps[e].height,h=s.chars[t].x,n=s.chars[t].y,a=h,r=n,l=h+s.chars[t].width,_=n-s.chars[t].height,m=1-s.chars[t].height/o;return[a/i,m-r/o,l/i,m-_/o]}onEnable(){this._fontAsset.autoLoad=!0,this._model&&this._element.addModelToLayers(this._model)}onDisable(){this._fontAsset.autoLoad=!1,this._model&&this._element.removeModelFromLayers(this._model)}_setStencil(t){if(this._model){const s=this._model.meshInstances;for(let e=0;e<s.length;e++)s[e].stencilFront=t,s[e].stencilBack=t}}_shouldAutoFitWidth(){return this._autoFitWidth&&!this._autoWidth}_shouldAutoFitHeight(){return this._autoFitHeight&&!this._autoHeight}_shouldAutoFit(){return this._autoFitWidth&&!this._autoWidth||this._autoFitHeight&&!this._autoHeight}_calculateCharsPerTexture(t){const s={};void 0===t&&(t=this._symbols.length);for(let e=0,i=t;e<i;e++){const t=this._symbols[e];let i=this._font.data.chars[t];i||(i=this._font.data.chars[" "],i||(i=this._font.data.chars[Object.keys(this._font.data.chars)[0]]));const o=i.map;s[o]?s[o]++:s[o]=1}return s}_updateRenderRange(){const t=0===this._rangeStart?0:this._calculateCharsPerTexture(this._rangeStart),s=0===this._rangeEnd?0:this._calculateCharsPerTexture(this._rangeEnd);for(let e=0,i=this._meshInfo.length;e<i;e++){const i=t[e]||0,o=s[e]||0,h=this._meshInfo[e].meshInstance;if(h){const t=h.mesh;t&&(t.primitive[0].base=3*i*2,t.primitive[0].count=3*(o-i)*2)}}}set text(t){this._i18nKey=null;const s=null!=t&&t.toString()||"";this._setText(s)}get text(){return this._text}set key(t){const s=null!==t?t.toString():null;this._i18nKey!==s&&(this._i18nKey=s,s?(this._fontAsset.disableLocalization=!1,this._resetLocalizedText()):this._fontAsset.disableLocalization=!0)}get key(){return this._i18nKey}set color(t){const s=t.r,e=t.g,i=t.b;if((this._color.r!==s||this._color.g!==e||this._color.b!==i)&&(this._color.r=s,this._color.g=e,this._color.b=i,this._model)){if(this._symbolColors)this._font&&this._updateText();else{this._colorUniform[0]=this._color.r,this._colorUniform[1]=this._color.g,this._colorUniform[2]=this._color.b;for(let t=0,s=this._model.meshInstances.length;t<s;t++){this._model.meshInstances[t].setParameter("material_emissive",this._colorUniform)}}this._element&&this._element.fire("set:color",this._color)}}get color(){return this._color}set opacity(t){if(this._color.a!==t&&(this._color.a=t,this._model))for(let s=0,e=this._model.meshInstances.length;s<e;s++){this._model.meshInstances[s].setParameter("material_opacity",t)}this._element&&this._element.fire("set:opacity",t)}get opacity(){return this._color.a}set lineHeight(t){const s=this._lineHeight;this._lineHeight=t,this._scaledLineHeight=t,s!==t&&this._font&&this._updateText()}get lineHeight(){return this._lineHeight}set wrapLines(t){const s=this._wrapLines;this._wrapLines=t,s!==t&&this._font&&this._updateText()}get wrapLines(){return this._wrapLines}get lines(){return this._lineContents}set spacing(t){const s=this._spacing;this._spacing=t,s!==t&&this._font&&this._updateText()}get spacing(){return this._spacing}set fontSize(t){const s=this._fontSize;this._fontSize=t,this._originalFontSize=t,s!==t&&this._font&&this._updateText()}get fontSize(){return this._fontSize}set fontAsset(t){this._fontAsset.defaultAsset=t}get fontAsset(){return this._fontAsset.localizedAsset}set font(t){let s;if(this._font&&(s=this._font.type,this._font.off&&this._font.off("render",this._onFontRender,this)),this._font=t,this._fontMinY=0,this._fontMaxY=0,!t)return;const e=this._font.data;for(const t in e.chars){const s=e.chars[t];s.bounds&&(this._fontMinY=Math.min(this._fontMinY,s.bounds[1]),this._fontMaxY=Math.max(this._fontMaxY,s.bounds[3]))}if(this._font.on&&this._font.on("render",this._onFontRender,this),this._fontAsset.localizedAsset){this._system.app.assets.get(this._fontAsset.localizedAsset).resource!==this._font&&(this._fontAsset.defaultAsset=null)}if(t.type!==s){const t=this._element._isScreenSpace();this._updateMaterial(t)}for(let t=0,s=this._font.textures.length;t<s;t++)if(this._meshInfo[t]){const s=this._meshInfo[t].meshInstance;s&&(s.setParameter("font_sdfIntensity",this._font.intensity),s.setParameter("font_pxrange",this._getPxRange(this._font)),s.setParameter("font_textureWidth",this._font.data.info.maps[t].width),this._setTextureParams(s,this._font.textures[t]))}else this._meshInfo[t]=new y;let i=!1;for(let t=this._font.textures.length;t<this._meshInfo.length;t++)this._meshInfo[t].meshInstance&&(i||(this._element.removeModelFromLayers(this._model),i=!0),this._removeMeshInstance(this._meshInfo[t].meshInstance));this._meshInfo.length>this._font.textures.length&&(this._meshInfo.length=this._font.textures.length),this._updateText()}get font(){return this._font}set alignment(t){t instanceof i?this._alignment.set(t.x,t.y):this._alignment.set(t[0],t[1]),this._font&&this._updateText()}get alignment(){return this._alignment}set autoWidth(t){const s=this._autoWidth;if(this._autoWidth=t,t&&Math.abs(this._element.anchor.x-this._element.anchor.z)<1e-4&&(this._element.width=this.width),s!==t){const t=this._shouldAutoFit()?this._maxFontSize:this._originalFontSize;t!==this._fontSize&&(this._fontSize=t,this._font&&this._updateText())}}get autoWidth(){return this._autoWidth}set autoHeight(t){const s=this._autoHeight;if(this._autoHeight=t,t&&Math.abs(this._element.anchor.y-this._element.anchor.w)<1e-4&&(this._element.height=this.height),s!==t){const t=this._shouldAutoFit()?this._maxFontSize:this._originalFontSize;t!==this._fontSize&&(this._fontSize=t,this._font&&this._updateText())}}get autoHeight(){return this._autoHeight}set rtlReorder(t){this._rtlReorder!==t&&(this._rtlReorder=t,this._font&&this._updateText())}get rtlReorder(){return this._rtlReorder}set unicodeConverter(t){this._unicodeConverter!==t&&(this._unicodeConverter=t,this._setText(this._text))}get unicodeConverter(){return this._unicodeConverter}get aabb(){if(this._aabbDirty){let t=!1;for(let s=0;s<this._meshInfo.length;s++)this._meshInfo[s].meshInstance&&(t?this._aabb.add(this._meshInfo[s].meshInstance.aabb):(this._aabb.copy(this._meshInfo[s].meshInstance.aabb),t=!0));this._aabbDirty=!1}return this._aabb}set outlineColor(t){const s=t instanceof e?t.r:t[0],i=t instanceof e?t.g:t[1],o=t instanceof e?t.b:t[2],h=t instanceof e?t.a:t[3];if((this._outlineColor.r!==s||this._outlineColor.g!==i||this._outlineColor.b!==o||this._outlineColor.a!==h)&&(this._outlineColor.r=s,this._outlineColor.g=i,this._outlineColor.b=o,this._outlineColor.a=h,this._model)){if(this._symbolOutlineParams)this._font&&this._updateText();else{this._outlineColorUniform[0]=this._outlineColor.r,this._outlineColorUniform[1]=this._outlineColor.g,this._outlineColorUniform[2]=this._outlineColor.b,this._outlineColorUniform[3]=this._outlineColor.a;for(let t=0,s=this._model.meshInstances.length;t<s;t++){this._model.meshInstances[t].setParameter("outline_color",this._outlineColorUniform)}}this._element&&this._element.fire("set:outline",this._color)}}get outlineColor(){return this._outlineColor}set outlineThickness(t){const s=this._outlineThickness;if(this._outlineThickness=t,s!==t&&this._font){if(!this._model)return;if(this._symbolOutlineParams)this._font&&this._updateText();else for(let t=0,s=this._model.meshInstances.length;t<s;t++){this._model.meshInstances[t].setParameter("outline_thickness",this._outlineThicknessScale*this._outlineThickness)}}}get outlineThickness(){return this._outlineThickness}set shadowColor(t){const s=t instanceof e?t.r:t[0],i=t instanceof e?t.g:t[1],o=t instanceof e?t.b:t[2],h=t instanceof e?t.a:t[3];if((this._shadowColor.r!==s||this._shadowColor.g!==i||this._shadowColor.b!==o||this._shadowColor.a!==h)&&(this._shadowColor.r=s,this._shadowColor.g=i,this._shadowColor.b=o,this._shadowColor.a=h,this._model))if(this._symbolShadowParams)this._font&&this._updateText();else{this._shadowColorUniform[0]=this._shadowColor.r,this._shadowColorUniform[1]=this._shadowColor.g,this._shadowColorUniform[2]=this._shadowColor.b,this._shadowColorUniform[3]=this._shadowColor.a;for(let t=0,s=this._model.meshInstances.length;t<s;t++){this._model.meshInstances[t].setParameter("shadow_color",this._shadowColorUniform)}}}get shadowColor(){return this._shadowColor}set shadowOffset(t){const s=t instanceof i?t.x:t[0],e=t instanceof i?t.y:t[1];if((this._shadowOffset.x!==s||this._shadowOffset.y!==e)&&(this._shadowOffset.set(s,e),this._font&&this._model))if(this._symbolShadowParams)this._updateText();else for(let t=0,s=this._model.meshInstances.length;t<s;t++){const s=-this._font.data.info.maps[t].width/this._font.data.info.maps[t].height;this._shadowOffsetUniform[0]=this._shadowOffsetScale*this._shadowOffset.x,this._shadowOffsetUniform[1]=s*this._shadowOffsetScale*this._shadowOffset.y;this._model.meshInstances[t].setParameter("shadow_offset",this._shadowOffsetUniform)}}get shadowOffset(){return this._shadowOffset}set minFontSize(t){this._minFontSize!==t&&(this._minFontSize=t,this.font&&this._shouldAutoFit()&&this._updateText())}get minFontSize(){return this._minFontSize}set maxFontSize(t){this._maxFontSize!==t&&(this._maxFontSize=t,this.font&&this._shouldAutoFit()&&this._updateText())}get maxFontSize(){return this._maxFontSize}set autoFitWidth(t){this._autoFitWidth!==t&&(this._autoFitWidth=t,this._fontSize=this._shouldAutoFit()?this._maxFontSize:this._originalFontSize,this.font&&this._updateText())}get autoFitWidth(){return this._autoFitWidth}set autoFitHeight(t){this._autoFitHeight!==t&&(this._autoFitHeight=t,this._fontSize=this._shouldAutoFit()?this._maxFontSize:this._originalFontSize,this.font&&this._updateText())}get autoFitHeight(){return this._autoFitHeight}set maxLines(t){this._maxLines!==t&&(null===t&&-1===this._maxLines||(this._maxLines=null===t?-1:t,this.font&&this._wrapLines&&this._updateText()))}get maxLines(){return this._maxLines}set enableMarkup(t){if(t=!!t,this._enableMarkup===t)return;this._enableMarkup=t,this.font&&this._updateText();const s=this._element._isScreenSpace();this._updateMaterial(s)}get enableMarkup(){return this._enableMarkup}get symbols(){return this._symbols}get symbolColors(){return null===this._symbolColors?null:this._symbolColors.map((function(t){return this._colorPalette.slice(3*t,3*t+3)}),this)}get symbolOutlineParams(){return null===this._symbolOutlineParams?null:this._symbolOutlineParams.map((function(t){return this._outlinePalette.slice(5*t,5*t+5)}),this)}get symbolShadowParams(){return null===this._symbolShadowParams?null:this._symbolShadowParams.map((function(t){return this._shadowPalette.slice(6*t,6*t+6)}),this)}get rtl(){return this._rtl}set rangeStart(t){(t=Math.max(0,Math.min(t,this._symbols.length)))!==this._rangeStart&&(this._rangeStart=t,this._updateRenderRange())}get rangeStart(){return this._rangeStart}set rangeEnd(t){(t=Math.max(this._rangeStart,Math.min(t,this._symbols.length)))!==this._rangeEnd&&(this._rangeEnd=t,this._updateRenderRange())}get rangeEnd(){return this._rangeEnd}}export{U as TextElement};