BizHawk/Bizware/BizHawk.Bizware.BizwareGL/Borrowed/BitmapFontParser/BitmapFontLoader.cs

171 lines
5.7 KiB
C#
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Xml;
// public domain assumed from cyotek.com
namespace Cyotek.Drawing.BitmapFont
{
// Parsing class for bitmap fonts generated by AngelCode BMFont
// http://www.angelcode.com/products/bmfont/
public static class BitmapFontLoader
{
#region  Public Class Methods
/// <summary>
/// Loads a bitmap font from an XML file.
/// </summary>
public static BitmapFont LoadFontFromXmlFile(Stream stream)
{
var document = new XmlDocument();
IDictionary<int, Page> pageData = new SortedDictionary<int, Page>();
IDictionary<Kerning, int> kerningDictionary = new Dictionary<Kerning, int>();
IDictionary<char, Character> charDictionary = new Dictionary<char, Character>();
var font = new BitmapFont();
document.Load(stream);
XmlNode root = document.DocumentElement;
// load the basic attributes
var properties = root.SelectSingleNode("info");
font.FamilyName = properties.Attributes["face"].Value;
font.FontSize = Convert.ToInt32(properties.Attributes["size"].Value);
font.Bold = Convert.ToInt32(properties.Attributes["bold"].Value) != 0;
font.Italic = Convert.ToInt32(properties.Attributes["italic"].Value) != 0;
font.Unicode = Convert.ToInt32(properties.Attributes["unicode"].Value) != 0;
font.StretchedHeight = Convert.ToInt32(properties.Attributes["stretchH"].Value);
font.Charset = properties.Attributes["charset"].Value;
font.Smoothed = Convert.ToInt32(properties.Attributes["smooth"].Value) != 0;
font.SuperSampling = Convert.ToInt32(properties.Attributes["aa"].Value);
font.Padding = ParsePadding(properties.Attributes["padding"].Value);
font.Spacing = ParsePoint(properties.Attributes["spacing"].Value);
font.OutlineSize = Convert.ToInt32(properties.Attributes["outline"].Value);
// common attributes
properties = root.SelectSingleNode("common");
font.BaseHeight = Convert.ToInt32(properties.Attributes["lineHeight"].Value);
font.LineHeight = Convert.ToInt32(properties.Attributes["base"].Value);
font.TextureSize = new Size
(
Convert.ToInt32(properties.Attributes["scaleW"].Value),
Convert.ToInt32(properties.Attributes["scaleH"].Value)
);
font.Packed = Convert.ToInt32(properties.Attributes["packed"].Value) != 0;
font.AlphaChannel = Convert.ToInt32(properties.Attributes["alphaChnl"].Value);
font.RedChannel = Convert.ToInt32(properties.Attributes["redChnl"].Value);
font.GreenChannel = Convert.ToInt32(properties.Attributes["greenChnl"].Value);
font.BlueChannel = Convert.ToInt32(properties.Attributes["blueChnl"].Value);
// load texture information
foreach (XmlNode node in root.SelectNodes("pages/page"))
{
var page = new Page
{
Id = Convert.ToInt32(node.Attributes["id"].Value),
FileName = node.Attributes["file"].Value
};
pageData.Add(page.Id, page);
}
font.Pages = ToArray(pageData.Values);
// load character information
foreach (XmlNode node in root.SelectNodes("chars/char"))
{
var character = new Character
{
Char = (char) Convert.ToInt32(node.Attributes["id"].Value),
Bounds = new Rectangle
(
Convert.ToInt32(node.Attributes["x"].Value),
Convert.ToInt32(node.Attributes["y"].Value),
Convert.ToInt32(node.Attributes["width"].Value),
Convert.ToInt32(node.Attributes["height"].Value)
),
Offset = new Point
(
Convert.ToInt32(node.Attributes["xoffset"].Value),
Convert.ToInt32(node.Attributes["yoffset"].Value)
),
XAdvance = Convert.ToInt32(node.Attributes["xadvance"].Value),
TexturePage = Convert.ToInt32(node.Attributes["page"].Value),
Channel = Convert.ToInt32(node.Attributes["chnl"].Value)
};
charDictionary.Add(character.Char, character);
}
font.Characters = charDictionary;
// loading kerning information
foreach (XmlNode node in root.SelectNodes("kernings/kerning"))
{
var key = new Kerning((char)Convert.ToInt32(node.Attributes["first"].Value), (char)Convert.ToInt32(node.Attributes["second"].Value), Convert.ToInt32(node.Attributes["amount"].Value));
if (!kerningDictionary.ContainsKey(key))
{
kerningDictionary.Add(key, key.Amount);
}
}
font.Kernings = kerningDictionary;
return font;
}
#endregion  Public Class Methods
#region  Private Class Methods
/// <summary>
/// Creates a Padding object from a string representation
/// </summary>
/// <param name="s">The string.</param>
private static Padding ParsePadding(string s)
{
var parts = s.Split(',');
return new Padding
{
Left = Convert.ToInt32(parts[3].Trim()),
Top = Convert.ToInt32(parts[0].Trim()),
Right = Convert.ToInt32(parts[1].Trim()),
Bottom = Convert.ToInt32(parts[2].Trim())
};
}
/// <summary>
/// Creates a Point object from a string representation
/// </summary>
/// <param name="s">The string.</param>
private static Point ParsePoint(string s)
{
var parts = s.Split(',');
return new Point
{
X = Convert.ToInt32(parts[0].Trim()),
Y = Convert.ToInt32(parts[1].Trim())
};
}
/// <summary>
/// Converts the given collection into an array
/// </summary>
/// <typeparam name="T">Type of the items in the array</typeparam>
/// <param name="values">The values.</param>
private static T[] ToArray<T>(ICollection<T> values)
{
// avoid a forced .NET 3 dependency just for one call to Linq
var result = new T[values.Count];
values.CopyTo(result, 0);
return result;
}
#endregion  Private Class Methods
}
}