Пример #1
0
        private static float CalcPixelSize(TopologyFace face, int height)
        {
            // See http://www.freetype.org/freetype2/docs/tutorial/step2.html
            // Chapter: Scaling Distances to Device Space
            // BBox suits better than Height (baseline-to-baseline distance), because it can enclose all the glyphs in the font face.
            var designHeight = (float)face.BBox.Top - (float)face.BBox.Bottom;
            var scale        = height / designHeight;
            var pixelSize    = scale * face.UnitsPerEM;

            return(pixelSize);
        }
Пример #2
0
        private void RenderFont(Font font, TopologyFace face)
        {
            var pixels = new Color4[TextureSize * TextureSize];
            int x      = 0;
            int y      = 0;

            foreach (var @char in Characters)
            {
                uint glyphIndex = face.GetCharIndex(@char);
                face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                if (face.Glyph.Metrics.Width == 0)
                {
                    continue;
                }
                face.Glyph.RenderGlyph(RenderMode.Normal);
                var bitmap = face.Glyph.Bitmap;
                if (x + bitmap.Width + 1 >= TextureSize)
                {
                    x  = 0;
                    y += Height + 1;
                }
                if (y + Height + 1 >= TextureSize)
                {
                    AddFontTexture(font, pixels);
                    pixels = new Color4[TextureSize * TextureSize];
                    x      = y = 0;
                }
                var verticalOffset = Height - face.Glyph.BitmapTop + face.Size.Metrics.Descender.Round();
                CopyBitmap(bitmap, pixels, x, y + verticalOffset);
                var uv0      = new Vector2(x, y) / TextureSize;
                var uv1      = new Vector2(x + bitmap.Width, y + Height) / TextureSize;
                var bearingX = (float)face.Glyph.Metrics.HorizontalBearingX;
                var fontChar = new FontChar()
                {
                    Char         = @char,
                    Width        = bitmap.Width,
                    Height       = Height,
                    TextureIndex = font.Textures.Count,
                    ACWidths     = new Vector2(
                        bearingX.Round(),
                        ((float)face.Glyph.Metrics.HorizontalAdvance - (float)face.Glyph.Metrics.Width - bearingX).Round()
                        ),
                    UV0 = uv0,
                    UV1 = uv1,
                };
                x += bitmap.Width + 1;
                // Iterate through kerning pairs
                foreach (var prevChar in Characters)
                {
                    uint prevGlyphIndex = face.GetCharIndex(prevChar);
                    var  kerning        = (float)face.GetKerning(prevGlyphIndex, glyphIndex, KerningMode.Default).X;
                    // Round kerning to prevent blurring
                    kerning = kerning.Round();
                    if (kerning != 0)
                    {
                        if (fontChar.KerningPairs == null)
                        {
                            fontChar.KerningPairs = new List <KerningPair>();
                        }
                        fontChar.KerningPairs.Add(new KerningPair()
                        {
                            Char = prevChar, Kerning = kerning
                        });
                    }
                }
                font.CharSource.Add(fontChar);
            }
            AddFontTexture(font, pixels);
            // Add the whitespace character
            font.CharSource.Add(new FontChar()
            {
                Char   = ' ',
                Width  = ((float)Height / 5).Round(),
                Height = Height,
            });
        }