public static void SaveToXML(IntFontInfo fnt, string outPath) { XmlDocument doc = new XmlDocument(); XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null); XmlElement root = doc.CreateElement("font"); doc.InsertBefore(decl, doc.DocumentElement); doc.AppendChild(root); XmlElement common = doc.CreateElement("common"); common.SetAttribute("lineHeight", fnt.lineHeight.ToString()); common.SetAttribute("scaleW", fnt.scaleW.ToString()); common.SetAttribute("scaleH", fnt.scaleH.ToString()); common.SetAttribute("pages", "1"); root.AppendChild(common); XmlElement pages = doc.CreateElement("pages"); XmlElement page1 = doc.CreateElement("page"); page1.SetAttribute("id", "0"); page1.SetAttribute("file", fnt.texName); pages.AppendChild(page1); root.AppendChild(pages); XmlElement chars = doc.CreateElement("chars"); chars.SetAttribute("count", fnt.chars.Count.ToString()); foreach (IntChar c in fnt.chars) { XmlElement cNode = doc.CreateElement("char"); cNode.SetAttribute("id", c.id.ToString()); cNode.SetAttribute("x", c.x.ToString()); cNode.SetAttribute("y", c.y.ToString()); cNode.SetAttribute("width", c.width.ToString()); cNode.SetAttribute("height", c.height.ToString()); cNode.SetAttribute("xoffset", c.xoffset.ToString()); cNode.SetAttribute("yoffset", c.yoffset.ToString()); cNode.SetAttribute("xadvance", c.xadvance.ToString()); chars.AppendChild(cNode); } root.AppendChild(chars); XmlElement kernings = doc.CreateElement("kernings"); kernings.SetAttribute("count", fnt.kernings.Count.ToString()); foreach (IntKerning k in fnt.kernings) { XmlElement kNode = doc.CreateElement("kerning"); kNode.SetAttribute("first", k.first.ToString()); kNode.SetAttribute("second", k.second.ToString()); kNode.SetAttribute("amount", k.amount.ToString()); kernings.AppendChild(kNode); } root.AppendChild(kernings); doc.Save(outPath); }
static IntFontInfo ParseBMFontText(string path) { IntFontInfo fontInfo = new IntFontInfo(); FileInfo finfo = new FileInfo(path); StreamReader reader = finfo.OpenText(); string line; while ((line = reader.ReadLine()) != null) { string[] tokens = line.Split(' '); if (tokens[0] == "common") { fontInfo.lineHeight = int.Parse(FindKeyValue(tokens, "lineHeight")); fontInfo.scaleW = int.Parse(FindKeyValue(tokens, "scaleW")); fontInfo.scaleH = int.Parse(FindKeyValue(tokens, "scaleH")); int pages = int.Parse(FindKeyValue(tokens, "pages")); if (pages != 1) { EditorUtility.DisplayDialog("Fatal error", "Only one page supported in font. Please change the setting and re-export.", "Ok"); return(null); } } else if (tokens[0] == "char") { IntChar thisChar = new IntChar(); thisChar.id = int.Parse(FindKeyValue(tokens, "id")); thisChar.x = int.Parse(FindKeyValue(tokens, "x")); thisChar.y = int.Parse(FindKeyValue(tokens, "y")); thisChar.width = int.Parse(FindKeyValue(tokens, "width")); thisChar.height = int.Parse(FindKeyValue(tokens, "height")); thisChar.xoffset = int.Parse(FindKeyValue(tokens, "xoffset")); thisChar.yoffset = int.Parse(FindKeyValue(tokens, "yoffset")); thisChar.xadvance = int.Parse(FindKeyValue(tokens, "xadvance")); fontInfo.chars.Add(thisChar); } else if (tokens[0] == "kerning") { IntKerning thisKerning = new IntKerning(); thisKerning.first = int.Parse(FindKeyValue(tokens, "first")); thisKerning.second = int.Parse(FindKeyValue(tokens, "second")); thisKerning.amount = int.Parse(FindKeyValue(tokens, "amount")); fontInfo.kernings.Add(thisKerning); } else if (tokens[0] == "page") { fontInfo.texName = FindKeyValue(tokens, "file"); } } reader.Close(); return(fontInfo); }
public static void SaveToXML(IntFontInfo fnt, string outPath) { XmlDocument doc = new XmlDocument(); XmlDeclaration decl = doc.CreateXmlDeclaration("1.0","utf-8",null); XmlElement root = doc.CreateElement("font"); doc.InsertBefore(decl, doc.DocumentElement); doc.AppendChild(root); XmlElement common = doc.CreateElement("common"); common.SetAttribute("lineHeight", fnt.lineHeight.ToString()); common.SetAttribute("scaleW", fnt.scaleW.ToString()); common.SetAttribute("scaleH", fnt.scaleH.ToString()); common.SetAttribute("pages", "1"); root.AppendChild(common); XmlElement pages = doc.CreateElement("pages"); XmlElement page1 = doc.CreateElement("page"); page1.SetAttribute("id", "0"); page1.SetAttribute("file", fnt.texName); pages.AppendChild(page1); root.AppendChild(pages); XmlElement chars = doc.CreateElement("chars"); chars.SetAttribute("count", fnt.chars.Count.ToString()); foreach(IntChar c in fnt.chars){ XmlElement cNode = doc.CreateElement("char"); cNode.SetAttribute("id", c.id.ToString()); cNode.SetAttribute("x", c.x.ToString()); cNode.SetAttribute("y", c.y.ToString()); cNode.SetAttribute("width", c.width.ToString()); cNode.SetAttribute("height", c.height.ToString()); cNode.SetAttribute("xoffset", c.xoffset.ToString()); cNode.SetAttribute("yoffset", c.yoffset.ToString()); cNode.SetAttribute("xadvance", c.xadvance.ToString()); chars.AppendChild(cNode); } root.AppendChild(chars); XmlElement kernings = doc.CreateElement("kernings"); kernings.SetAttribute("count", fnt.kernings.Count.ToString()); foreach(IntKerning k in fnt.kernings){ XmlElement kNode = doc.CreateElement("kerning"); kNode.SetAttribute("first", k.first.ToString()); kNode.SetAttribute("second", k.second.ToString()); kNode.SetAttribute("amount", k.amount.ToString()); kernings.AppendChild(kNode); } root.AppendChild(kernings); doc.Save(outPath); }
static IntFontInfo ParseBMFontXml(XmlDocument doc) { IntFontInfo fontInfo = new IntFontInfo(); XmlNode nodeCommon = doc.SelectSingleNode("/font/common"); fontInfo.scaleW = ReadIntAttribute(nodeCommon, "scaleW"); fontInfo.scaleH = ReadIntAttribute(nodeCommon, "scaleH"); fontInfo.lineHeight = ReadIntAttribute(nodeCommon, "lineHeight"); int pages = ReadIntAttribute(nodeCommon, "pages"); if (pages != 1) { EditorUtility.DisplayDialog("Fatal error", "Only one page supported in font. Please change the setting and re-export.", "Ok"); return(null); } foreach (XmlNode node in doc.SelectNodes(("/font/pages/page"))) { fontInfo.texName = ReadStringAttribute(node, "file"); } foreach (XmlNode node in doc.SelectNodes(("/font/chars/char"))) { IntChar thisChar = new IntChar(); thisChar.id = ReadIntAttribute(node, "id"); thisChar.x = ReadIntAttribute(node, "x"); thisChar.y = ReadIntAttribute(node, "y"); thisChar.width = ReadIntAttribute(node, "width"); thisChar.height = ReadIntAttribute(node, "height"); thisChar.xoffset = ReadIntAttribute(node, "xoffset"); thisChar.yoffset = ReadIntAttribute(node, "yoffset"); thisChar.xadvance = ReadIntAttribute(node, "xadvance"); fontInfo.chars.Add(thisChar); } foreach (XmlNode node in doc.SelectNodes("/font/kernings/kerning")) { IntKerning thisKerning = new IntKerning(); thisKerning.first = ReadIntAttribute(node, "first"); thisKerning.second = ReadIntAttribute(node, "second"); thisKerning.amount = ReadIntAttribute(node, "amount"); fontInfo.kernings.Add(thisKerning); } return(fontInfo); }
public static IntFontInfo ParseFromPath(string path) { IntFontInfo fontInfo = null; try { XmlDocument doc = new XmlDocument(); doc.Load(path); fontInfo = ParseBMFontXml(doc); } catch { fontInfo = ParseBMFontText(path); } if (fontInfo == null || fontInfo.chars.Count == 0) { return(null); } return(fontInfo); }
static IntFontInfo ParseBMFontXml(XmlDocument doc) { IntFontInfo fontInfo = new IntFontInfo(); XmlNode nodeCommon = doc.SelectSingleNode("/font/common"); fontInfo.scaleW = ReadIntAttribute(nodeCommon, "scaleW"); fontInfo.scaleH = ReadIntAttribute(nodeCommon, "scaleH"); fontInfo.lineHeight = ReadIntAttribute(nodeCommon, "lineHeight"); int pages = ReadIntAttribute(nodeCommon, "pages"); if (pages != 1) { EditorUtility.DisplayDialog("Fatal error", "Only one page supported in font. Please change the setting and re-export.", "Ok"); return null; } foreach (XmlNode node in doc.SelectNodes(("/font/pages/page"))) { fontInfo.texName = ReadStringAttribute(node, "file"); } foreach (XmlNode node in doc.SelectNodes(("/font/chars/char"))) { IntChar thisChar = new IntChar(); thisChar.id = ReadIntAttribute(node, "id"); thisChar.x = ReadIntAttribute(node, "x"); thisChar.y = ReadIntAttribute(node, "y"); thisChar.width = ReadIntAttribute(node, "width"); thisChar.height = ReadIntAttribute(node, "height"); thisChar.xoffset = ReadIntAttribute(node, "xoffset"); thisChar.yoffset = ReadIntAttribute(node, "yoffset"); thisChar.xadvance = ReadIntAttribute(node, "xadvance"); fontInfo.chars.Add(thisChar); } foreach (XmlNode node in doc.SelectNodes("/font/kernings/kerning")) { IntKerning thisKerning = new IntKerning(); thisKerning.first = ReadIntAttribute(node, "first"); thisKerning.second = ReadIntAttribute(node, "second"); thisKerning.amount = ReadIntAttribute(node, "amount"); fontInfo.kernings.Add(thisKerning); } return fontInfo; }
static IntFontInfo ParseBMFontText(string path) { IntFontInfo fontInfo = new IntFontInfo(); FileInfo finfo = new FileInfo(path); StreamReader reader = finfo.OpenText(); string line; while ((line = reader.ReadLine()) != null) { string[] tokens = line.Split( ' ' ); if (tokens[0] == "common") { fontInfo.lineHeight = int.Parse( FindKeyValue(tokens, "lineHeight") ); fontInfo.scaleW = int.Parse( FindKeyValue(tokens, "scaleW") ); fontInfo.scaleH = int.Parse( FindKeyValue(tokens, "scaleH") ); int pages = int.Parse( FindKeyValue(tokens, "pages") ); if (pages != 1) { EditorUtility.DisplayDialog("Fatal error", "Only one page supported in font. Please change the setting and re-export.", "Ok"); return null; } } else if (tokens[0] == "char") { IntChar thisChar = new IntChar(); thisChar.id = int.Parse(FindKeyValue(tokens, "id")); thisChar.x = int.Parse(FindKeyValue(tokens, "x")); thisChar.y = int.Parse(FindKeyValue(tokens, "y")); thisChar.width = int.Parse(FindKeyValue(tokens, "width")); thisChar.height = int.Parse(FindKeyValue(tokens, "height")); thisChar.xoffset = int.Parse(FindKeyValue(tokens, "xoffset")); thisChar.yoffset = int.Parse(FindKeyValue(tokens, "yoffset")); thisChar.xadvance = int.Parse(FindKeyValue(tokens, "xadvance")); fontInfo.chars.Add(thisChar); } else if (tokens[0] == "kerning") { IntKerning thisKerning = new IntKerning(); thisKerning.first = int.Parse(FindKeyValue(tokens, "first")); thisKerning.second = int.Parse(FindKeyValue(tokens, "second")); thisKerning.amount = int.Parse(FindKeyValue(tokens, "amount")); fontInfo.kernings.Add(thisKerning); } else if (tokens[0] == "page") { fontInfo.texName = FindKeyValue(tokens, "file"); } } reader.Close(); return fontInfo; }
bool ParseBMFont(string path, tk2dFontData bmFont, tk2dFont source) { IntFontInfo fontInfo = null; try { XmlDocument doc = new XmlDocument(); doc.Load(path); fontInfo = ParseBMFontXml(doc); } catch { fontInfo = ParseBMFontText(path); } if (fontInfo == null || fontInfo.chars.Count == 0) { return(false); } float texWidth = fontInfo.scaleW; float texHeight = fontInfo.scaleH; float lineHeight = fontInfo.lineHeight; float scale = 2.0f * source.targetOrthoSize / source.targetHeight; bmFont.lineHeight = lineHeight * scale; tk2dFontChar[] chars = new tk2dFontChar[source.numCharacters]; int minChar = 65536; int maxCharWithinBounds = 0; int numLocalChars = 0; float largestWidth = 0.0f; foreach (var theChar in fontInfo.chars) { tk2dFontChar thisChar = new tk2dFontChar(); int id = theChar.id; int x = theChar.x; int y = theChar.y; int width = theChar.width; int height = theChar.height; int xoffset = theChar.xoffset; int yoffset = theChar.yoffset; int xadvance = theChar.xadvance; // precompute required data float px = xoffset * scale; float py = (lineHeight - yoffset) * scale; thisChar.p0 = new Vector3(px, py, 0); thisChar.p1 = new Vector3(px + width * scale, py - height * scale, 0); if (source.flipTextureY) { thisChar.uv0 = new Vector2(x / texWidth, y / texHeight); thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y + height / texHeight); } else { thisChar.uv0 = new Vector2(x / texWidth, 1.0f - y / texHeight); thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y - height / texHeight); } thisChar.advance = xadvance * scale; largestWidth = Mathf.Max(thisChar.advance, largestWidth); // Needs gradient data if (source.gradientTexture != null) { // build it up assuming the first gradient float x0 = (float)(0.0f / source.gradientCount); float x1 = (float)(1.0f / source.gradientCount); float y0 = 1.0f; float y1 = 0.0f; // align to glyph if necessary thisChar.gradientUv = new Vector2[4]; thisChar.gradientUv[0] = new Vector2(x0, y0); thisChar.gradientUv[1] = new Vector2(x1, y0); thisChar.gradientUv[2] = new Vector2(x0, y1); thisChar.gradientUv[3] = new Vector2(x1, y1); } if (id < source.numCharacters) { maxCharWithinBounds = (id > maxCharWithinBounds) ? id : maxCharWithinBounds; minChar = (id < minChar) ? id : minChar; chars[id] = thisChar; ++numLocalChars; } } if (source.dupeCaps) { for (int uc = 'A'; uc <= 'Z'; ++uc) { int lc = uc + ('a' - 'A'); if (chars[lc] == null) { chars[lc] = chars[uc]; } else if (chars[uc] == null) { chars[uc] = chars[lc]; } } } bmFont.largestWidth = largestWidth; bmFont.chars = new tk2dFontChar[source.numCharacters]; for (int i = 0; i < source.numCharacters; ++i) { bmFont.chars[i] = chars[i]; if (bmFont.chars[i] == null) { bmFont.chars[i] = new tk2dFontChar(); // zero everything, null char } } // kerning bmFont.kerning = new tk2dFontKerning[fontInfo.kernings.Count]; for (int i = 0; i < bmFont.kerning.Length; ++i) { tk2dFontKerning kerning = new tk2dFontKerning(); kerning.c0 = fontInfo.kernings[i].first; kerning.c1 = fontInfo.kernings[i].second; kerning.amount = fontInfo.kernings[i].amount * scale; bmFont.kerning[i] = kerning; } return(true); }