/// <summary> /// Returns an element back to the pool. /// </summary> /// <param name="rEdge"></param> public static void Release(TextFont rInstance) { if (object.ReferenceEquals(rInstance, null)) { return; } if (rInstance.Texture != null) { Texture2D.Destroy(rInstance.Texture); rInstance.Texture = null; } foreach (TextCharacter lCharacter in rInstance.Characters.Values) { TextCharacter.Release(lCharacter); } // Set values rInstance.Font = null; rInstance.Characters.Clear(); rInstance.MinX = 0; rInstance.MaxX = 0; rInstance.MinY = 0; rInstance.MaxY = 0; // Make it available to others. sPool.Release(rInstance); }
/// <summary> /// Pulls an object from the pool. /// </summary> /// <returns></returns> public static TextCharacter Allocate() { // Grab the next available object TextCharacter lInstance = sPool.Allocate(); // Return the allocated instance (should be cleaned before // being put back into the pool) return(lInstance); }
/// <summary> /// Returns an element back to the pool. /// </summary> /// <param name="rEdge"></param> public static void Release(TextCharacter rInstance) { if (object.ReferenceEquals(rInstance, null)) { return; } // Set values rInstance.Character = (char)0; rInstance.Pixels = null; rInstance.Width = 0; rInstance.Height = 0; // Make it available to others. sPool.Release(rInstance); }
/// <summary> /// If the pixels are cached, grab them. Otherwise, create the cache /// </summary> /// <param name="rFont"></param> /// <param name="rCharacter"></param> /// <returns></returns> private static TextCharacter GetCharacterPixels(Font rFont, char rCharacter) { // If we already grabbed the pixesl, this is easy if (!mFonts.ContainsKey(rFont)) { return(null); } if (mFonts[rFont].Characters.ContainsKey(rCharacter)) { return(mFonts[rFont].Characters[rCharacter]); } // Grab our font's source texture Texture2D lFontTexture = mFonts[rFont].Texture; // Process each character in the text int x, y, w, h; CharacterInfo lInfo; Vector2 lGlyphBottomLeft = Vector2.zero; Color[] lPixels = null; rFont.GetCharacterInfo(rCharacter, out lInfo); // Rotate 90-counter-clockwise needed if (lInfo.uvBottomLeft.x == lInfo.uvBottomRight.x) { // No flip needed if (lInfo.uvBottomLeft.y > lInfo.uvBottomRight.y) { lGlyphBottomLeft = lInfo.uvBottomRight; } else { lGlyphBottomLeft = lInfo.uvBottomLeft; } } // No rotate needed else { // Flip needed if (lInfo.uvBottomLeft.y > lInfo.uvTopLeft.y) { lGlyphBottomLeft = lInfo.uvTopLeft; } // No flip needed else { lGlyphBottomLeft = lInfo.uvBottomLeft; } } x = (int)((float)lFontTexture.width * lGlyphBottomLeft.x) + 0; y = (int)((float)lFontTexture.height * lGlyphBottomLeft.y) + 0; w = lInfo.glyphWidth; h = lInfo.glyphHeight; // We need to rotate the pixels if (lInfo.uvBottomLeft.x == lInfo.uvBottomRight.x) { if (lInfo.uvBottomLeft.y > lInfo.uvBottomRight.y) { lPixels = lFontTexture.GetPixels(x, y, h, w); lPixels = RotatePixelsLeft(lPixels, h, w); } } // We need to flip the array if (lInfo.uvBottomLeft.y > lInfo.uvTopLeft.y) { lPixels = lFontTexture.GetPixels(x, y, w, h); lPixels = FlipPixelsVertically(lPixels, w, h); } // We need to mirror the array if (lInfo.uvTopLeft.x > lInfo.uvTopRight.x) { lPixels = lFontTexture.GetPixels(x, y, w, h); lPixels = FlipPixelsHorizontally(lPixels, w, h); } // Add the character pixels since they didn't exist in the beginning TextCharacter lTextCharacter = TextCharacter.Allocate(); lTextCharacter.Character = rCharacter; lTextCharacter.Pixels = lPixels; lTextCharacter.MinX = lInfo.minX; lTextCharacter.MinY = lInfo.minY; lTextCharacter.Width = w; lTextCharacter.Height = h; lTextCharacter.Advance = lInfo.advance; mFonts[rFont].Characters.Add(rCharacter, lTextCharacter); // Return the pixels return(lTextCharacter); }
/// <summary> /// Draws text on the screen /// </summary> /// <param name="sText"></param> /// <param name="rPosition"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="rFont"></param> /// <param name="fontSize"></param> public static void DrawText(string rText, Vector3 rPosition, Color rColor, Font rFont) { // Extract the font texture if we haven't already if (!mFonts.ContainsKey(rFont)) { if (!AddFont(rFont)) { return; } } TextFont lTextFont = mFonts[rFont]; // Gather information about the text int lWidth = Mathf.Abs(lTextFont.MinX); CharacterInfo lInfo; char[] lString = rText.ToCharArray(); for (int i = 0; i < lString.Length; i++) { rFont.GetCharacterInfo(lString[i], out lInfo); lWidth += Mathf.Max(lInfo.advance, lInfo.glyphWidth); } int lHeight = lTextFont.MaxY - lTextFont.MinY; // Create the destination texture and clear it Texture2D lTexture = new Texture2D(lWidth, lHeight, TextureFormat.ARGB32, false, true); Color32[] lColors = new Color32[lWidth * lHeight]; for (int i = 0; i < lColors.Length; i++) { lColors[i] = new Color32(0, 0, 0, 0); } lTexture.SetPixels32(lColors); // Process each character in the text int lStartX = Mathf.Abs(lTextFont.MinX); int lStartY = Mathf.Abs(lTextFont.MinY); for (int i = 0; i < lString.Length; i++) { TextCharacter lCharacter = GetCharacterPixels(rFont, lString[i]); // Change color and set pixels if we're not dealing with a white space if (lCharacter.Pixels != null) { for (int j = 0; j < lCharacter.Pixels.Length; j++) { rColor.a = lCharacter.Pixels[j].a; lCharacter.Pixels[j] = rColor; } lTexture.SetPixels(lStartX + lCharacter.MinX, lStartY + lCharacter.MinY, lCharacter.Width, lCharacter.Height, lCharacter.Pixels); } // Move our cursor forward lStartX += (int)lCharacter.Advance; } // Apply all the changes lTexture.Apply(); // The allocation is really just so we can destroy the texture at the end of the frame Text lText = Text.Allocate(); lText.Position = rPosition; lText.Texture = lTexture; mText.Add(lText); }