Beispiel #1
0
        public static FontTexture CreateFont(Library ftLibrary, string filename, ushort fontSize)
        {
            if(ftLibrary != null)
            {
                var glf = new FontTexture();

                Face face = null;
                try
                {
                    face = new Face(ftLibrary, filename, 0);
                }
                catch
                {
                    return null;
                }
                glf.FTFace = face;

                Array.Resize(ref glf.Glyphs, glf.FTFace.GlyphCount);

                glf.GLMaxTexWidth = GL.GetInteger(GetPName.MaxTextureSize);
                glf.GLTexWidth = glf.GLMaxTexWidth;
                glf.GLTexIndexes = new uint[0];
                glf.GLRealTexIndexesCount = 0;
                glf.GLFontColor = new [] {0.0f, 0.0f, 0.0f, 1.0f};

                Resize(glf, fontSize);
                glf.FTFace.SelectCharmap(Encoding.Unicode);

                return glf;
            }

            return null;
        }
Beispiel #2
0
 public void InitFonts()
 {
     font = Global.FontManager.GetFont(FontType.Console);
     SetLineInterval(spacing);
 }
Beispiel #3
0
        public static FontTexture CreateFontMem(Library ftLibrary, byte[] faceData, ushort fontSize)
        {
            if (ftLibrary != null)
            {
                var glf = new FontTexture();

                Face face = null;
                try
                {
                    face = new Face(ftLibrary, faceData, 0);
                }
                catch
                {
                    glf.Dispose();
                    return null;
                }
                glf.FTFace = face;

                Array.Resize(ref glf.Glyphs, glf.FTFace.GlyphCount);

                glf.GLMaxTexWidth = GL.GetInteger(GetPName.MaxTextureSize);
                glf.GLTexWidth = glf.GLMaxTexWidth;
                glf.GLTexIndexes = new uint[0];
                glf.GLRealTexIndexesCount = 0;
                Resize(glf, fontSize);
                glf.FTFace.SelectCharmap(Encoding.Unicode);

                return glf;
            }

            return null;
        }
