Beispiel #1
0
        public TextGenerator(string path, string fontName, uint fontSize = 12)
        {
            if (_textPs == null)
            {
                LoadProgramShader();
            }

            FontName = fontName;
            FontSize = fontSize;

            SharpFont.Library fontLib  = new SharpFont.Library();
            SharpFont.Face    fontFace = new SharpFont.Face(fontLib, path);
            fontFace.SetPixelSizes(0, FontSize);

            GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);

            for (char c = (char)0x20; c <= (char)0x7E; c++)
            {
                fontFace.LoadChar(c, LoadFlags.Render, LoadTarget.Normal);

                Texture texture = Texture.CreateTexture(
                    fontFace.Glyph.Bitmap.Width,
                    fontFace.Glyph.Bitmap.Rows,
                    PixelInternalFormat.R8,
                    PixelFormat.Red,
                    fontFace.Glyph.Bitmap.Buffer);

                Character character = new Character(
                    texture.ID,
                    new Vector2(fontFace.Glyph.Bitmap.Width, fontFace.Glyph.Bitmap.Rows),
                    new Vector2(fontFace.Glyph.BitmapLeft, fontFace.Glyph.BitmapTop),
                    (int)fontFace.Glyph.Advance.X);

                _characters.Add(c, character);
            }

            fontFace.Dispose();
            fontLib.Dispose();

            vao = VAO.Create();
            vao.LinkPS(_textPs);

            vbo     = VBO.Create <float>(vertices.Length, 4, "vertex");
            indices = new IndicesCollection();
            indices.Add(4, vertices.Length);
            vao.AddVBuff(vbo);
            vao.AddIndicesCollection(indices);
        }
Beispiel #2
0
        /// <summary>
        /// Releases all resources used by the <see cref="Text"/>.
        /// </summary>
        public void Dispose()
        {
            if (_stroker != null && !_stroker.IsDisposed)
            {
                _stroker.Dispose();
            }

            if (_face != null && !_face.IsDisposed)
            {
                _face.Dispose();
            }

            if (_library != null && !_library.IsDisposed)
            {
                _library.Dispose();
            }

            _pages    = null;
            _fontData = null;
        }
Beispiel #3
0
        private void Clear()
        {
            try {
                if (Font != null)
                {
                    Font.Dispose();
                    Font = null;
                }

                GL.BindTexture(TextureTarget.Texture2D, 0);

                if (GlyphCount > 0)
                {
                    if (m_ListBase > 0)
                    {
                        GL.DeleteLists(m_ListBase, GlyphCount);
                    }
                    else if (!CharMap.IsNullOrEmpty())
                    {
                        CharMap.Values.Select(val => val.ListID).ForEach(lid => GL.DeleteLists(lid, 1));
                        CharMap.Clear();
                    }
                }
                if (!m_Textures.IsNullOrEmpty())
                {
                    GL.DeleteTextures(m_Textures.Length, m_Textures);
                }
            } catch (Exception ex) {
                ex.LogError();
            } finally {
                GlyphCount           = 0;
                m_ListBase           = 0;
                m_Textures           = null;
                Height               = 0;
                Count                = 0;
                m_EllipsisGlyphIndex = GlyphInfo.Empty;
            }
        }
