public Rectangle GetCharacterRect(char c, int lineNumber, ref Point point, out Rectangle destinationRectangle, out int pageIndex, float fontScale = 1) { BitmapCharacterInfo characterInfo = GetCharacterInfo(c); int sourceLeft = characterInfo.GetPixelLeft(Texture); int sourceTop = characterInfo.GetPixelTop(Texture); int sourceWidth = characterInfo.GetPixelRight(Texture) - sourceLeft; int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop; int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels); // There could be some offset for this character int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels); point.X += (int)(xOffset * fontScale); point.Y = (int)((lineNumber * LineHeightInPixels + distanceFromTop) * fontScale); var sourceRectangle = new Microsoft.Xna.Framework.Rectangle( sourceLeft, sourceTop, sourceWidth, sourceHeight); pageIndex = characterInfo.PageNumber; destinationRectangle = new Rectangle(point.X, point.Y, (int)(sourceWidth * fontScale), (int)(sourceHeight * fontScale)); point.X -= (int)(xOffset * fontScale); point.X += (int)(characterInfo.GetXAdvanceInPixels(LineHeightInPixels) * fontScale); return(sourceRectangle); }
private Texture2D RenderToTexture2DUsingImageData(IEnumerable lines, HorizontalAlignment horizontalAlignment, SystemManagers managers) { ImageData[] imageDatas = new ImageData[this.mTextures.Length]; for (int i = 0; i < imageDatas.Length; i++) { // Only use the existing buffer on one-page fonts var bufferToUse = mColorBuffer; if (i > 0) { bufferToUse = null; } imageDatas[i] = ImageData.FromTexture2D(this.mTextures[i], managers, bufferToUse); } Point point = new Point(); int maxWidthSoFar = 0; int requiredWidth = 0; int requiredHeight = 0; List <int> widths = new List <int>(); foreach (string line in lines) { requiredHeight += LineHeightInPixels; requiredWidth = 0; requiredWidth = MeasureString(line); widths.Add(requiredWidth); maxWidthSoFar = System.Math.Max(requiredWidth, maxWidthSoFar); } const int MaxWidthAndHeight = 2048; // change this later? maxWidthSoFar = System.Math.Min(maxWidthSoFar, MaxWidthAndHeight); requiredHeight = System.Math.Min(requiredHeight, MaxWidthAndHeight); ImageData imageData = null; if (maxWidthSoFar != 0) { imageData = new ImageData(maxWidthSoFar, requiredHeight, managers); int lineNumber = 0; foreach (string line in lines) { point.X = 0; if (horizontalAlignment == HorizontalAlignment.Right) { point.X = maxWidthSoFar - widths[lineNumber]; } else if (horizontalAlignment == HorizontalAlignment.Center) { point.X = (maxWidthSoFar - widths[lineNumber]) / 2; } foreach (char c in line) { BitmapCharacterInfo characterInfo = GetCharacterInfo(c); int sourceLeft = characterInfo.GetPixelLeft(Texture); int sourceTop = characterInfo.GetPixelTop(Texture); int sourceWidth = characterInfo.GetPixelRight(Texture) - sourceLeft; int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop; int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels); // There could be some offset for this character int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels); point.X += xOffset; point.Y = lineNumber * LineHeightInPixels + distanceFromTop; Microsoft.Xna.Framework.Rectangle sourceRectangle = new Microsoft.Xna.Framework.Rectangle( sourceLeft, sourceTop, sourceWidth, sourceHeight); int pageIndex = characterInfo.PageNumber; imageData.Blit(imageDatas[pageIndex], sourceRectangle, point); point.X -= xOffset; point.X += characterInfo.GetXAdvanceInPixels(LineHeightInPixels); } point.X = 0; lineNumber++; } } if (imageData != null) { // We don't want // to generate mipmaps // because text is usually // rendered pixel-perfect. const bool generateMipmaps = false; return(imageData.ToTexture2D(generateMipmaps)); } else { return(null); } }
private Texture2D RenderToTexture2DUsingRenderStates(IEnumerable <string> lines, HorizontalAlignment horizontalAlignment, SystemManagers managers, Texture2D toReplace = null) { if (managers == null) { managers = SystemManagers.Default; } ////////////////// Early out ///////////////////////// if (managers.Renderer.GraphicsDevice.GraphicsDeviceStatus != GraphicsDeviceStatus.Normal) { return(null); } ///////////////// End early out ////////////////////// RenderTarget2D renderTarget = null; Point point = new Point(); int requiredWidth; int requiredHeight; List <int> widths; GetRequiredWithAndHeight(lines, out requiredWidth, out requiredHeight, out widths); if (requiredWidth != 0) { var oldViewport = managers.Renderer.GraphicsDevice.Viewport; if (toReplace != null && requiredWidth == toReplace.Width && requiredHeight == toReplace.Height) { renderTarget = toReplace as RenderTarget2D; } else { renderTarget = new RenderTarget2D(managers.Renderer.GraphicsDevice, requiredWidth, requiredHeight); } managers.Renderer.GraphicsDevice.SetRenderTarget(renderTarget); SpriteBatch spriteBatch = managers.Renderer.SpriteBatch; { managers.Renderer.GraphicsDevice.Clear(Color.Transparent); spriteBatch.Begin(); int lineNumber = 0; foreach (string line in lines) { // scoot over to leave room for the outline point.X = mOutlineThickness; if (horizontalAlignment == HorizontalAlignment.Right) { point.X = requiredWidth - widths[lineNumber]; } else if (horizontalAlignment == HorizontalAlignment.Center) { point.X = (requiredWidth - widths[lineNumber]) / 2; } foreach (char c in line) { BitmapCharacterInfo characterInfo = GetCharacterInfo(c); int sourceLeft = characterInfo.GetPixelLeft(Texture); int sourceTop = characterInfo.GetPixelTop(Texture); int sourceWidth = characterInfo.GetPixelRight(Texture) - sourceLeft; int sourceHeight = characterInfo.GetPixelBottom(Texture) - sourceTop; int distanceFromTop = characterInfo.GetPixelDistanceFromTop(LineHeightInPixels); // There could be some offset for this character int xOffset = characterInfo.GetPixelXOffset(LineHeightInPixels); point.X += xOffset; point.Y = lineNumber * LineHeightInPixels + distanceFromTop; Microsoft.Xna.Framework.Rectangle sourceRectangle = new Microsoft.Xna.Framework.Rectangle( sourceLeft, sourceTop, sourceWidth, sourceHeight); int pageIndex = characterInfo.PageNumber; Rectangle destinationRectangle = new Rectangle(point.X, point.Y, sourceWidth, sourceHeight); spriteBatch.Draw(mTextures[pageIndex], destinationRectangle, sourceRectangle, Color.White); point.X -= xOffset; point.X += characterInfo.GetXAdvanceInPixels(LineHeightInPixels); } point.X = 0; lineNumber++; } spriteBatch.End(); } managers.Renderer.GraphicsDevice.SetRenderTarget(null); managers.Renderer.GraphicsDevice.Viewport = oldViewport; } return(renderTarget); }