Commit Description:
Add timers for Simulation and various engines...
Commit Description:
Add timers for Simulation and various engines Starting to add additional timers for different stages of the process of updating in order to get more insight into what is slowing it down. The update takes 9ms, which is much longer than it used to. Engine-specific timers are coming later.
File last commit:
Show/Diff file:
Action:
SpriteFontPlus/deps/BMFontToSpriteFont/Cyotek.Drawing.Bitmap/BitmapFontLoader.cs
343 lines | 9.2 KiB | text/x-csharp | CSharpLexer
/* AngelCode bitmap font parsing using C#
* http://www.cyotek.com/blog/angelcode-bitmap-font-parsing-using-csharp
*
* Copyright © 2012-2015 Cyotek Ltd.
*
* Licensed under the MIT License. See license.txt for the full text.
*/
using System;
using System.Collections.Generic;
using System.IO;
#if !XENKO
using Microsoft.Xna.Framework;
#else
using Xenko.Core.Mathematics;
#endif
namespace Cyotek.Drawing.BitmapFont
{
/// <summary>
/// Parsing class for bitmap fonts generated by AngelCode BMFont
/// </summary>
internal static class BitmapFontLoader
{
#region Static Methods
/// <summary>
/// Loads a bitmap font from a file, attempting to auto detect the file type
/// </summary>
/// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
/// <exception cref="FileNotFoundException">Thrown when the requested file is not present.</exception>
/// <exception cref="InvalidDataException">Thrown when an Invalid Data error condition occurs.</exception>
/// <param name="fileName">Name of the file to load.</param>
/// <returns>
/// A <see cref="BitmapFont" /> containing the loaded data.
/// </returns>
public static BitmapFont LoadFontFromFile(string fileName)
{
BitmapFont result;
if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName", "File name not specified");
if (!File.Exists(fileName))
throw new FileNotFoundException(string.Format("Cannot find file '{0}'", fileName), fileName);
using (var file = File.OpenRead(fileName))
{
using (TextReader reader = new StreamReader(file))
{
string line;
line = reader.ReadLine();
if (line.StartsWith("info "))
result = LoadFontFromTextFile(fileName);
else if (line.StartsWith("<?xml"))
result = LoadFontFromXmlFile(fileName);
else
throw new InvalidDataException("Unknown file format.");
}
}
return result;
}
/// <summary>
/// Loads a bitmap font from a file containing font data in text format.
/// </summary>
/// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
/// <exception cref="FileNotFoundException">Thrown when the requested file is not present.</exception>
/// <param name="fileName">Name of the file to load.</param>
/// <returns>
/// A <see cref="BitmapFont" /> containing the loaded data.
/// </returns>
public static BitmapFont LoadFontFromTextFile(string fileName)
{
BitmapFont font;
if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName");
if (!File.Exists(fileName))
throw new FileNotFoundException(string.Format("Cannot find file '{0}'", fileName), fileName);
font = new BitmapFont();
using (Stream stream = File.OpenRead(fileName))
{
font.LoadText(stream);
}
QualifyResourcePaths(font, Path.GetDirectoryName(fileName));
return font;
}
/// <summary>
/// Loads a bitmap font from a file containing font data in XML format.
/// </summary>
/// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
/// <exception cref="FileNotFoundException">Thrown when the requested file is not present.</exception>
/// <param name="fileName">Name of the file to load.</param>
/// <returns>
/// A <see cref="BitmapFont" /> containing the loaded data.
/// </returns>
public static BitmapFont LoadFontFromXmlFile(string fileName)
{
BitmapFont font;
if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName");
if (!File.Exists(fileName))
throw new FileNotFoundException(string.Format("Cannot find file '{0}'", fileName), fileName);
font = new BitmapFont();
using (Stream stream = File.OpenRead(fileName))
{
font.LoadXml(stream);
}
QualifyResourcePaths(font, Path.GetDirectoryName(fileName));
return font;
}
/// <summary>
/// Returns a boolean from an array of name/value pairs.
/// </summary>
/// <param name="parts">The array of parts.</param>
/// <param name="name">The name of the value to return.</param>
/// <param name="defaultValue">Default value(if the key doesnt exist or can't be parsed)</param>
/// <returns></returns>
internal static bool GetNamedBool(string[] parts, string name, bool defaultValue = false)
{
var s = GetNamedString(parts, name);
bool result;
int v;
if (int.TryParse(s, out v))
result = v > 0;
else
result = defaultValue;
return result;
}
/// <summary>
/// Returns an integer from an array of name/value pairs.
/// </summary>
/// <param name="parts">The array of parts.</param>
/// <param name="name">The name of the value to return.</param>
/// <param name="defaultValue">Default value(if the key doesnt exist or can't be parsed)</param>
/// <returns></returns>
internal static int GetNamedInt(string[] parts, string name, int defaultValue = 0)
{
var s = GetNamedString(parts, name);
int result;
if (!int.TryParse(s, out result)) result = defaultValue;
return result;
}
/// <summary>
/// Returns a string from an array of name/value pairs.
/// </summary>
/// <param name="parts">The array of parts.</param>
/// <param name="name">The name of the value to return.</param>
/// <returns></returns>
internal static string GetNamedString(string[] parts, string name)
{
string result;
result = string.Empty;
foreach (var part in parts)
{
int nameEndIndex;
nameEndIndex = part.IndexOf('=');
if (nameEndIndex != -1)
{
string namePart;
string valuePart;
namePart = part.Substring(0, nameEndIndex);
valuePart = part.Substring(nameEndIndex + 1);
if (string.Equals(name, namePart, StringComparison.OrdinalIgnoreCase))
{
int length;
length = valuePart.Length;
if (length > 1 && valuePart[0] == '"' && valuePart[length - 1] == '"')
valuePart = valuePart.Substring(1, length - 2);
result = valuePart;
break;
}
}
}
return result;
}
/// <summary>
/// Creates a Padding object from a string representation
/// </summary>
/// <param name="s">The string.</param>
/// <returns></returns>
internal static Padding ParsePadding(string s)
{
string[] parts;
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>
/// <returns></returns>
internal static Point ParsePoint(string s)
{
string[] parts;
parts = s.Split(',');
return new Point
{
X = Convert.ToInt32(parts[0].Trim()),
Y = Convert.ToInt32(parts[1].Trim())
};
}
/// <summary>
/// Updates <see cref="Page" /> data with a fully qualified path
/// </summary>
/// <param name="font">The <see cref="BitmapFont" /> to update.</param>
/// <param name="resourcePath">The path where texture resources are located.</param>
internal static void QualifyResourcePaths(BitmapFont font, string resourcePath)
{
Page[] pages;
pages = font.Pages;
for (var i = 0; i < pages.Length; i++)
{
Page page;
page = pages[i];
page.FileName = Path.Combine(resourcePath, page.FileName);
pages[i] = page;
}
font.Pages = pages;
}
/// <summary>
/// Splits the specified string using a given delimiter, ignoring any instances of the delimiter as part of a quoted
/// string.
/// </summary>
/// <param name="s">The string to split.</param>
/// <param name="delimiter">The delimiter.</param>
/// <returns></returns>
internal static string[] Split(string s, char delimiter)
{
string[] results;
if (s.IndexOf('"') != -1)
{
List<string> parts;
int partStart;
partStart = -1;
parts = new List<string>();
do
{
int partEnd;
int quoteStart;
int quoteEnd;
bool hasQuotes;
quoteStart = s.IndexOf('"', partStart + 1);
quoteEnd = s.IndexOf('"', quoteStart + 1);
partEnd = s.IndexOf(delimiter, partStart + 1);
if (partEnd == -1) partEnd = s.Length;
hasQuotes = quoteStart != -1 && partEnd > quoteStart && partEnd < quoteEnd;
if (hasQuotes) partEnd = s.IndexOf(delimiter, quoteEnd + 1);
parts.Add(s.Substring(partStart + 1, partEnd - partStart - 1));
if (hasQuotes) partStart = partEnd - 1;
partStart = s.IndexOf(delimiter, partStart + 1);
} while (partStart != -1);
results = parts.ToArray();
}
else
{
results = s.Split(new[]
{
delimiter
}, StringSplitOptions.RemoveEmptyEntries);
}
return results;
}
/// <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>
/// <returns></returns>
internal static T[] ToArray<T>(ICollection<T> values)
{
T[] result;
// avoid a forced .NET 3 dependency just for one call to Linq
result = new T[values.Count];
values.CopyTo(result, 0);
return result;
}
#endregion
}
}