Beispiel #4
0
        private void InitFont(float scaleFactor)
        {
            try {
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

                ScaleFactor   = scaleFactor;
                YOffsetScaled = YOffset * scaleFactor;

                // Reset everything
                Clear();

                Font = new Face(FontManager.Library, FilePath);

                // Go on

                float size = Size.Scale(ScaleFactor);

                Fixed26Dot6 sz = new Fixed26Dot6(size / 64);
                Font.SetCharSize(sz, sz, 72, 72);

                int pixelSize = (size * 1.3334).Ceil();
                Font.SetPixelSizes((uint)pixelSize, (uint)pixelSize);

                GlyphCount = Font.GlyphCount;
                int glyphCount = GlyphCount;
                Monospace = Font.FaceFlags.HasFlag(FaceFlags.FixedWidth);

                string tmpName = Font.GetPostscriptName();
                if (!String.IsNullOrEmpty(tmpName))
                {
                    Name = tmpName;
                }


                // We support 4 different glyph loading strategies:
                //
                // (1) All: all glyphs loaded at once on start
                // (2) Filtered: all filtered glyphs loaded at once on start
                // (3) OnDemand: no glyphs loaded at start, all glyphs on demand


                if (OnDemand)
                {
                    // Startegy (3)
                    GlyphCount = 0;
                }
                else if (Filter > GlyphFilterFlags.OnDemand)
                {
                    // Startegy (2)
                    // If we have a Filter set, let's count the number of valid glyphs
                    // to minimize graphics memory.
                    uint glyphindex;
                    uint cc    = Font.GetFirstChar(out glyphindex);
                    int  count = 0;
                    while (glyphindex > 0)
                    {
                        char c = (char)cc;
                        if (Filter.IsValid(c))
                        {
                            count++;
                        }
                        cc = Font.GetNextChar(cc, out glyphindex);
                    }
                    GlyphCount = count;
                }
                else
                {
                    // Strategy (1), loading the entire font
                }

                m_Textures = new int[Math.Max(32, GlyphCount)];
                CharMap    = new ThreadSafeDictionary <char, GlyphInfo>(Math.Max(31, GlyphCount));

                if (!OnDemand)
                {
                    // Strategy (1) + (2): Load all or filtered glyphs
                    m_ListBase = GL.GenLists(GlyphCount);
                    GL.GenTextures(GlyphCount, m_Textures);

                    uint glyphindex;
                    uint cc = Font.GetFirstChar(out glyphindex);
                    while (glyphindex > 0)
                    {
                        char c = (char)cc;
                        if (!CharMap.ContainsKey(c) && Filter.IsValid(c))
                        {
                            try {
                                CharMap.Add(c, CompileCharacter(Font, glyphindex, c));
                            } catch (Exception ex) {
                                ex.LogWarning();
                            }
                        }
                        cc = Font.GetNextChar(cc, out glyphindex);
                    }
                    CharMap.TryGetValue(SpecialCharacters.Ellipsis, out m_EllipsisGlyphIndex);
                }
                else
                {
                    try {
                        GetGlyphIndex(SpecialCharacters.Ellipsis, out m_EllipsisGlyphIndex);
                    } catch (Exception ex) {
                        ex.LogError();
                    }
                }

                //if (Height <= 1)
                //Height = pixelSize.NextPowerOf2();
                //Height = pixelSize * 1.33335f;

                Height = pixelSize;

                float fscale = Height / Font.Height * 1.33334f;
                //float fscale = Height / Font.Height * 0.776f;

                Ascender  = Font.Ascender * fscale;
                Descender = Font.Descender * fscale;
                //HalfHeight = Height / 2;

                Height     = (Ascender).Ceil();
                HalfHeight = (int)(Height / 2);

                //LineHeight = Height * 1.42f * LineSpacing;
                LineHeight = (int)((Height * 1.42f * LineSpacing) + 0.5f);

                //TextBoxHeight = ((Height * 2f) + (ScaleFactor * 2f)).Ceil();
                //TextBoxHeight = (int)(Height * 1.85f + 0.5f);
                TextBoxHeight = (int)(Height * 1.85f + 2);
                CaptionHeight = (int)(Height * 1.55 + 2);

                YOffsetScaled = (YOffset * ScaleFactor) - HalfHeight;

                if (OnDemand)
                {
                    Count.LogInformation("Font {0} ({1}), {2}/{3} glyphs pre-loaded in {4} ms, more glyphs are loaded on demand.", Name, Size, Count, glyphCount, sw.ElapsedMilliseconds);
                }
                else
                {
                    Count.LogInformation("Font {0} ({1}), {2}/{3} glyphs loaded in {4} ms.", Name, Size, Count, glyphCount, sw.ElapsedMilliseconds);
                }
            } catch (Exception ex) {
                ex.LogError();
            } finally {
                if (!OnDemand && Font != null)
                {
                    Font.Dispose();
                    Font = null;
                }
            }
        }