0

I am trying to use the following example: http://www.faqstackoverflow.com/answered/using-a-bmp-image-as-font-in-monogame

The concept seems sound. I'm using a .fnt generated by the suggested tool. It looks properly formatted and makes sense based on the [Serialization] used in the classes.

However, Every time I run the code I get this error: "An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll

Additional information: There is an error in XML document (1, 1)."

I have looked feverishly around StackExchange and google, and tried many things before coming here and posting my question. I have many of the messy leavings of those attempts still in the comments posted below inside the FontLoader class I am modifying to try to fix the issue. No matter how it is sliced, it gives the same error, or worse.

    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;*/

    }
}

The font I'm using is Arial, as a test, so it should be ok to use. It starts out with these lines:

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

And then contineus with many "char" lines that have identical structure, followed by the kernings line, and then a bunce of "kerning" lines as below with identical structure to one another:

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

If it ends up being something wrong with the serialization, I apologize for positing, but I am not seeing it. Please let me know if anyone has a solution. Thank you.

craftworkgames
  • 9,437
  • 4
  • 41
  • 52
user3421630
  • 48
  • 1
  • 8

2 Answers2

1

A few things have changed since that answer you're referring to was written. Rather than writing it yourself you can use the MonoGame.Extended library to do exactly what you're trying to do. I wrote a detailed blog post about it a while back.

The first thing you'll need to do is install the MonoGame.Extended NuGet package. Run the following command in the Package Manager Console.

Install-Package MonoGame.Extended -Pre

Once it's installed you'll have a couple of DLLs in your packages folder. One of them will need to be referenced by the MonoGame Pipeline tool. The easiest way to do that is to edit your Content.mgcb file manually in a text editor. Add a reference line like this, but be sure to match the current version.

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

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

Lastly, you can add your font file and texture to the MonoGame Pipeline tool and load like any other content.

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

Then draw it using a sprite batch

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

If you really do want to write it yourself you can look at the implementation from MonoGame.Extended as it's open source.

craftworkgames
  • 9,437
  • 4
  • 41
  • 52
  • Hi, thank you for this. I expect once getting past this next issue I'll give this an accepted answer check, and I'm excited to be able to do the things your extension promises. Right now though, I am getting the same error as with the "loose code" attempt. There is an error at 1,1 in the xml. This is a fresh creation of a .fnt using the BM Font tool. The error happens right when rebuilding the content... the png succeeds, the .fnt fails with "BitmapFontImporter" had unexpected failure! With the details being that there is an error in xml document at 1,1, and issue with serialization... – user3421630 Sep 30 '15 at 19:47
  • Interesting. Can you zip up the font file and its texture then post a link somehow so i can download it. I'll see if I can spot the issue. – craftworkgames Sep 30 '15 at 22:09
  • Thank you for giving this attention. I hope you can find the files and the issue here https://drive.google.com/file/d/0BxA8WLGSiKm-MmFSQmptVmw4OUE/view?usp=sharing – user3421630 Sep 30 '15 at 22:32
  • @user3421630 Sorry it took a while to get back to you. When you sent the file this morning I was on my phone going to work and I didn't get a chance to look at it until just now. I've posted the solution as another answer because it's quite different to the first answer, but I think they both have value to anyone landing on this question. Feel free to accept whichever one you like. – craftworkgames Oct 01 '15 at 07:43
1

The issue is actually obvious from your original question, but like you I overlooked the problem at first.

After you sent me the .fnt file I spotted the issue almost immediately because I compared it to one I exported earlier. The problem is that you've exported the file in the wrong format. As you said in your question, your file looks like this:

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

But it should look more like this:

<?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">

Once you compare them side by side the difference is obvious. The first file is plain text and the second file is XML. It happens to the best of us :)

Anyway, to fix it you just need to set the file format to XML in the BMFont tool.

  1. Click Options
  2. Click Export Options
  3. Click the XML radio button near the bottom of the dialog

Then export your file again.

craftworkgames
  • 9,437
  • 4
  • 41
  • 52
  • Oh wow... I thought the custom class was supposed to convert the plain text into xml based on the expected schema, and then deserialize it, based on my assumption that the plain text was just how BM Font did things and it was up to the .net application to fix it up as xml. Ha... the default being Text I didn't even know you could change it. Thank you so much! – user3421630 Oct 01 '15 at 12:09
  • You're welcome. We could eventually support all of the different formats in MonoGame.Extended but since it's only 1 click it's not a priority at the moment. Glad to you got it working :) – craftworkgames Oct 01 '15 at 12:18