helper that wraps either a string or StringBuilder and provides a common API to read them for measuring/drawing
Example #1
0
		/// <summary>
		/// Submit a text string of sprites for drawing in the current batch.
		/// </summary>
		/// <param name="spriteFont">A font.</param>
		/// <param name="text">The text which will be drawn.</param>
		/// <param name="position">The drawing location on screen.</param>
		/// <param name="color">A color mask.</param>
		/// <param name="rotation">A rotation of this string.</param>
		/// <param name="origin">Center of the rotation. 0,0 by default.</param>
		/// <param name="scale">A scaling of this string.</param>
		/// <param name="effects">Modificators for drawing. Can be combined.</param>
		/// <param name="layerDepth">A depth of the layer of this string.</param>
		public static void drawString( this Batcher batcher, BitmapFont bitmapFont, string text, Vector2 position, Color color,
			float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth )
		{
			var scaleVec = new Vector2( scale, scale );
			var source = new FontCharacterSource( text );
			bitmapFont.drawInto( batcher, ref source, position, color, rotation, origin, scaleVec, effects, layerDepth );
		}
Example #2
0
		/// <summary>
		/// Returns the size of the contents of a StringBuilder when
		/// rendered in this font.
		/// </summary>
		/// <param name="text">The text to measure.</param>
		/// <returns>The size, in pixels, of 'text' when rendered in
		/// this font.</returns>
		public Vector2 measureString( StringBuilder text )
		{
			var source = new FontCharacterSource( text );
			Vector2 size;
			measureString( ref source, out size );
			return size;
		}
Example #3
0
		public static void drawString( this Batcher batcher, NezSpriteFont spriteFont, string text, Vector2 position, Color color, float rotation,
			Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth )
		{
			Assert.isFalse( text == null );

			if( text.Length == 0 )
				return;

			var source = new FontCharacterSource( text );
			spriteFont.drawInto( batcher, ref source, position, color, rotation, origin, scale, effects, layerDepth );
		}
Example #4
0
		void measureString( ref FontCharacterSource text, out Vector2 size )
		{
			if( text.Length == 0 )
			{
				size = Vector2.Zero;
				return;
			}

			// Get the default glyph here once.
			SpriteFont.Glyph? defaultGlyph = null;
			if( _font.DefaultCharacter.HasValue )
				defaultGlyph = _glyphs[_font.DefaultCharacter.Value];

			var width = 0.0f;
			var finalLineHeight = (float)_font.LineSpacing;

			var currentGlyph = SpriteFont.Glyph.Empty;
			var offset = Vector2.Zero;
			var firstGlyphOfLine = true;

			for( var i = 0; i < text.Length; ++i )
			{
				var c = text[i];

				if( c == '\r' )
					continue;

				if( c == '\n' )
				{
					finalLineHeight = _font.LineSpacing;

					offset.X = 0;
					offset.Y += _font.LineSpacing;
					firstGlyphOfLine = true;
					continue;
				}

				if( !_glyphs.TryGetValue( c, out currentGlyph ) )
				{
					if( !defaultGlyph.HasValue )
						throw new ArgumentException( "Errors.TextContainsUnresolvableCharacters", "text" );

					currentGlyph = defaultGlyph.Value;
				}

				// The first character on a line might have a negative left side bearing.
				// In this scenario, SpriteBatch/SpriteFont normally offset the text to the right,
				//  so that text does not hang off the left side of its rectangle.
				if( firstGlyphOfLine )
				{
					offset.X = Math.Max( currentGlyph.LeftSideBearing, 0 );
					firstGlyphOfLine = false;
				}
				else
				{
					offset.X += _font.Spacing + currentGlyph.LeftSideBearing;
				}

				offset.X += currentGlyph.Width;

				var proposedWidth = offset.X + Math.Max( currentGlyph.RightSideBearing, 0 );
				if( proposedWidth > width )
					width = proposedWidth;

				offset.X += currentGlyph.RightSideBearing;

				if( currentGlyph.Cropping.Height > finalLineHeight )
					finalLineHeight = currentGlyph.Cropping.Height;
			}

			size.X = width;
			size.Y = offset.Y + finalLineHeight;
		}
