예제 #1
0
        public static int FT_Open_Face(IntPtr library, FreeTypeStreamWrapper streamWrapper, long face_index, out FT_Face aface)
        {
            var args   = streamWrapper.FT_Open_ArgsWin32;
            var result = _FT_Open_Face_Win32(library, ref args, (Win32Long)face_index, out var afacePointer);

            aface = new FT_Face(afacePointer);
            return(result);
        }
예제 #2
0
        public static Font RenderFromStream(GraphicsContext graphics, Stream stream, uint fontSize, IEnumerable <char> characters, byte alpha = 0)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            int fontWidth         = 0;
            int fontHeight        = 0;
            int fontLineHeight    = 0;
            var characterSurfaces = new Dictionary <char, Surface>();
            var characterData     = new Dictionary <char, Font.Character>();

            FT_Init_FreeType(out IntPtr library);

            using (var streamWrapper = new FreeTypeStreamWrapper(stream))
            {
                if (FT_Open_Face(library, streamWrapper, 0, out var face) != 0)
                {
                    throw new PixelCannonException("Could not open font.");
                }

                FT_Set_Pixel_Sizes(face, 0, fontSize);

                if (FT_Load_Char(face, 'M', FT_LOAD_RENDER) != 0)
                {
                    throw new PixelCannonException($"Could not load character 'M'.");
                }

                var glyph   = face.Glyph();
                var metrics = glyph.Metrics();
                var bitmap  = glyph.Bitmap();
                fontWidth      = (int)bitmap.width;
                fontHeight     = (int)bitmap.rows;
                fontLineHeight = (int)(metrics.height / 64);

                foreach (var ch in characters)
                {
                    if (FT_Load_Char(face, ch, FT_LOAD_RENDER) != 0)
                    {
                        throw new PixelCannonException($"Could not load character '{ch}'.");
                    }

                    glyph   = face.Glyph();
                    metrics = glyph.Metrics();
                    bitmap  = glyph.Bitmap();
                    var width   = (int)(metrics.width / 64);
                    var height  = (int)(metrics.height / 64);
                    var offsetX = (int)(metrics.horiBearingX / 64);
                    var offsetY = fontLineHeight - (int)(metrics.horiBearingY / 64);
                    var advance = glyph.Advance();

                    characterSurfaces[ch] = RenderGlyph(bitmap, alpha);

                    var data = new Character()
                    {
                        Width    = width,
                        Height   = height,
                        OffsetX  = offsetX,
                        OffsetY  = offsetY,
                        AdvanceX = (int)(advance.x / 64),
                        AdvanceY = (int)(advance.y / 64),
                    };

                    characterData[ch] = data;
                }

                FT_Done_FreeType(library);
            }

            var surface = RenderSheet(characterSurfaces, characterData, fontWidth, fontHeight, alpha);

            return(new Font(surface.ToTexture(graphics), characterData, fontLineHeight));
        }