反序列化从BMFont工具导出的XML时出错

时间:2015-09-29 17:06:49

标签: c# xml fonts bitmap monogame

我正在尝试使用以下示例:http://www.faqstackoverflow.com/answered/using-a-bmp-image-as-font-in-monogame

这个概念似乎很合理。我正在使用建议工具生成的.fnt。它看起来格式正确,并且基于类中使用的[序列化]有意义。

但是,每次运行代码时都会出现此错误:“System.Xml.dll中出现未处理的类型'System.InvalidOperationException'异常

其他信息:XML文档(1,1)中存在错误。“

我看起来狂热地围绕StackExchange和谷歌,并在来到这里并发布我的问题之前尝试了很多东西。我仍然在下面发布的FontLoader类中的注释中发现了许多这些尝试的混乱,我正在修改以尝试解决问题。无论它是如何切片的,都会产生同样的错误,或者更糟。

    public class FontLoader
{
    public static FontFile Load(String filename)
    {
           /* XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
            TextReader textReader = new StreamReader(Encoding.UTF8.GetBytes(filename).ToString());
            FontFile file = (FontFile)deserializer.Deserialize(textReader);
            textReader.Close();
            return file;*/


byte[] bytes = Encoding.UTF8.GetBytes(System.IO.File.ReadAllText(filename));
FontFile myInstance = null;
using (MemoryStream memStream = new MemoryStream(bytes))
{
XmlSerializer tokenSerializer = new XmlSerializer(typeof(FontFile));
myInstance = (FontFile)tokenSerializer.Deserialize(memStream);
Console.WriteLine(myInstance);
return myInstance;
}

/*
        XmlSerializer deserializer = new XmlSerializer(typeof(FontFile));
        TextReader textReader = new StreamReader(filename);
        FontFile file = (FontFile)deserializer.Deserialize(textReader);
        textReader.Close();
        return file;*/

/*         var xml = System.IO.File.ReadAllText(filename);
        using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(FontFile));
            FontFile file = (FontFile)serializer.Deserialize(stream);
            return file;
        }*/

     /*   var writer = new StringWriter();
        var serializer = new XmlSerializer((filename.GetType()));
        serializer.Serialize(writer, filename);
        string xml = writer.ToString();
        return xml;*/

    }
}

我使用的字体是Arial,作为测试,所以应该可以使用。它从这些行开始:

info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32   x=155   y=75    width=3     height=1     xoffset=-1    yoffset=31    xadvance=8     page=0  chnl=15

然后是具有相同结构的许多“char”线的contineus,接着是kernings线,然后是下面的“kerning”线,并且彼此具有相同的结构:

kernings count=91
kerning first=32  second=65  amount=-2  

如果它最终导致序列化出错,我为定位道歉,但我没有看到它。如果有人有解决方案,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:1)

有些事情发生了变化,因为你所指的回答是写的。您可以使用MonoGame.Extended库来完成您正在尝试的操作,而不是自己编写。我曾经写过一篇详细的blog post

您需要做的第一件事是install the MonoGame.Extended NuGet package。在程序包管理器控制台中运行以下命令。

Install-Package MonoGame.Extended -Pre

安装完成后,您的packages文件夹中会包含几个DLL。其中一个需要由MonoGame Pipeline工具引用。最简单的方法是在文本编辑器中手动编辑Content.mgcb文件。添加这样的参考线,但一定要与当前版本匹配。

#-------------------------------- References --------------------------------#

/reference:..\..\packages\MonoGame.Extended.0.3.44-alpha\lib\MonoGame.Extended.Content.Pipeline.dll

最后,您可以将字体文件和纹理添加到MonoGame管道工具中,并像其他任何内容一样加载。

_bitmapFont = Content.Load<BitmapFont>("my-font");

然后使用精灵批次

绘制它
_spriteBatch.Begin();
_spriteBatch.DrawString(_bitmapFont, "Hello World", new Vector2(100, 200), Color.Red);
_spriteBatch.End();

如果你真的想自己写,你可以查看implementation from MonoGame.Extended作为它的开源。

答案 1 :(得分:1)

问题实际上从你原来的问题中显而易见,但与你一样,我一开始忽略了这个问题。

在您发送.fnt文件后,我几乎立即发现了问题,因为我将其与之前导出的文件进行了比较。问题是您以错误的格式导出文件。正如您在问题中所说,您的文件如下所示:

info face="Arial" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
common lineHeight=32 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="arial_0.png"
chars count=191
char id=32   x=155   y=75    width=3     height=1     xoffset=-1    yoffset=31    xadvance=8     page=0  chnl=15

但看起来应该更像这样:

<?xml version="1.0"?>
<font>
  <info face="Arial" size="32" bold="1" italic="0" charset="" unicode="1" stretchH="100" smooth="1" aa="1" padding="0,0,0,0" spacing="1,1" outline="1"/>
  <common lineHeight="32" base="26" scaleW="256" scaleH="256" pages="1" packed="0" alphaChnl="1" redChnl="0" greenChnl="0" blueChnl="0"/>
  <pages>
    <page id="0" file="arial_0.png" />
  </pages>
  <chars count="191">

一旦你将它们并排比较,差异是显而易见的。第一个文件是纯文本,第二个文件是XML。它发生在我们最好的人身上:))

无论如何,要修复它,您只需要在BMFont工具中将文件格式设置为XML。

  1. 点击选项
  2. 点击导出选项
  3. 点击对话框底部附近的 XML 单选按钮
  4. 然后再次导出文件。