Beispiel #4
0
        public static unsafe void RenderStr(FontTexture glf, float x, float y, string text)
        {
            text = text.NullCheck();

            byte* nch;
            var charr = Helper.GetStringBPUTF8(text);
            FTVector26Dot6 kern;

            if(glf?.FTFace == null || text == null || text[0] == '\0')
            {
                return;
            }

            FontBuffer.Bind();

            fixed (byte* ptr = charr)
            {
                var ch = ptr;
                if (glf.GLRealTexIndexesCount == 1)
                {
                    var p = FontBuffer.ResizeAndMap(48 * (int) Helper.UTF8StrLen(text) * sizeof (float));
                    uint elementsCount = 0;
                    uint curr_utf32, next_utf32;
                    nch = Helper.UTF8ToUTF32(ch, &curr_utf32);
                    curr_utf32 = glf.FTFace.GetCharIndex(curr_utf32);

                    while (*ch != 0)
                    {
                        var nch2 = Helper.UTF8ToUTF32(nch, &next_utf32);

                        next_utf32 = glf.FTFace.GetCharIndex(next_utf32);
                        ch = nch;
                        nch = nch2;

                        fixed (CharInfo* g = &glf.Glyphs[(int) curr_utf32])
                        {
                            kern = glf.FTFace.GetKerning(curr_utf32, next_utf32, KerningMode.Unscaled);
                            curr_utf32 = next_utf32;

                            if (g->TexIndex != 0)
                            {
                                var x0 = x + g->Left;
                                var x1 = x0 + g->Width;
                                var y0 = y + g->Top;
                                var y1 = y0 - g->Height;

                                *p = x0;
                                p++;
                                *p = y0;
                                p++;
                                *p = g->TexX0;
                                p++;
                                *p = g->TexY0;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x1;
                                p++;
                                *p = y0;
                                p++;
                                *p = g->TexX1;
                                p++;
                                *p = g->TexY0;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x1;
                                p++;
                                *p = y1;
                                p++;
                                *p = g->TexX1;
                                p++;
                                *p = g->TexY1;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;
                                elementsCount++;

                                *p = x0;
                                p++;
                                *p = y0;
                                p++;
                                *p = g->TexX0;
                                p++;
                                *p = g->TexY0;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x1;
                                p++;
                                *p = y1;
                                p++;
                                *p = g->TexX1;
                                p++;
                                *p = g->TexY1;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x0;
                                p++;
                                *p = y1;
                                p++;
                                *p = g->TexX0;
                                p++;
                                *p = g->TexY1;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;
                                elementsCount++;
                            }
                            x += (kern.X.ToSingle() + g->AdvanceX) / 64.0f;
                            y += (kern.Y.ToSingle() + g->AdvanceY) / 64.0f;
                        }
                    }
                    FontBuffer.Unmap();
                    // RENDER
                    if (elementsCount != 0)
                    {
                        GL.BindTexture(TextureTarget.Texture2D, glf.GLTexIndexes[0]);
                        GL.DrawArrays(PrimitiveType.Triangles, 0, (int) elementsCount * 3);
                    }
                }
                else
                {
                    uint activeTexture = 0;
                    uint curr_utf32, next_utf32;
                    nch = Helper.UTF8ToUTF32(ch, &curr_utf32);
                    curr_utf32 = glf.FTFace.GetCharIndex(curr_utf32);

                    for (; *ch != 0;)
                    {
                        var p = FontBuffer.ResizeAndMap(32 * sizeof (float));

                        var nch2 = Helper.UTF8ToUTF32(nch, &next_utf32);

                        next_utf32 = glf.FTFace.GetCharIndex(next_utf32);
                        ch = nch;
                        nch = nch2;

                        fixed (CharInfo* g = &glf.Glyphs[(int) curr_utf32])
                        {
                            kern = glf.FTFace.GetKerning(curr_utf32, next_utf32, KerningMode.Unscaled);
                            curr_utf32 = next_utf32;

                            if (g->TexIndex != 0)
                            {
                                if (activeTexture != g->TexIndex)
                                {
                                    GL.BindTexture(TextureTarget.Texture2D, g->TexIndex);
                                }
                                // RENDER
                                var x0 = x + g->Left;
                                var x1 = x0 + g->Width;
                                var y0 = y + g->Top;
                                var y1 = y0 - g->Height;

                                *p = x0;
                                p++;
                                *p = y0;
                                p++;
                                *p = g->TexX0;
                                p++;
                                *p = g->TexY0;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x1;
                                p++;
                                *p = y0;
                                p++;
                                *p = g->TexX1;
                                p++;
                                *p = g->TexY0;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x1;
                                p++;
                                *p = y1;
                                p++;
                                *p = g->TexX1;
                                p++;
                                *p = g->TexY1;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);
                                p += 4;

                                *p = x0;
                                p++;
                                *p = y1;
                                p++;
                                *p = g->TexX0;
                                p++;
                                *p = g->TexY1;
                                p++;
                                fixed (float* glfc = glf.GLFontColor) Helper.Vec4CopyPointer(p, glfc);

                                FontBuffer.Unmap();

                                GL.DrawArrays(PrimitiveType.TriangleFan, 0, 4);
                            }
                            x += (kern.X.ToSingle() + g->AdvanceX) / 64.0f;
                            y += (kern.Y.ToSingle() + g->AdvanceY) / 64.0f;
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public static ushort GetFontSize(FontTexture glf)
        {
            if(glf?.FTFace == null)
            {
                return 0;
            }

            return glf.FontSize;
        }
Beispiel #6
0
        public static unsafe void GetStringBB(FontTexture glf, string text, int n, ref float x0, ref float y0, ref float x1, ref float y1)
        {
            text = text.NullCheck();

            x0 = 0;
            x1 = 0;
            y0 = 0;
            y1 = 0;

            if(glf?.FTFace != null)
            {
                byte* nch2;
                var charr = Helper.GetStringBPUTF8(text);
                fixed (byte* tmp = charr)
                {
                    var ch = tmp;
                    var x = 0.0f;
                    var y = 0.0f;
                    float xx0, xx1, yy0, yy1;
                    uint curr_utf32, next_utf32;

                    var nch = Helper.UTF8ToUTF32(ch, &curr_utf32);
                    curr_utf32 = glf.FTFace.GetCharIndex(curr_utf32);

                    for (var i = 0; (*ch != 0) && !(n >= 0 && i >= n); i++)
                    {
                        fixed (CharInfo* g = &glf.Glyphs[(int) curr_utf32])
                        {
                            nch2 = Helper.UTF8ToUTF32(nch, &next_utf32);

                            next_utf32 = glf.FTFace.GetCharIndex(next_utf32);
                            ch = nch;
                            nch = nch2;

                            var kern = glf.FTFace.GetKerning(curr_utf32, next_utf32, KerningMode.Unscaled);
                            curr_utf32 = next_utf32;

                            xx0 = x + g->Left;
                            xx1 = xx0 + g->Width;
                            yy0 = y + g->Top;
                            yy1 = yy0 - g->Height;
                            Helper.BBoxAdd(xx0, xx1, yy0, yy1, ref x0, ref x1, ref y0, ref y1);

                            x += (kern.X.ToSingle() + g->AdvanceX) / 64.0f;
                            y += (kern.Y.ToSingle() + g->AdvanceY) / 64.0f;
                        }
                    }
                }
            }
        }
Beispiel #7
0
        public static float GetAscender(FontTexture glf)
        {
            if(glf.FontSize == 0 || glf.FTFace == null)
            {
                return 0.0f;
            }

            return glf.FTFace.Ascender / 64.0f;
        }
Beispiel #8
0
        public static unsafe float GetStringLen2(FontTexture glf, string text, int n)
        {
            text = text.NullCheck();

            var x = 0.0f;

            if (glf?.FTFace != null)
            {
                var charr = Helper.GetStringBPUTF8(text);
                /*fixed (byte* ptr = charr)
                {
                    var ch = ptr;
                    uint curr_utf32, next_utf32;
                    var nch = Helper.UTF8ToUTF32(ch, &curr_utf32);
                    curr_utf32 = glf.FTFace.GetCharIndex(curr_utf32);

                    for (var i = 0; (*ch != 0) && !(n >= 0 && i >= n); i++)
                    {
                        var nch2 = Helper.UTF8ToUTF32(nch, &next_utf32);
                        next_utf32 = glf.FTFace.GetCharIndex(next_utf32);
                        ch = nch;
                        nch = nch2;

                        var kern = glf.FTFace.GetKerning(curr_utf32, next_utf32, KerningMode.Unscaled);
                        curr_utf32 = next_utf32;
                        x += (kern.X.ToSingle() + glf.Glyphs[(int)curr_utf32].AdvanceX) / 64.0f;
                    }
                }*/

                var utf32b = System.Text.Encoding.Convert(System.Text.Encoding.UTF8, System.Text.Encoding.UTF32, charr);
                var utf32 = new uint[utf32b.Length / 4];
                Buffer.BlockCopy(utf32b, 0, utf32, 0, utf32b.Length);

                if (utf32.Length == 0) return 0;

                uint ci = 0;
                uint cilast = 0;
                for (var i = 0; i < n && i < utf32.Length; i++)
                {
                    var cur = utf32[i];
                    if (cur == 0) break;
                    if(i > 0)
                        cilast = ci;
                    ci = glf.FTFace.GetCharIndex(cur);
                    x += glf.Glyphs[(int) ci].AdvanceX / 64.0f;
                    if (i > 0)
                    {
                        var kern = glf.FTFace.GetKerning(cilast, ci, KerningMode.Unscaled);
                        x += kern.X.ToSingle() / 64.0f;
                    }
                }
            }

            return x;
        }
Beispiel #9
0
        public static unsafe float GetStringLen(FontTexture glf, string text, int n)
        {
            text = text.NullCheck();

            var x = 0.0f;

            if (glf?.FTFace != null)
            {
                var charr = Helper.GetStringBPUTF8(text);
                fixed (byte* ptr = charr)
                {
                    var ch = ptr;
                    uint curr_utf32, next_utf32;
                    var nch = Helper.UTF8ToUTF32(ch, &curr_utf32);
                    curr_utf32 = glf.FTFace.GetCharIndex(curr_utf32);

                    for (var i = 0; (*ch != 0) && !(n >= 0 && i >= n); i++)
                    {
                        var nch2 = Helper.UTF8ToUTF32(nch, &next_utf32);
                        next_utf32 = glf.FTFace.GetCharIndex(next_utf32);
                        ch = nch;
                        nch = nch2;

                        var kern = glf.FTFace.GetKerning(curr_utf32, next_utf32, KerningMode.Unscaled);
                        curr_utf32 = next_utf32;
                        x += (kern.X.ToSingle() + glf.Glyphs[(int) curr_utf32].AdvanceX) / 64.0f;
                    }
                }
            }

            return x;
        }
Beispiel #10
0
 public static void Reface(FontTexture glf, string filename, ushort fontSize)
 {
     Face face;
     try
     {
         face = new Face(glf.FTLibrary, filename, 0);
     }
     catch
     {
         return;
     }
     glf.FTFace = face;
     Resize(glf, fontSize);
 }
Beispiel #11
0
        public static void Resize(FontTexture glf, ushort fontSize)
        {
            if (glf?.FTFace != null)
            {
                var padding = 2;
                int x, y;
                int i, ii, i0 = 0;

                // clear old atlas, if exists
                if (glf.GLTexIndexes.Length > 0)
                {
                    GL.DeleteTextures(glf.GLTexIndexes.Length, glf.GLTexIndexes);
                }
                glf.GLTexIndexes = new uint[0];
                glf.GLRealTexIndexesCount = 0;

                // resize base font
                glf.FontSize = fontSize;
                glf.FTFace.SetCharSize(fontSize, fontSize, 0, 0);

                // calculate texture atlas size
                var charsInRow = 1 + (int) Math.Sqrt(glf.Glyphs.Length);
                glf.GLTexWidth = Math.Min(Helper.NextPowerOf2((fontSize + padding) * charsInRow), glf.GLMaxTexWidth);

                // create new atlas
                charsInRow = glf.GLTexWidth / (fontSize + padding);
                var charsInColumn = glf.Glyphs.Length / charsInRow + 1;
                Array.Resize(ref glf.GLTexIndexes, charsInColumn * (fontSize + padding) / glf.GLTexWidth + 1);
                GL.GenTextures(glf.GLTexIndexes.Length, glf.GLTexIndexes);

                var bufferSize = glf.GLTexWidth * glf.GLTexWidth * sizeof (byte);
                var buffer = new byte[bufferSize];

                for (i = 0, x = 0, y = 0; i < glf.Glyphs.Length; i++)
                {
                    GlyphSlot g;
                    glf.Glyphs[i].TexIndex = 0;

                    // load glyph image into the slot (erase previous one)
                    try
                    {
                        glf.FTFace.LoadGlyph((uint) i, LoadFlags.Render, LoadTarget.Normal);
                    }
                    catch
                    {
                        continue;
                    }

                    // convert to an anti-aliased bitmap
                    try
                    {
                        glf.FTFace.Glyph.RenderGlyph(RenderMode.Normal);
                    }
                    catch
                    {
                        continue;
                    }

                    g = glf.FTFace.Glyph;
                    glf.Glyphs[i].Width = g.Bitmap.Width;
                    glf.Glyphs[i].Height = g.Bitmap.Rows;
                    glf.Glyphs[i].AdvanceX = g.Advance.X.ToSingle() * 64;
                    glf.Glyphs[i].AdvanceY = g.Advance.Y.ToSingle() * 64;
                    glf.Glyphs[i].Left = g.BitmapLeft;
                    glf.Glyphs[i].Top = g.BitmapTop;

                    if (g.Bitmap.Width == 0 || g.Bitmap.Rows == 0)
                    {
                        continue;
                    }

                    if (g.Bitmap.Width + x > glf.GLTexWidth)
                    {
                        x = 0;
                        y += glf.FontSize + padding;
                        if (glf.FontSize + y > glf.GLTexWidth)
                        {
                            GL.BindTexture(TextureTarget.Texture2D, glf.GLTexIndexes[glf.GLRealTexIndexesCount]);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                                (int) TextureMagFilter.Linear);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                                (int) TextureMinFilter.Linear);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                                (int) TextureWrapMode.ClampToEdge);
                            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                                (int) TextureWrapMode.ClampToEdge);
                            GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat) PixelFormat.Red,
                                glf.GLTexWidth, glf.GLTexWidth, 0, (PixelFormat) PixelInternalFormat.R8,
                                PixelType.UnsignedByte, buffer);
                            for (var ii2 = i0; ii2 < i; ii2++)
                            {
                                glf.Glyphs[ii2].TexX0 /= glf.GLTexWidth;
                                glf.Glyphs[ii2].TexX1 /= glf.GLTexWidth;
                                glf.Glyphs[ii2].TexY0 /= glf.GLTexWidth;
                                glf.Glyphs[ii2].TexY1 /= glf.GLTexWidth;
                            }
                            buffer = new byte[bufferSize];
                            y = 0;
                            i0 = i;
                            glf.GLRealTexIndexesCount++;
                        }
                    }

                    glf.Glyphs[i].TexX0 = x;
                    glf.Glyphs[i].TexY0 = y;
                    glf.Glyphs[i].TexX1 = x + g.Bitmap.Width;
                    glf.Glyphs[i].TexY1 = y + g.Bitmap.Rows;

                    glf.Glyphs[i].TexIndex = glf.GLTexIndexes[glf.GLRealTexIndexesCount];

                    for (var xx = 0; xx < g.Bitmap.Width; xx++)
                    {
                        for (var yy = 0; yy < g.Bitmap.Rows; yy++)
                        {
                            buffer[(y + yy) * glf.GLTexWidth + x + xx] = g.Bitmap.BufferData[yy * g.Bitmap.Width + xx];
                        }
                    }

                    x += g.Bitmap.Width + padding;
                }

                GL.BindTexture(TextureTarget.Texture2D, glf.GLTexIndexes[glf.GLRealTexIndexesCount]);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                    (int)TextureMagFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                    (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
                    (int)TextureWrapMode.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
                    (int)TextureWrapMode.ClampToEdge);
                charsInColumn = Helper.NextPowerOf2(y + fontSize + padding);
                GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat)PixelFormat.Red,
                    glf.GLTexWidth, charsInColumn, 0, PixelFormat.Red, 
                    PixelType.UnsignedByte, buffer);

                for (ii = i0; ii < glf.Glyphs.Length; ii++)
                {
                    glf.Glyphs[ii].TexX0 /= glf.GLTexWidth;
                    glf.Glyphs[ii].TexX1 /= glf.GLTexWidth;
                    glf.Glyphs[ii].TexY0 /= charsInColumn;
                    glf.Glyphs[ii].TexY1 /= charsInColumn;
                }
                buffer = new byte[0];
                glf.GLRealTexIndexesCount++;
            }
        }