private float GetLineWidth(string text) { float result = 0f; float scale = 1f / font.LineHeight; for (int i = 0; i < text.Length; i++) { Character ch; if (!font.Characters.TryGetValue(text[i], out ch)) { continue; } result += ch.Advance * scale; //kerning if (i < text.Length - 1) { int first = text[i]; int second = text[i + 1]; CharsPair pair = new CharsPair((char)first, (char)second); if (font.Kernings.TryGetValue(pair, out int amount)) { result += amount * scale; } } } return(result); }
private TextVertex[] GenSingleLineMesh(string text, float xOffset, float yOffset) { //init int vertCount = text.Count(c => font.Characters.ContainsKey(c)) * 6; TextVertex[] vertices = new TextVertex[vertCount]; float scale = 1f / font.LineHeight; int spaceWidth = font.PaddingTop + font.PaddingBottom; int offset = 0; for (int i = 0; i < text.Length; i++) { if (text[i] == '\n' || text[i] == '\r') { throw new Exception("How did you even get here???"); } Character ch; if (!font.Characters.TryGetValue(text[i], out ch)) { continue; } float xpos = xOffset + ch.Offset.X * scale; float ypos = yOffset + ch.Offset.Y * scale; float xmax = xpos + ch.Size.X * scale; float ymax = ypos + ch.Size.Y * scale; float xproper = xpos; float yproper = -ypos + spaceWidth * scale + 0.5f; float xmaxproper = xmax; float ymaxproper = -ymax + spaceWidth * scale + 0.5f; //set vertices vertices[offset + 0] = new TextVertex(new Vector3(xmaxproper, ymaxproper, 0f), new Vector2(ch.End.X, ch.End.Y)); vertices[offset + 1] = new TextVertex(new Vector3(xmaxproper, yproper, 0f), new Vector2(ch.End.X, ch.Start.Y)); vertices[offset + 2] = new TextVertex(new Vector3(xproper, ymaxproper, 0f), new Vector2(ch.Start.X, ch.End.Y)); vertices[offset + 3] = new TextVertex(new Vector3(xmaxproper, yproper, 0f), new Vector2(ch.End.X, ch.Start.Y)); vertices[offset + 4] = new TextVertex(new Vector3(xproper, yproper, 0f), new Vector2(ch.Start.X, ch.Start.Y)); vertices[offset + 5] = new TextVertex(new Vector3(xproper, ymaxproper, 0f), new Vector2(ch.Start.X, ch.End.Y)); //update offset offset += 6; xOffset += ch.Advance * scale; //kerning if (i < text.Length - 1) { int first = text[i]; int second = text[i + 1]; CharsPair pair = new CharsPair((char)first, (char)second); if (font.Kernings.TryGetValue(pair, out int amount)) { xOffset += amount * scale; } } } return(vertices); }
public Font(string name, string path) : base(name) { FntParser parser = new FntParser(path); LineHeight = int.Parse(parser.RootNode["common"][0]["lineHeight"][0].Value); string[] paddings = parser.RootNode["info"][0]["padding"][0].Value.Split(','); PaddingTop = int.Parse(paddings[0]); PaddingLeft = int.Parse(paddings[1]); PaddingBottom = int.Parse(paddings[2]); PaddingRight = int.Parse(paddings[3]); TextureWidth = int.Parse(parser.RootNode["common"][0]["scaleW"][0].Value); TextureHeight = int.Parse(parser.RootNode["common"][0]["scaleH"][0].Value); int kerningsCount = int.Parse(parser.RootNode["kernings"][0]["count"][0].Value); for (int i = 0; i < kerningsCount; i++) { FntNode node = parser.RootNode["kerning"][i]; CharsPair pair = new CharsPair( (char)int.Parse(node["first"][0].Value), (char)int.Parse(node["second"][0].Value)); Kernings.Add(pair, int.Parse(node["amount"][0].Value)); } int charsCount = int.Parse(parser.RootNode["chars"][0]["count"][0].Value); for (int i = 0; i < charsCount; i++) { FntNode node = parser.RootNode["char"][i]; char c = (char)int.Parse(node["id"][0].Value); Vector2i size = new Vector2i( int.Parse(node["width"][0].Value), int.Parse(node["height"][0].Value)); Vector2i offset = new Vector2i( int.Parse(node["xoffset"][0].Value), int.Parse(node["yoffset"][0].Value)); Vector2i start = new Vector2i( int.Parse(node["x"][0].Value), int.Parse(node["y"][0].Value)); Vector2i end = start + size; Characters.Add(c, new Character { Start = new Vector2(start.X / (float)TextureWidth, start.Y / (float)TextureHeight), End = new Vector2(end.X / (float)TextureWidth, end.Y / (float)TextureHeight), Size = size, Offset = offset, Advance = int.Parse(node["xadvance"][0].Value) - PaddingLeft - PaddingRight }); } string texPath = Path.Combine(Path.GetDirectoryName(path), parser.RootNode["page"][0]["file"][0].Value); Rgba32[] pixels = Helper.LoadImageFromFile(texPath, out _, out _); FontTexture = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, FontTexture); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextureWidth, TextureHeight, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.BindTexture(TextureTarget.Texture2D, 0); }