Esempio n. 1
0
        public static CharacterInfo Parse(XElement xElement)
        {
            CharacterInfo cInfo = new CharacterInfo();
            cInfo.xoffset = int.Parse(xElement.Attribute(strXOffset).Value);
            cInfo.yoffset = int.Parse(xElement.Attribute(strYOffset).Value);
            cInfo.width = int.Parse(xElement.Attribute(strWidth).Value);
            cInfo.height = int.Parse(xElement.Attribute(strHeight).Value);

            return cInfo;
        }
Esempio n. 2
0
        /// <summary>
        /// 根据<paramref name="firstChar"/>等信息获取要制作的贴图的宽高和各个字形的位置信息。
        /// </summary>
        /// <param name="face"></param>
        /// <param name="fontHeight"></param>
        /// <param name="firstChar"></param>
        /// <param name="lastChar"></param>
        /// <param name="maxTextureWidth"></param>
        /// <param name="charInfoDict"></param>
        /// <param name="textureWidth"></param>
        /// <param name="textureHeight"></param>
        private static void GetTextureBlueprint(FreeTypeFace face, int fontHeight, int maxTextureWidth,
            char firstChar, char lastChar,
            out Dictionary<char, CharacterInfo> charInfoDict, out int textureWidth, out int textureHeight)
        {
            charInfoDict = new Dictionary<char, CharacterInfo>();
            textureWidth = 0;
            textureHeight = fontHeight;

            int glyphXOffset = 0;
            int glyphYOffset = 0;

            for (char c = firstChar; c <= lastChar; c++)
            {
                FreeTypeBitmapGlyph glyph = new FreeTypeBitmapGlyph(face, c, fontHeight);

                bool zeroSize = (glyph.obj.bitmap.rows == 0 && glyph.obj.bitmap.width == 0);

                {
                    bool zeroBuffer = glyph.obj.bitmap.buffer == IntPtr.Zero;
                    if (zeroSize && (!zeroBuffer)) { throw new Exception(); }
                    if ((!zeroSize) && zeroBuffer) { throw new Exception(); }
                }

                int glyphWidth = glyph.obj.bitmap.width;
                int glyphHeight = glyph.obj.bitmap.rows;

                if (c == ' ' && zeroSize)// 空格需要特殊处理
                {
                    zeroSize = false;
                    FreeTypeBitmapGlyph tabGlyph = new FreeTypeBitmapGlyph(face, '\t', fontHeight);
                    glyphWidth = tabGlyph.obj.bitmap.width / 8;
                    if (glyphWidth < 1) { glyphWidth = fontHeight / 2; }
                    glyphHeight = tabGlyph.obj.bitmap.rows;
                    //if (glyphHeight < 1) { glyphHeight = 1; }
                }
                else if (c == '\t' && zeroSize)// tab可能需要特殊处理
                {
                    zeroSize = false;
                    glyphWidth = glyph.obj.bitmap.width;
                    if (glyphWidth < 1) { glyphWidth = fontHeight * 2; }
                    glyphHeight = glyph.obj.bitmap.rows;
                    //if (glyphHeight < 1) { glyphHeight = 1; }
                }

                if (!zeroSize)
                {
                    if (glyphXOffset + glyphWidth + 1 <= maxTextureWidth)
                    {
                        textureWidth = Math.Max(textureWidth, glyphXOffset + glyphWidth + 1);
                    }
                    else// 此字形将超出最大宽度,所以要换行。
                    {
                        textureHeight += fontHeight;

                        glyphXOffset = 0;
                        glyphYOffset = textureHeight - fontHeight;
                    }

                    CharacterInfo cInfo = new CharacterInfo();
                    cInfo.xoffset = glyphXOffset; cInfo.yoffset = glyphYOffset;
                    cInfo.width = glyphWidth; cInfo.height = glyphHeight;
                    charInfoDict.Add(c, cInfo);

                    glyphXOffset += glyphWidth + 1;
                }

                if (c == char.MaxValue) { break; }
            }
        }
        /// <summary>
        /// 根据<paramref name="firstChar"/>等信息获取要制作的贴图的宽高和各个字形的位置信息。
        /// </summary>
        /// <param name="face"></param>
        /// <param name="fontHeight"></param>
        /// <param name="firstChar"></param>
        /// <param name="lastChar"></param>
        /// <param name="maxTextureWidth"></param>
        /// <param name="charInfoDict"></param>
        /// <param name="textureWidth"></param>
        /// <param name="textureHeight"></param>
        private static IEnumerable<TTFTextureYeildingState> GetTextureBlueprint(
            FreeTypeFace face, int fontHeight, int maxTextureWidth, char firstChar, char lastChar)
        {
            int count = lastChar - firstChar;
            int index = 0;

            var charInfoDict = new Dictionary<char, CharacterInfo>();
            int textureWidth = 0;
            int textureHeight = fontHeight;

            int glyphXOffset = 0;
            int glyphYOffset = 0;

            for (char c = firstChar; c <= lastChar; c++)
            {
                FreeTypeBitmapGlyph glyph = new FreeTypeBitmapGlyph(face, c, fontHeight);
                {
                    var rect = glyph.glyphRec;
                    var glyphChar = glyph.glyphChar;
                    var left = glyph.obj.left;
                    var top = glyph.obj.top;
                    var x = glyph.obj.root.advance.x >> 6;
                    var y = glyph.obj.root.advance.y >> 6;
                    var clazz = glyph.obj.root.clazz;
                    var format = glyph.obj.root.format;
                    var library = glyph.obj.root.library;
                    var num_grays = glyph.obj.bitmap.num_grays;
                    var palette = glyph.obj.bitmap.palette;
                    var palette_mode = glyph.obj.bitmap.palette_mode;
                    var pitch = glyph.obj.bitmap.pitch;
                    var pixel_mode = glyph.obj.bitmap.pixel_mode;
                }

                bool zeroSize = (glyph.obj.bitmap.rows == 0 && glyph.obj.bitmap.width == 0);

                {
                    bool zeroBuffer = glyph.obj.bitmap.buffer == IntPtr.Zero;
                    if (zeroSize && (!zeroBuffer)) { throw new Exception(); }
                    if ((!zeroSize) && zeroBuffer) { throw new Exception(); }
                }

                int glyphWidth = glyph.obj.bitmap.width;
                int glyphHeight = glyph.obj.bitmap.rows;

                if (c == ' ' && zeroSize)// 空格需要特殊处理
                {
                    zeroSize = false;
                    FreeTypeBitmapGlyph tabGlyph = new FreeTypeBitmapGlyph(face, ' ', fontHeight);
                    glyphWidth = tabGlyph.obj.bitmap.width / 8;
                    if (glyphWidth < 1) { glyphWidth = fontHeight / 3; }
                    glyphHeight = tabGlyph.obj.bitmap.rows;
                    if (glyphHeight < 1) { glyphHeight = 1; }
                }
                else if (c == '\t' && zeroSize)// tab可能需要特殊处理
                {
                    zeroSize = false;
                    glyphWidth = glyph.obj.bitmap.width;
                    if (glyphWidth < 1) { glyphWidth = fontHeight * 2; }
                    glyphHeight = glyph.obj.bitmap.rows;
                    if (glyphHeight < 1) { glyphHeight = 1; }
                }

                if (!zeroSize)
                {
                    if (glyphXOffset + glyphWidth + 1 <= maxTextureWidth)
                    {
                        textureWidth = Math.Max(textureWidth, glyphXOffset + glyphWidth + 1);
                    }
                    else// 此字形将超出最大宽度,所以要换行。
                    {
                        textureHeight += fontHeight;

                        glyphXOffset = 0;
                        glyphYOffset = textureHeight - fontHeight;
                    }

                    CharacterInfo cInfo = new CharacterInfo();
                    cInfo.xoffset = glyphXOffset; cInfo.yoffset = glyphYOffset;
                    cInfo.width = glyphWidth; cInfo.height = glyphHeight;
                    charInfoDict.Add(c, cInfo);

                    glyphXOffset += glyphWidth + 1;
                }

                if (c == char.MaxValue) { break; }

                yield return new TTFTextureYeildingState()
                {
                    percent = index++ * 100 / count,
                    //message = "generating blueprint",
                    message = "blueprint",
                };
            }

            yield return new TTFTextureYeildingState()
            {
                percent = index++ * 100 / count,
                dict = charInfoDict,
                textureWidth = textureWidth,
                textureHeight = textureHeight,
                message = "blueprint done",
            };
        }