Пример #1
0
        /// <summary>
        /// Add a character.
        /// </summary>
        /// <param name="codePoint">Codepoint.</param>
        unsafe void AddCharacter(uint codePoint)
        {
            // Handle Tab
            if (codePoint == (uint)'\t')
            {
                var spaceGlyph = GetGlyph((uint)' ');
                glyphs.Add(codePoint, new GlyphInfo(spaceGlyph.AdvanceX * 5, spaceGlyph.AdvanceY, spaceGlyph.CharIndex));
                return;
            }

            // Check if Glyph exists
            uint index = FT.FT_Get_Char_Index(facePtr, codePoint);

            if (index == 0)
            {
                if (codePoint == (uint)'?')
                {
                    throw new Exception("Font does not contain required character '?'");
                }
                glyphs.Add(codePoint, GetGlyph((uint)'?'));
                return;
            }

            // Render the glyph
            FT.FT_Load_Glyph(facePtr, index, FT.FT_LOAD_DEFAULT | FT.FT_LOAD_TARGET_NORMAL);
            var faceRec = (FT.FaceRec)Marshal.PtrToStructure(facePtr, typeof(FT.FaceRec));

            FT.FT_Render_Glyph(faceRec.glyph, FT.FT_RENDER_MODE_NORMAL);
            var glyphRec = (FT.GlyphSlotRec)Marshal.PtrToStructure(faceRec.glyph, typeof(FT.GlyphSlotRec));

            //Check for glyph that is only spacing
            if (glyphRec.bitmap.width == 0 || glyphRec.bitmap.rows == 0)
            {
                glyphs.Add(codePoint, new GlyphInfo(
                               (int)Math.Ceiling(FTMath.From26Dot6(glyphRec.advance.x)),
                               (int)Math.Ceiling(FTMath.From26Dot6(glyphRec.advance.y)),
                               index
                               ));
                return;
            }

            var pixels = new RGBA[glyphRec.bitmap.width * glyphRec.bitmap.rows];

            if (glyphRec.bitmap.pixel_mode == 2)
            {
                byte *data = (byte *)glyphRec.bitmap.buffer;
                for (int i = 0; i < glyphRec.bitmap.width * glyphRec.bitmap.rows; i++)
                {
                    // TODO: 4 bytes used for 1 byte of alpha data? investigate compression with GL_RED and shader.
                    pixels [i] = new RGBA(255, 255, 255, data [i]);
                }
            }
            else
            {
                throw new NotImplementedException();
            }

            if (currentX + glyphRec.bitmap.width > TEXTURE_SIZE)
            {
                currentX  = 0;
                currentY += lineMax;
                lineMax   = 0;
            }

            if (currentY + glyphRec.bitmap.rows > TEXTURE_SIZE)
            {
                currentX = 0;
                currentY = 0;
                lineMax  = 0;
                pages.Add(GetNewTexture());
            }

            lineMax = Math.Max(lineMax, glyphRec.bitmap.rows);
            var rect = new Rectangle(currentX, currentY, glyphRec.bitmap.width, glyphRec.bitmap.rows);
            var tex  = pages [pages.Count - 1];

            tex.SetData(pixels, rect);
            currentX += glyphRec.bitmap.width;

            var glyphInfo = new GlyphInfo(
                t: tex,
                r: rect,
                advX: (int)Math.Ceiling(FTMath.From26Dot6(glyphRec.advance.x)),
                advY: (int)Math.Ceiling(FTMath.From26Dot6(glyphRec.advance.y)),
                horzAdv: (int)Math.Ceiling(FTMath.From26Dot6(glyphRec.metrics.horiAdvance)),
                xOff: glyphRec.bitmap_left,
                yOff: glyphRec.bitmap_top,
                idx: index
                );

            glyphs.Add(codePoint, glyphInfo);
        }
Пример #2
0
        /// <summary>
        /// Add a character.
        /// </summary>
        /// <param name="codePoint">Codepoint.</param>
        unsafe void AddCharacter(uint codePoint)
        {
            // Handle Tab
            if (codePoint == (uint) '\t') {
                var spaceGlyph = GetGlyph ((uint) ' ');
                glyphs.Add (codePoint, new GlyphInfo (spaceGlyph.AdvanceX * 5, spaceGlyph.AdvanceY, spaceGlyph.CharIndex));
                return;
            }

            // Check if Glyph exists
            uint index = FT.FT_Get_Char_Index (facePtr, codePoint);
            if (index == 0) {
                if (codePoint == (uint) '?')
                    throw new Exception ("Font does not contain required character '?'");
                glyphs.Add (codePoint, GetGlyph ((uint) '?'));
                return;
            }

            // Render the glyph
            FT.FT_Load_Glyph (facePtr, index, FT.FT_LOAD_DEFAULT | FT.FT_LOAD_TARGET_NORMAL);
            var faceRec = (FT.FaceRec) Marshal.PtrToStructure (facePtr, typeof(FT.FaceRec));
            FT.FT_Render_Glyph (faceRec.glyph, FT.FT_RENDER_MODE_NORMAL);
            var glyphRec = (FT.GlyphSlotRec) Marshal.PtrToStructure (faceRec.glyph, typeof(FT.GlyphSlotRec));

            //Check for glyph that is only spacing
            if (glyphRec.bitmap.width == 0 || glyphRec.bitmap.rows == 0) {
                glyphs.Add (codePoint, new GlyphInfo (
                    (int) Math.Ceiling (FTMath.From26Dot6 (glyphRec.advance.x)),
                    (int) Math.Ceiling (FTMath.From26Dot6 (glyphRec.advance.y)),
                    index
                ));
                return;
            }

            var pixels = new RGBA[glyphRec.bitmap.width * glyphRec.bitmap.rows];
            if (glyphRec.bitmap.pixel_mode == 2) {
                byte* data = (byte*) glyphRec.bitmap.buffer;
                for (int i = 0; i < glyphRec.bitmap.width * glyphRec.bitmap.rows; i++) {
                    // TODO: 4 bytes used for 1 byte of alpha data? investigate compression with GL_RED and shader.
                    pixels [i] = new RGBA (255, 255, 255, data [i]);
                }
            } else {
                throw new NotImplementedException ();
            }

            if (currentX + glyphRec.bitmap.width > TEXTURE_SIZE) {
                currentX = 0;
                currentY += lineMax;
                lineMax = 0;
            }

            if (currentY + glyphRec.bitmap.rows > TEXTURE_SIZE) {
                currentX = 0;
                currentY = 0;
                lineMax = 0;
                pages.Add (GetNewTexture ());
            }

            lineMax = Math.Max (lineMax, glyphRec.bitmap.rows);
            var rect = new Rectangle (currentX, currentY, glyphRec.bitmap.width, glyphRec.bitmap.rows);
            var tex = pages [pages.Count - 1];
            tex.SetData (pixels, rect);
            currentX += glyphRec.bitmap.width;

            var glyphInfo = new GlyphInfo (
                                t: tex,
                                r: rect,
                                advX: (int) Math.Ceiling (FTMath.From26Dot6 (glyphRec.advance.x)),
                                advY: (int) Math.Ceiling (FTMath.From26Dot6 (glyphRec.advance.y)),
                                horzAdv: (int) Math.Ceiling (FTMath.From26Dot6 (glyphRec.metrics.horiAdvance)),
                                xOff: glyphRec.bitmap_left,
                                yOff: glyphRec.bitmap_top,
                                idx: index
                            );
            glyphs.Add (codePoint, glyphInfo);
        }