185 lines
4.6 KiB
C#
185 lines
4.6 KiB
C#
//public domain assumed from cyotek.com
|
||
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Drawing;
|
||
|
||
namespace Cyotek.Drawing.BitmapFont
|
||
{
|
||
public class BitmapFont : IEnumerable<Character>
|
||
{
|
||
#region Public Member Declarations
|
||
|
||
public const int NoMaxWidth = -1;
|
||
|
||
#endregion Public Member Declarations
|
||
|
||
#region Public Constructors
|
||
|
||
public BitmapFont()
|
||
{ }
|
||
|
||
#endregion Public Constructors
|
||
|
||
#region Public Methods
|
||
|
||
public IEnumerator<Character> GetEnumerator()
|
||
{
|
||
foreach (KeyValuePair<char, Character> pair in this.Characters)
|
||
yield return pair.Value;
|
||
}
|
||
|
||
public int GetKerning(char previous, char current)
|
||
{
|
||
Kerning key;
|
||
int result;
|
||
|
||
key = new Kerning(previous, current, 0);
|
||
if (!this.Kernings.TryGetValue(key, out result))
|
||
result = 0;
|
||
|
||
return result;
|
||
}
|
||
|
||
public Size MeasureFont(string text)
|
||
{
|
||
return this.MeasureFont(text, BitmapFont.NoMaxWidth);
|
||
}
|
||
|
||
public Size MeasureFont(string text, double maxWidth)
|
||
{
|
||
char previousCharacter;
|
||
string normalizedText;
|
||
int currentLineWidth;
|
||
int currentLineHeight;
|
||
int blockWidth;
|
||
int blockHeight;
|
||
List<int> lineHeights;
|
||
|
||
previousCharacter = ' ';
|
||
normalizedText = this.NormalizeLineBreaks(text);
|
||
currentLineWidth = 0;
|
||
currentLineHeight = this.LineHeight;
|
||
blockWidth = 0;
|
||
blockHeight = 0;
|
||
lineHeights = new List<int>();
|
||
|
||
foreach (char character in normalizedText)
|
||
{
|
||
switch (character)
|
||
{
|
||
case '\n':
|
||
lineHeights.Add(currentLineHeight);
|
||
blockWidth = Math.Max(blockWidth, currentLineWidth);
|
||
currentLineWidth = 0;
|
||
currentLineHeight = this.LineHeight;
|
||
break;
|
||
default:
|
||
Character data;
|
||
int width;
|
||
|
||
data = this[character];
|
||
width = data.XAdvance + this.GetKerning(previousCharacter, character);
|
||
|
||
if (maxWidth != BitmapFont.NoMaxWidth && currentLineWidth + width >= maxWidth)
|
||
{
|
||
lineHeights.Add(currentLineHeight);
|
||
blockWidth = Math.Max(blockWidth, currentLineWidth);
|
||
currentLineWidth = 0;
|
||
currentLineHeight = this.LineHeight;
|
||
}
|
||
|
||
currentLineWidth += width;
|
||
currentLineHeight = Math.Max(currentLineHeight, data.Bounds.Height + data.Offset.Y);
|
||
previousCharacter = character;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// finish off the current line if required
|
||
if (currentLineHeight != 0)
|
||
lineHeights.Add(currentLineHeight);
|
||
|
||
// reduce any lines other than the last back to the base
|
||
for (int i = 0; i < lineHeights.Count - 1; i++)
|
||
lineHeights[i] = this.LineHeight;
|
||
|
||
// calculate the final block height
|
||
foreach (int lineHeight in lineHeights)
|
||
blockHeight += lineHeight;
|
||
|
||
return new Size(Math.Max(currentLineWidth, blockWidth), blockHeight);
|
||
}
|
||
|
||
public string NormalizeLineBreaks(string s)
|
||
{
|
||
return s.Replace("\r\n", "\n").Replace("\r", "\n");
|
||
}
|
||
|
||
#endregion Public Methods
|
||
|
||
#region Public Properties
|
||
|
||
public int AlphaChannel { get; set; }
|
||
|
||
public int BaseHeight { get; set; }
|
||
|
||
public int BlueChannel { get; set; }
|
||
|
||
public bool Bold { get; set; }
|
||
|
||
public IDictionary<char, Character> Characters { get; set; }
|
||
|
||
public string Charset { get; set; }
|
||
|
||
public string FamilyName { get; set; }
|
||
|
||
public int FontSize { get; set; }
|
||
|
||
public int GreenChannel { get; set; }
|
||
|
||
public bool Italic { get; set; }
|
||
|
||
public IDictionary<Kerning, int> Kernings { get; set; }
|
||
|
||
public int LineHeight { get; set; }
|
||
|
||
public int OutlineSize { get; set; }
|
||
|
||
public bool Packed { get; set; }
|
||
|
||
public Padding Padding { get; set; }
|
||
|
||
public Page[] Pages { get; set; }
|
||
|
||
public int RedChannel { get; set; }
|
||
|
||
public bool Smoothed { get; set; }
|
||
|
||
public Point Spacing { get; set; }
|
||
|
||
public int StretchedHeight { get; set; }
|
||
|
||
public int SuperSampling { get; set; }
|
||
|
||
public Size TextureSize { get; set; }
|
||
|
||
public Character this[char character]
|
||
{ get { return this.Characters[character]; } }
|
||
|
||
public bool Unicode { get; set; }
|
||
|
||
#endregion Public Properties
|
||
|
||
#region Private Methods
|
||
|
||
IEnumerator IEnumerable.GetEnumerator()
|
||
{
|
||
return this.GetEnumerator();
|
||
}
|
||
|
||
#endregion Private Methods
|
||
}
|
||
}
|