mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 12:22:35 +00:00
256 lines
6.2 KiB
C#
256 lines
6.2 KiB
C#
|
|
||
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||
|
* This program is released under GNU General Public License
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Namespaces
|
||
|
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Text;
|
||
|
using System.IO;
|
||
|
using System.Drawing;
|
||
|
using SlimDX;
|
||
|
|
||
|
using Configuration = CodeImp.DoomBuilder.IO.Configuration;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
namespace CodeImp.DoomBuilder.Rendering
|
||
|
{
|
||
|
internal class TextFont : IDisposable
|
||
|
{
|
||
|
#region ================== Structures
|
||
|
|
||
|
// This structure defines character properties
|
||
|
private struct FontCharacter
|
||
|
{
|
||
|
// Variables
|
||
|
public float width;
|
||
|
public float height;
|
||
|
public float u1;
|
||
|
public float v1;
|
||
|
public float u2;
|
||
|
public float v2;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Constants
|
||
|
|
||
|
// Font resource name
|
||
|
private const string FONT_RESOURCE = "Font.cfg";
|
||
|
|
||
|
// Spacing adjustments
|
||
|
private const float ADJUST_SPACING = -0.08f;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Variables
|
||
|
|
||
|
// Characters
|
||
|
private FontCharacter[] characters;
|
||
|
|
||
|
// Disposing
|
||
|
private bool isdisposed = false;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Properties
|
||
|
|
||
|
public bool IsDisposed { get { return isdisposed; } }
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Constructor / Disposer
|
||
|
|
||
|
// Constructor
|
||
|
internal TextFont()
|
||
|
{
|
||
|
Configuration cfg;
|
||
|
Stream fontdata;
|
||
|
StreamReader fontreader;
|
||
|
string[] resnames;
|
||
|
|
||
|
// Initialize
|
||
|
characters = new FontCharacter[256];
|
||
|
|
||
|
// Make chars configuration
|
||
|
cfg = new Configuration();
|
||
|
|
||
|
// Find a resource named Font.cfg
|
||
|
resnames = General.ThisAssembly.GetManifestResourceNames();
|
||
|
foreach(string rn in resnames)
|
||
|
{
|
||
|
// Found it?
|
||
|
if(rn.EndsWith(FONT_RESOURCE, StringComparison.InvariantCultureIgnoreCase))
|
||
|
{
|
||
|
// Get a stream from the resource
|
||
|
fontdata = General.ThisAssembly.GetManifestResourceStream(rn);
|
||
|
fontreader = new StreamReader(fontdata, Encoding.ASCII);
|
||
|
|
||
|
// Load configuration from stream
|
||
|
cfg.InputConfiguration(fontreader.ReadToEnd());
|
||
|
|
||
|
// Done
|
||
|
fontreader.Dispose();
|
||
|
fontdata.Dispose();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get the charset from configuration
|
||
|
IDictionary cfgchars = cfg.ReadSetting("chars", new Hashtable());
|
||
|
|
||
|
// Go for all defined chars
|
||
|
foreach(DictionaryEntry item in cfgchars)
|
||
|
{
|
||
|
// Get the character Hashtable
|
||
|
IDictionary chr = (IDictionary)item.Value;
|
||
|
int i = Convert.ToInt32(item.Key);
|
||
|
|
||
|
// This is ancient code of mine.
|
||
|
// The charater sizes were based on 800x600 resolution.
|
||
|
characters[i].width = (float)(int)chr["width"] / 40f;
|
||
|
characters[i].height = (float)(int)chr["height"] / 30f;
|
||
|
characters[i].u1 = (float)chr["u1"];
|
||
|
characters[i].v1 = (float)chr["v1"];
|
||
|
characters[i].u2 = (float)chr["u2"];
|
||
|
characters[i].v2 = (float)chr["v2"];
|
||
|
}
|
||
|
|
||
|
// We have no destructor
|
||
|
GC.SuppressFinalize(this);
|
||
|
}
|
||
|
|
||
|
// Diposer
|
||
|
public void Dispose()
|
||
|
{
|
||
|
// Not already disposed?
|
||
|
if(!isdisposed)
|
||
|
{
|
||
|
// Done
|
||
|
isdisposed = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region ================== Methods
|
||
|
|
||
|
// This sets up vertices for a specific character
|
||
|
// also advances vertsoffset and textx
|
||
|
public void SetupVertices(DataStream stream, byte c, float scale, int color,
|
||
|
ref float textx, float texty, float textheight, float offsetv)
|
||
|
{
|
||
|
FlatVertex vert = new FlatVertex();
|
||
|
FontCharacter cinfo;
|
||
|
float cwidth;
|
||
|
|
||
|
// Get the character information
|
||
|
cinfo = characters[c];
|
||
|
cwidth = cinfo.width * scale;
|
||
|
|
||
|
// Create lefttop vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u1;
|
||
|
vert.v = cinfo.v1 * 0.5f + offsetv;
|
||
|
vert.x = textx;
|
||
|
vert.y = texty;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
// Create leftbottom vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u1;
|
||
|
vert.v = cinfo.v2 * 0.5f + offsetv;
|
||
|
vert.x = textx;
|
||
|
vert.y = texty + textheight;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
// Create righttop vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u2;
|
||
|
vert.v = cinfo.v1 * 0.5f + offsetv;
|
||
|
vert.x = textx + cwidth;
|
||
|
vert.y = texty;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
// Create leftbottom vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u1;
|
||
|
vert.v = cinfo.v2 * 0.5f + offsetv;
|
||
|
vert.x = textx;
|
||
|
vert.y = texty + textheight;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
// Create righttop vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u2;
|
||
|
vert.v = cinfo.v1 * 0.5f + offsetv;
|
||
|
vert.x = textx + cwidth;
|
||
|
vert.y = texty;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
// Create rightbottom vertex
|
||
|
vert.c = color;
|
||
|
vert.u = cinfo.u2;
|
||
|
vert.v = cinfo.v2 * 0.5f + offsetv;
|
||
|
vert.x = textx + cwidth;
|
||
|
vert.y = texty + textheight;
|
||
|
stream.Write<FlatVertex>(vert);
|
||
|
|
||
|
textx += (cwidth + (ADJUST_SPACING * scale));
|
||
|
}
|
||
|
|
||
|
// This checks if the given character exists in the charset
|
||
|
public bool Contains(char c)
|
||
|
{
|
||
|
// Convert character to ASCII
|
||
|
byte[] keybyte = Encoding.ASCII.GetBytes(c.ToString());
|
||
|
return Contains(keybyte[0]);
|
||
|
}
|
||
|
|
||
|
// This checks if the given character exists in the charset
|
||
|
public bool Contains(byte b)
|
||
|
{
|
||
|
// Check if the character has been set
|
||
|
return ((characters[b].width > 0.000000001f) ||
|
||
|
(characters[b].height > 0.000000001f));
|
||
|
}
|
||
|
|
||
|
// This calculates the size of a text string at a given scale
|
||
|
public SizeF GetTextSize(string text, float scale)
|
||
|
{
|
||
|
// Size items
|
||
|
float sizex = 0, sizey = 0;
|
||
|
|
||
|
// Get the ASCII bytes for the text
|
||
|
byte[] btext = Encoding.ASCII.GetBytes(text);
|
||
|
|
||
|
// Go for all chars in text to calculate final text size
|
||
|
foreach(byte b in btext)
|
||
|
{
|
||
|
// Add to the final size
|
||
|
sizex += characters[b].width * scale;
|
||
|
sizey = characters[b].height * scale;
|
||
|
}
|
||
|
|
||
|
// Return size
|
||
|
return new SizeF(sizex, sizey);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
}
|