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; }
/// <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", }; }