Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }