XNAExtras : tools and classes for XNA

In order to simplify releases, I'm collecting all of my XNA tools, classes and sample code into a single XNAExtras package. You can find a link to the latest version of XNAExtras here.

This first XNAExtras release contains updated versions of BMFontGen and BitmapFont:

BMFontGen :

Added font face name, size and style info to XML font descriptor file.
Added option to prevent custom glyphs from being tinted when drawing colored text.
Fixed crash when cancelling the font select dialog (oops!).
Changed code to prevent substitute fonts being used when the requested font is unavailable.
Changed "origin" attribute in font XML files to "loc" (location) since this is a better description and is more consistent with usage in sprite/texture XML files. Fonts created with "origin" attribute are still supported.
Removed support for ClearType anti-aliasing.

BitmapFont :

Fixed path problem whereby font image files weren't found if the font was in a subdirectory.
Changed GlyphInfo struct (in BitmapFont) to use bytes/sbytes instead of ints.
Added support for new features in XML font file.
Added TextBox method to format left, center or right-aligned text in a rectangle.
Added Save/RestoreState methods to save and restore the font rendering state.

Thanks to David Wyand, Thijs Kruithof (Gleoi), Jim Welch and Roger Bocksnick for their comments/suggestions.

In addition, a few extra classes (and associated demos) have been added:

TextBox : Class to manage more complex text rendering, includes support for rendering text borders to create UI elements. Makes use of BitmapFont and Border. (TextBox.cs)

Border : Class to draw sprite-based borders around rectangles. Makes use of XSprite. (Border.cs)

XSprite : Classes to manage sprites. Supports shared textures, animated sprites, different framerates for each sprite, keeps sprites sorted by depth (so that transparency works correctly) and allows sprites to be loaded from an XML descriptor file. (XSprite.cs, XSpriteBase.cs, XSpriteManager.cs, TexturePool.cs)

Note that I wasn't originally intending to include the XSprite classes with this release because there are still a few features that I wanted to add and I still need to finish the sprite demo to make it more interesting. However, because the Border class relies on it, you get to see a preview of these classes.

I'll probably talk about these classes and demos more in upcoming posts. As always, comments, suggestions and bug reports are welcome.

Comments (12)

  1. The folks over at XNA Diaries have been building and packaging up their XNA tools for the community! …

  2. David says:

    Thanks! I’ve been using BitMapFont extensively, and I’m looking forward to putting TextBox in action.


  3. The SBC DotNet WebLog has some links to XNA Dev Docs, as well as a link to a couple of XNA You Tube Videos….

  4. Gregory Wurm says:

    My suggestions for XSprite would be two things, one a way to run an animation once and then stop. The other is having a way to set different states. (Running walking standing…) this one not a big deal because it can be handled other ways.

    I did not see an easy to translate (move) the sprite with the sprite manager. (I may have missed it)

    Why are these not done as components?

    [To move a sprite, you need to set the position directly on the sprite. From the XSpriteManager, you could use something like sprite_mgr.GetSprite(“name”).SetPosition(x,y). Most likely you would cache the sprite somewhere so that you can do sprite.SetPosition(x,y) directly (which eliminates the name lookup).

    And they’re not components, because, well, I haven’t gotten around to it yet (sorry!). The sprite classes are not quite done (although they’re functional). I hesitated including them, but I wanted to release the TextBox class and I didn’t want to wait until everything was finished before releasing.

    Thanks for the suggestions. -GaryKac]

  5. DMZ says:

    I think I found a bug – try creating a textbox with a background after adding a sprite as a screen background (eg size of window). Crashes on me during Draw(), for reasons I haven’t quite discerned yet. Might just be my code, though – let me know if you can’t reproduce it or don’t see it.

    For the next version, dare I ask for “XSprite.ChangeSprite(String spritename, String texname)”? At the moment, there’s no easy way to change the texture of the sprite, and I can envision any number of scenarios where doing this would be helpful (that’s DMZ speak for “I have a need for it!”). It shouldn’t be very difficult to add, either.

    Otherwise, very excellent stuff: it’s really reducing my code size :).

    [I just tried the following code:

       m_font = new BitmapFont(“Content/cooper18.xml”);
       m_mgrSprites = new XSpriteManager();
       XSprite s = m_mgrSprites.AddSprite(“background”, Color.Magenta);
       s.SetDestRect(0, 0, 800, 500);
       Rectangle r = new Rectangle(20, 20, 100, 100);
       TextBox tb = m_mgrSprites.AddTextBox(“tb”, m_font, r, Color.Black, “sample string”);

    and it worked as expected. Can you send/post me an example of the problem? I may be missing some error handling on an invalid set of parameters.

    I’m curious about your need for redefining a sprite. Why not just remove the old sprite and create a new one? Or have two that you hide/show at different times? Can you explain your usage scenario so that I can understand what you’re doing?

    Thanks! – GaryKac]

  6. redwyre says:

    I have two requests for BitmapFont/BMFontGen:

    1. Allow alternate fonts to be used for different ranges (In my case I wanted to use “Lucida Console” but also add Japanese support – but it won’t work since the font doesn’t have it). I know this is probably a big one so I’m not getting my hopes up…

    2. Allow custom characters to be used for characters that have no glyph – I tried to map A/B/X/Y images to the “Private Use” range but since no glyphs exist it doesn’t let you.

    I was going to ask about support for not colouring the custom characters but you already added it, yay!

    [#1 is something that I’m already considering. I noticed the same thing with Japanese fonts – the Latin1 characters looked awful and I wanted to replace them with glyphs from another font. It won’t be right away, but I am thinking about this.

    #2 is something I hadn’t thought to test. I’ll try to get it for the next version.

    #3 is already done ^_^

    Thanks – GaryKac]

  7. crashlander says:

    When i run your Bitmap Font Demo, I get the following in my output window:

    A first chance exception of type ‘System.NullReferenceException’ occurred in BitmapFontDemo.exe

    The app still runs, just wondering if this is a known issue?  It happens somwhere in the code that is parsing thru the font xml file

    [See my response to the following comment. Thanks.]

  8. SSquared says:

    These are GREAT!  Thanks.  I am now taking advantage of the BitmapFont class and am looking forward to trying the other classes.  Especially TextBox.  That will come in real handy.

    The bug mentioned with the XML parsing is because the XML files still have the old ‘origin’ values instead of using ‘loc’.  The parsing throws an exception because it can’t find ‘loc’.  I ended up replacing ‘origin’ with ‘loc’.

    Same thing happens with ‘forcewhite’.  The Exception is getting caught and simply returns an empty string, so it is OK.

    [Do you have VisualStudio set to break when exceptions are thrown (instead of just having it break when the exception is not caught)? These are expected exceptions which are caught and handled in the XML loader.

    I have a version of GetXMLAttribute that doesn’t throw, but it iterates through the attributes so I opted for the try-catch version. If this is annoying people, then maybe I should use the iterating version.


  9. redwyre says:

    I was also annoyed by the exceptions, so I changed GetXMLAttribute to this:

    private static string GetXMLAttribute(XmlNode n, string strAttr)
       string strVal = “”;
       XmlAttribute node = (XmlAttribute)n.Attributes.GetNamedItem(strAttr);
       if (node != null)
           strVal = node.Value;
       return strVal;

    [Cool. That’s a better approach than my non-throwing version (I suppose I should have looked harder ^_^). I’ll definitely be changing this for the next release.

    Thanks for the feedback. -GaryKac]

  10. DMZ says:


    Your example doesn’t work for me. I’ve uploaded your sample program (or my interpretation of it) here:

    I stripped the binaries from it, so it should be pretty lean. Let me know what stupid mistake I’m making :).


    [My earlier comment on this mysteriously disappeared. Here it is again (as best as I can remember):

    This was a bug in AddTexture() that has now been fixed in the 0916 release:

       (TexturePool) Fixed bug in AddTexture(string,Color) where the texture wasn’t being created if the GraphicsDevice already existed

    Thanks for taking the time to wrap up your code for the bug report.


  11. redwyre says:

    Glad I could give something back 🙂 Speaking of giving, I have two things after upgrading… 😛

    Firstly: what’s the command in BMFontGen to force rendering custom glyphs white?

    [There’s an extra parameter to the -custom option which should be set to “true”. Or you can edit the font xml file and add an attibute directly: forcewhite=”true”.]

    Secondly: I found a bug in TextBox, it calls string.Format on the args, but then it calls DrawString which again calls string.Format on the string.. if the original string has an escape sequence like {{}} then that will become {} which makes it throw a format exception.

    I replaced the line in DrawString with string str = (args.Length == 0) ? format : string.Format(format, args);
    but I’m not sure that’s the proper way to do it…

    [I fixed this by adding an internal DrawString method that expects the string to already be formatted. It’ll be in the next version.


Skip to main content