Axiom.Overlays.Elements.TextArea.UpdateGeometry C# (CSharp) Method

UpdateGeometry() protected method

protected UpdateGeometry ( ) : void
return void
		protected unsafe void UpdateGeometry()
		{
			if ( font == null || text == null || !this.isGeomPositionsOutOfDate )
			{
				// must not be initialized yet, probably due to order of creation in a template
				return;
			}

			int charLength = text.Length;
			// make sure the buffers are big enough
			CheckMemoryAllocation( charLength );

			renderOperation.vertexData.vertexCount = charLength * 6;

			// get pos/tex buffer
			HardwareVertexBuffer buffer = renderOperation.vertexData.vertexBufferBinding.GetBuffer( POSITION_TEXCOORD_BINDING );
			IntPtr data = buffer.Lock( BufferLocking.Discard );
			float largestWidth = 0.0f;
			float left = this.DerivedLeft * 2.0f - 1.0f;
			float top = -( ( this.DerivedTop * 2.0f ) - 1.0f );

			// derive space width from the size of a capital A
			if ( spaceWidth == 0 )
			{
				spaceWidth = font.GetGlyphAspectRatio( 'A' ) * charHeight * 2.0f * viewportAspectCoef;
			}


			bool newLine = true;
			int index = 0;

			// go through each character and process
			for ( int i = 0; i < charLength; i++ )
			{
				char c = text[ i ];

				if ( newLine )
				{
					float length = 0.0f;

					// precalc the length of this line
					for ( int j = i; j < charLength && text[ j ] != '\n'; j++ )
					{
						if ( text[ j ] == ' ' )
						{
							length += spaceWidth;
						}
						else
						{
							length += font.GetGlyphAspectRatio( text[ j ] ) * charHeight * 2f * viewportAspectCoef;
						}
					} // for j

					if ( this.horzAlign == HorizontalAlignment.Right )
					{
						left -= length;
					}
					else if ( this.horzAlign == HorizontalAlignment.Center )
					{
						left -= length * 0.5f;
					}

					newLine = false;
				} // if newLine

				if ( c == '\n' )
				{
					left = this.DerivedLeft * 2.0f - 1.0f;
					top -= charHeight * 2.0f;
					newLine = true;
					// reduce tri count
					renderOperation.vertexData.vertexCount -= 6;
					continue;
				}

				if ( c == ' ' )
				{
					// leave a gap, no tris required
					left += spaceWidth;
					// reduce tri count
					renderOperation.vertexData.vertexCount -= 6;
					continue;
				}

				float horizHeight = font.GetGlyphAspectRatio( c ) * viewportAspectCoef;
				Real u1, u2, v1, v2;

				// get the texcoords for the specified character
				font.GetGlyphTexCoords( c, out u1, out v1, out u2, out v2 );

				// each vert is (x, y, z, u, v)
				// first tri
				// upper left
				float* vertPtr = (float*)data.ToPointer();
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u1;
				vertPtr[ index++ ] = v1;

				top -= charHeight * 2.0f;

				// bottom left
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u1;
				vertPtr[ index++ ] = v2;

				top += charHeight * 2.0f;
				left += horizHeight * charHeight * 2.0f;

				// top right
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u2;
				vertPtr[ index++ ] = v1;

				// second tri

				// top right (again)
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u2;
				vertPtr[ index++ ] = v1;

				top -= charHeight * 2.0f;
				left -= horizHeight * charHeight * 2.0f;

				// bottom left (again)
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u1;
				vertPtr[ index++ ] = v2;

				left += horizHeight * charHeight * 2.0f;

				// bottom right
				vertPtr[ index++ ] = left;
				vertPtr[ index++ ] = top;
				vertPtr[ index++ ] = -1.0f;
				vertPtr[ index++ ] = u2;
				vertPtr[ index++ ] = v2;

				// go back up with top
				top += charHeight * 2.0f;

				float currentWidth = ( left + 1 ) / 2 - this.DerivedLeft;

				if ( currentWidth > largestWidth )
				{
					largestWidth = currentWidth;
				}
			} // for i

			// unlock vertex buffer
			buffer.Unlock();

			if ( metricsMode == MetricsMode.Pixels )
			{
				// Derive parametric version of dimensions
				float vpWidth = OverlayManager.Instance.ViewportWidth;

				largestWidth *= vpWidth;
			}

			// record the width as the longest width calculated for any of the lines
			if ( this.Width < largestWidth )
			{
				this.Width = largestWidth;
			}
		}