Example #5
0
		public void drawInto( Batcher batcher, ref FontCharacterSource text, Vector2 position, Color color,
		                        float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth )
		{
			var flipAdjustment = Vector2.Zero;

			var flippedVert = ( effect & SpriteEffects.FlipVertically ) == SpriteEffects.FlipVertically;
			var flippedHorz = ( effect & SpriteEffects.FlipHorizontally ) == SpriteEffects.FlipHorizontally;

			if( flippedVert || flippedHorz )
			{
				Vector2 size;
				measureString( ref text, out size );

				if( flippedHorz )
				{
					origin.X *= -1;
					flipAdjustment.X = -size.X;
				}

				if( flippedVert )
				{
					origin.Y *= -1;
					flipAdjustment.Y = _font.LineSpacing - size.Y;
				}
			}

			// TODO: This looks excessive... i suspect we could do most of this with simple vector math and avoid this much matrix work.
			var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != Vector2.One;
			if( requiresTransformation )
			{
				Matrix2D temp;
				Matrix2D.createTranslation( -origin.X, -origin.Y, out _transformationMatrix );
				Matrix2D.createScale( ( flippedHorz ? -scale.X : scale.X ), ( flippedVert ? -scale.Y : scale.Y ), out temp );
				Matrix2D.multiply( ref _transformationMatrix, ref temp, out _transformationMatrix );
				Matrix2D.createTranslation( flipAdjustment.X, flipAdjustment.Y, out temp );
				Matrix2D.multiply( ref temp, ref _transformationMatrix, out _transformationMatrix );
				Matrix2D.createRotation( rotation, out temp );
				Matrix2D.multiply( ref _transformationMatrix, ref temp, out _transformationMatrix );
				Matrix2D.createTranslation( position.X, position.Y, out temp );
				Matrix2D.multiply( ref _transformationMatrix, ref temp, out _transformationMatrix );
			}

			// Get the default glyph here once.
			SpriteFont.Glyph? defaultGlyph = null;
			if( _font.DefaultCharacter.HasValue )
				defaultGlyph = _glyphs[_font.DefaultCharacter.Value];

			var currentGlyph = SpriteFont.Glyph.Empty;
			var offset = requiresTransformation ? Vector2.Zero : position - origin;
			var firstGlyphOfLine = true;

			for( var i = 0; i < text.Length; ++i )
			{
				var c = text[i];

				if( c == '\r' )
					continue;

				if( c == '\n' )
				{
					offset.X = requiresTransformation ? 0f : position.X - origin.X;
					offset.Y += _font.LineSpacing;
					firstGlyphOfLine = true;
					continue;
				}

				if( !_glyphs.TryGetValue( c, out currentGlyph ) )
				{
					if( !defaultGlyph.HasValue )
						throw new ArgumentException( "Errors.TextContainsUnresolvableCharacters", "text" );

					currentGlyph = defaultGlyph.Value;
				}

				// The first character on a line might have a negative left side bearing.
				// In this scenario, SpriteBatch/SpriteFont normally offset the text to the right,
				// so that text does not hang off the left side of its rectangle.
				if( firstGlyphOfLine )
				{
					offset.X += Math.Max( currentGlyph.LeftSideBearing, 0 );
					firstGlyphOfLine = false;
				}
				else
				{
					offset.X += _font.Spacing + currentGlyph.LeftSideBearing;
				}

				var p = offset;

				if( flippedHorz )
					p.X += currentGlyph.BoundsInTexture.Width;
				p.X += currentGlyph.Cropping.X;

				if( flippedVert )
					p.Y += currentGlyph.BoundsInTexture.Height - _font.LineSpacing;
				p.Y += currentGlyph.Cropping.Y;

				// transform our point if we need to
				if( requiresTransformation )
					Vector2Ext.transform( ref p, ref _transformationMatrix, out p );

				var destRect = RectangleExt.fromFloats( p.X, p.Y, 
					               currentGlyph.BoundsInTexture.Width * scale.X,
					               currentGlyph.BoundsInTexture.Height * scale.Y );

				batcher.draw( _font.Texture, destRect, currentGlyph.BoundsInTexture, color, rotation, Vector2.Zero, effect, depth );

				offset.X += currentGlyph.Width + currentGlyph.RightSideBearing;
			}
		}
Example #6
0
		void IFont.drawInto( Batcher batcher, StringBuilder text, Vector2 position, Color color,
			float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth )
		{
			var source = new FontCharacterSource( text );
			drawInto( batcher, ref source, position, color, rotation, origin, scale, effect, depth );
		}
Example #7
0
		/// <summary>
		/// Submit a text string of sprites for drawing in the current batch.
		/// </summary>
		/// <param name="spriteFont">A font.</param>
		/// <param name="text">The text which will be drawn.</param>
		/// <param name="position">The drawing location on screen.</param>
		/// <param name="color">A color mask.</param>
		public static void drawString( this Batcher batcher, BitmapFont bitmapFont, StringBuilder text, Vector2 position, Color color )
		{
			var source = new FontCharacterSource( text );
			bitmapFont.drawInto( batcher, ref source, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0f );
		}
Example #8
0
		/// <summary>
		/// Submit a text string of sprites for drawing in the current batch.
		/// </summary>
		/// <param name="spriteFont">A font.</param>
		/// <param name="text">The text which will be drawn.</param>
		/// <param name="position">The drawing location on screen.</param>
		/// <param name="color">A color mask.</param>
		/// <param name="rotation">A rotation of this string.</param>
		/// <param name="origin">Center of the rotation. 0,0 by default.</param>
		/// <param name="scale">A scaling of this string.</param>
		/// <param name="effects">Modificators for drawing. Can be combined.</param>
		/// <param name="layerDepth">A depth of the layer of this string.</param>
		public static void DrawString( this SpriteBatch spriteBatch, BitmapFont bitmapFont, string text, Vector2 position, Color color,
			float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth )
		{
			var source = new FontCharacterSource( text );
			bitmapFont.drawInto( spriteBatch, ref source, position, color, rotation, origin, scale, effects, layerDepth );
		}
Example #9
0
		/// <summary>
		/// Submit a text string of sprites for drawing in the current batch.
		/// </summary>
		/// <param name="spriteFont">A font.</param>
		/// <param name="text">The text which will be drawn.</param>
		/// <param name="position">The drawing location on screen.</param>
		/// <param name="color">A color mask.</param>
		public static void DrawString( this SpriteBatch spriteBatch, BitmapFont bitmapFont, string text, Vector2 position, Color color )
		{
			var source = new FontCharacterSource( text );
			bitmapFont.drawInto(
				spriteBatch, ref source, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0f );
		}