forked from Thraka/SadConsole
/
Font.cs
133 lines (106 loc) · 4.97 KB
/
Font.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Runtime.Serialization;
using System.Xml.Linq;
namespace SadConsole
{
public class Font
{
public string Name { get; set; }
public string FilePath { get; set; }
public int CellHeight { get; set; }
public int CellWidth { get; set; }
public int CellPadding { get; set; }
public bool IsDefault { get; set; }
[IgnoreDataMember]
public int Rows { get { return Image.Height / (CellHeight + CellPadding); } }
[IgnoreDataMember]
public Texture2D Image { get; private set; }
[IgnoreDataMember]
public Point[] CharacterIndexPoints;
[IgnoreDataMember]
public Rectangle[] CharacterIndexRects;
#region Constructors
public Font() { }
public Font(string name, XElement fontXmlNode, GraphicsDevice device)
{
XAttribute xwidth = fontXmlNode.Attribute("width");
XAttribute xheight = fontXmlNode.Attribute("height");
string filename = fontXmlNode.Value;
if (xwidth == null || xheight == null)
throw new Exception("Width or Height attribute for font is missing");
int width;
int height;
if (!int.TryParse(xwidth.Value, out width))
throw new Exception("Width value is invalid: " + xwidth.Value);
if (!int.TryParse(xheight.Value, out height))
throw new Exception("Height value is invalid: " + xheight.Value);
System.IO.Stream fontStream = System.IO.File.OpenRead(filename);
this.Image = Texture2D.FromStream(device, fontStream);
fontStream.Dispose();
FilePath = filename;
Name = name;
CellWidth = width;
CellHeight = height;
Generate();
}
#endregion
#region Methods
/// <summary>
/// After the font has been loaded, (with the FilePath, CellHeight, and CellWidth fields filled out) this method will create the actual texture.
/// </summary>
public void Generate()
{
System.IO.Stream fontStream = System.IO.File.OpenRead(FilePath);
this.Image = Texture2D.FromStream(Engine.Device, fontStream);
fontStream.Dispose();
ConfigureRects();
}
public void ConfigureRects()
{
CharacterIndexRects = new Rectangle[Rows * Engine.FontColumns];
CharacterIndexPoints = new Point[CharacterIndexRects.Length];
for (int i = 0; i < CharacterIndexRects.Length; i++)
{
CharacterIndexPoints[i] = new Point(i % Engine.FontColumns, i / Engine.FontColumns);
if (CellPadding != 0)
CharacterIndexRects[i] = new Rectangle((CharacterIndexPoints[i].X * CellWidth) + ((CharacterIndexPoints[i].X + 1) * CellPadding),
(CharacterIndexPoints[i].Y * CellHeight) + ((CharacterIndexPoints[i].Y + 1) * CellPadding), CellWidth, CellHeight);
else
CharacterIndexRects[i] = new Rectangle(CharacterIndexPoints[i].X * CellWidth, CharacterIndexPoints[i].Y * CellHeight, CellWidth, CellHeight);
}
}
private void GetImageMask()
{
Texture2D texture = new Texture2D(Engine.Device, Image.Width, Image.Height,
false, SurfaceFormat.Color);
Color[] newPixels = new Color[texture.Width * texture.Height];
Color[] oldPixels = new Color[texture.Width * texture.Height];
texture.GetData<Color>(newPixels);
Image.GetData<Color>(oldPixels);
}
/// <summary>
/// Resizes the graphics device manager to this font cell size.
/// </summary>
/// <param name="manager">Graphics device manager to resize.</param>
/// <param name="width">The width in cell count.</param>
/// <param name="height">The height in cell count.</param>
/// <param name="additionalWidth">Additional pixel width to add to the resize.</param>
/// <param name="additionalHeight">Additional pixel height to add to the resize.</param>
public void ResizeGraphicsDeviceManager(GraphicsDeviceManager manager, int width, int height, int additionalWidth, int additionalHeight)
{
manager.PreferredBackBufferWidth = (CellWidth * width) + additionalWidth;
manager.PreferredBackBufferHeight = (CellHeight * height) + additionalHeight;
manager.ApplyChanges();
Engine.WindowWidth = manager.PreferredBackBufferWidth;
Engine.WindowHeight = manager.PreferredBackBufferHeight;
}
[OnDeserialized]
private void AfterDeserialized(System.Runtime.Serialization.StreamingContext context)
{
Generate();
}
#endregion
}
}