diff --git a/src/SlatedGameToolkit.Framework/Graphics/Text/BitmapFont.cs b/src/SlatedGameToolkit.Framework/Graphics/Text/BitmapFont.cs index ec63677..30e120d 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Text/BitmapFont.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Text/BitmapFont.cs @@ -37,6 +37,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Text } private Dictionary<(char, float), int> glyphTexLocations = new Dictionary<(char, float), int>(); private LRUCache metricsCache; + private int ascent, descent, lineGap; private int drawingTo; private bool disposed; @@ -58,6 +59,11 @@ namespace SlatedGameToolkit.Framework.Graphics.Text int spaceAdvance, leftSideBearing; StbTrueType.stbtt_GetCodepointHMetrics(info, ' ', &spaceAdvance, &leftSideBearing); this.spaceAdvance = spaceAdvance; + int ascent, descent, lineGap; + StbTrueType.stbtt_GetFontVMetrics(info, &ascent, &descent, &lineGap); + this.ascent = ascent; + this.descent = descent; + this.lineGap = lineGap; } public BitmapFont(string path, GLContext glContext = null, int cacheSize = 1024, int textures = 2, uint textureSizes = 512) : this(File.ReadAllBytes(path), glContext, cacheSize, textures, textureSizes) { @@ -89,12 +95,15 @@ namespace SlatedGameToolkit.Framework.Graphics.Text if (textureChanges > textures.Length) throw new FrameworkUsageException(string.Format("Character group \"{0}\" takes up too much texture space! Consider increasing decreasing font size, or increasing texture lengths, or number of backing textures.", new string(characters))); } glyphTexLocations.Add((c, scale), drawingTo); + int glyphIndex = glyphIndices.ComputeIfNonExistent(c, (p) => StbTrueType.stbtt_FindGlyphIndex(info, p)); + metricsCache.ComputeIfNonExistent(c, (p) => new CharacterMetrics(glyphIndex, info)); } } } - public unsafe void Draw(MeshBatch batch, float x, float baseLine, string text, Color color) { + public unsafe void WriteLine(MeshBatch batch, float x, float y, string text, Color color) { float currentPoint = x; + float baseLine = y; char[] chars = text.ToCharArray(); for (int i = 0; i < chars.Length; i++) { char c = chars[i]; @@ -103,7 +112,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Text int viewWidth, viewHeight, vX, vY; context.GetViewport(out vX, out vY, out viewWidth, out viewHeight); - if (c != ' ') { + if (c == ' ') { + currentPoint += (scale * spaceAdvance) / viewWidth; + } else if (c == '\n') { + currentPoint = x; + baseLine -= ((ascent - descent + lineGap) * scale) / viewHeight; + } else { //Check if glyph is loaded, if not, throw exception. if (!glyphTexLocations.ContainsKey((c, scale)) || !textures[glyphTexLocations[(c, scale)]].ContainsChar(c, scale)) { throw new FrameworkUsageException(string.Format("Character \'{0}\' was not prepared and is missing!", c)); @@ -124,8 +138,6 @@ namespace SlatedGameToolkit.Framework.Graphics.Text int nextGlyph = glyphIndices.ComputeIfNonExistent(chars[i + 1], (p) => StbTrueType.stbtt_FindGlyphIndex(info, p)); currentPoint += (StbTrueType.stbtt_GetGlyphKernAdvance(info, glyphIndex, nextGlyph) * scale) / viewWidth; } - } else { - currentPoint += (scale * spaceAdvance) / viewWidth; } } } diff --git a/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs b/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs index 63c0c28..e864a5a 100644 --- a/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs +++ b/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs @@ -89,7 +89,7 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground renderer.Draw(logo); renderer.Draw(textureTester); renderer.Draw(untextured); - font.Draw(renderer, 0.25f, -0.35f, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", Color.White); + font.WriteLine(renderer, 0.25f, -0.35f, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n1234567890", Color.White); renderer.End(); }