mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
361 lines
16 KiB
C#
361 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Orvid.Graphics.FontSupport.bdf
|
|
{
|
|
public class BDFParser
|
|
{
|
|
#region Dep classes
|
|
public class Dimension
|
|
{
|
|
public int width, height;
|
|
public void setSize(int w, int h)
|
|
{
|
|
width = w;
|
|
height = h;
|
|
}
|
|
}
|
|
|
|
public class Rectangle
|
|
{
|
|
public int x, y, width, height;
|
|
|
|
public Rectangle() { }
|
|
public Rectangle(Rectangle rect)
|
|
{
|
|
setBounds(rect.x, rect.y, rect.width, rect.height);
|
|
}
|
|
|
|
public void setBounds(int x, int y, int w, int h)
|
|
{
|
|
this.x = x;
|
|
this.y = y;
|
|
this.width = w;
|
|
this.height = h;
|
|
}
|
|
}
|
|
|
|
public class Version
|
|
{
|
|
private int major;
|
|
private int minor;
|
|
|
|
public Version()
|
|
{
|
|
}
|
|
|
|
public void setVersion(int major, int minor)
|
|
{
|
|
this.major = major;
|
|
this.minor = minor;
|
|
}
|
|
|
|
public int getMajor()
|
|
{
|
|
return major;
|
|
}
|
|
|
|
public int getMinor()
|
|
{
|
|
return minor;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return major + "." + minor;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
StreamReader inStream;
|
|
|
|
#region Actual Implementation
|
|
public BDFFontContainer CreateFont()
|
|
{
|
|
return LoadFont();
|
|
}
|
|
|
|
public BDFFontContainer LoadFont()
|
|
{
|
|
BDFFontContainer font = null;
|
|
int[] version = null;
|
|
List<String> comments = new List<string>();
|
|
String[] fontName = null;
|
|
int[] size = null;
|
|
int[] bBox = null;
|
|
int contentVersion = 0;
|
|
int metrics = 0;
|
|
List<String> properties = new List<string>();
|
|
List<BDFGlyph> chars = new List<BDFGlyph>();
|
|
FontStyle style = FontStyle.Normal;
|
|
string s = "";
|
|
|
|
s = inStream.ReadLine();
|
|
if (s.Substring(0, 9).ToLower() == "startfont")
|
|
{
|
|
version = new int[2];
|
|
version[0] = int.Parse(s.Substring(10, 1));
|
|
version[1] = int.Parse(s.Substring(12, 1));
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Unable to find start of the font");
|
|
}
|
|
while (!inStream.EndOfStream)
|
|
{
|
|
System.GC.Collect();
|
|
s = inStream.ReadLine();
|
|
if (s.Length > 4)
|
|
{
|
|
if (s.Substring(0, 4).ToLower() == "size")
|
|
{
|
|
string[] s2 = s.Substring(5).Split(new char[] { ' ' });
|
|
size = new int[4];
|
|
if (s2.Length == 3)
|
|
{
|
|
size[3] = 1;
|
|
}
|
|
else
|
|
{
|
|
size[3] = int.Parse(s2[3]);
|
|
}
|
|
size[0] = int.Parse(s2[0]);
|
|
size[1] = int.Parse(s2[1]);
|
|
size[2] = int.Parse(s2[2]);
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 4).ToLower() == "font")
|
|
{
|
|
if (s.Substring(4, 1) == " ") // font command
|
|
{
|
|
fontName = new string[14];
|
|
String[] split = s.Trim().Split(new char[] { '-' });
|
|
Array.Copy(split, 1, fontName, 0, split.Length - 2);
|
|
continue;
|
|
}
|
|
else if (s.Length > 15)
|
|
{
|
|
if (s.Substring(0, 15).ToLower() == "fontboundingbox")
|
|
{
|
|
string[] s2 = s.Substring(16).Split(new char[] { ' ' });
|
|
bBox = new int[4];
|
|
if (s2.Length != 4)
|
|
{
|
|
throw new Exception("Unknown formatting!");
|
|
}
|
|
bBox[0] = int.Parse(s2[0]);
|
|
bBox[1] = int.Parse(s2[1]);
|
|
bBox[2] = int.Parse(s2[2]);
|
|
bBox[3] = int.Parse(s2[3]);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else if (s.Length > 5)
|
|
{
|
|
if (s.Substring(0, 5).ToLower() == "chars")
|
|
{
|
|
int chrs = int.Parse(s.Substring(6));
|
|
StringBuilder sb;
|
|
|
|
for (uint i = 0; i < chrs; i++)
|
|
{
|
|
System.GC.Collect();
|
|
s = inStream.ReadLine();
|
|
BDFGlyph g = null;
|
|
|
|
if (s.Length < 9 || s.Substring(0, 9).ToLower() != "startchar")
|
|
{
|
|
throw new Exception("Expected StartChar, but didn't get it");
|
|
}
|
|
g = new BDFGlyph(s.Substring(10));
|
|
while (true)
|
|
{
|
|
s = inStream.ReadLine();
|
|
if (s.Length > 3)
|
|
{
|
|
if (s.Substring(0, 3).ToLower() == "bbx")
|
|
{
|
|
string[] strs = s.Substring(4).Split(new char[] { ' ' });
|
|
if (strs.Length != 4)
|
|
{
|
|
throw new Exception("Error when loading bbx!");
|
|
}
|
|
g.setBBX(int.Parse(strs[2]), int.Parse(strs[3]), int.Parse(strs[0]), int.Parse(strs[1]));
|
|
continue;
|
|
}
|
|
else if (s.Length >= 6)
|
|
{
|
|
if (s.Substring(0, 6).ToLower() == "swidth")
|
|
{
|
|
string[] s2 = s.Substring(7).Split(new char[] { ' ' });
|
|
if (s2.Length != 2)
|
|
{
|
|
throw new Exception("Error when loading swidth!");
|
|
}
|
|
g.setSWidth(int.Parse(s2[0]), int.Parse(s2[1]));
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 6).ToLower() == "dwidth")
|
|
{
|
|
string[] s2 = s.Substring(7).Split(new char[] { ' ' });
|
|
if (s2.Length != 2)
|
|
{
|
|
throw new Exception("Error when loading dwidth!");
|
|
}
|
|
g.setDWidth(int.Parse(s2[0]), int.Parse(s2[1]));
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 6).ToLower() == "bitmap")
|
|
{
|
|
s = inStream.ReadLine();
|
|
sb = new StringBuilder(200);
|
|
if (s.Length == 2)
|
|
{
|
|
while (s.Length == 2)
|
|
{
|
|
sb.Append(s);
|
|
s = inStream.ReadLine();
|
|
}
|
|
}
|
|
else if (s.Length == 4)
|
|
{
|
|
while (s.Length == 4)
|
|
{
|
|
sb.Append(s);
|
|
s = inStream.ReadLine();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Unknown depth");
|
|
}
|
|
|
|
g.setRawData(sb.ToString());
|
|
if (s.ToLower() != "endchar")
|
|
{
|
|
throw new Exception("Unknown end to the bitmap");
|
|
}
|
|
break;
|
|
}
|
|
else if (s.Length > 7)
|
|
{
|
|
if (s.Substring(0, 7).ToLower() == "vvector")
|
|
{
|
|
// We don't take this into account.
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 7).ToLower() == "dwidth1")
|
|
{
|
|
// We don't take this into account.
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 7).ToLower() == "swidth1")
|
|
{
|
|
// We don't take this into account.
|
|
continue;
|
|
}
|
|
else if (s.Substring(0, 7).ToLower() == "endchar")
|
|
{
|
|
throw new Exception("ERROR: Character didn't include a bitmap!");
|
|
}
|
|
else if (s.Length > 8)
|
|
{
|
|
if (s.Substring(0, 8).ToLower() == "encoding")
|
|
{
|
|
g.encoding = int.Parse(s.Substring(9));
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
throw new Exception("Unknown Property");
|
|
}
|
|
chars.Add(g);
|
|
}
|
|
|
|
if (inStream.ReadLine().ToLower() != "endfont")
|
|
{
|
|
throw new Exception("Error when loading chars, missing endfont message.");
|
|
}
|
|
break;
|
|
}
|
|
else if (s.Length > 7)
|
|
{
|
|
if (s.Substring(0, 7).ToLower() == "comment")
|
|
{
|
|
comments.Add(s.Substring(9, (s.Length - 10)));
|
|
continue;
|
|
}
|
|
else if (s.Length > 10)
|
|
{
|
|
if (s.Substring(0, 10).ToLower() == "metricset")
|
|
{
|
|
metrics = int.Parse(s.Substring(11,1));
|
|
continue;
|
|
}
|
|
else if (s.Length > 14)
|
|
{
|
|
if (s.Substring(0, 14).ToLower() == "contentversion")
|
|
{
|
|
contentVersion = int.Parse(s.Substring(15));
|
|
continue;
|
|
}
|
|
else if (s.Length > 15)
|
|
{
|
|
if (s.Substring(0, 15).ToLower() == "startproperties")
|
|
{
|
|
int props = int.Parse(s.Substring(16));
|
|
for (uint i = 0; i < props; i++)
|
|
{
|
|
properties.Add(inStream.ReadLine());
|
|
}
|
|
s = inStream.ReadLine();
|
|
if (s.ToLower() != "endproperties")
|
|
{
|
|
throw new Exception("An error occured while loading properties!");
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
throw new Exception("Unknown command");
|
|
}
|
|
|
|
if ("i".Equals(fontName[BDFFontContainer.SLANT], StringComparison.InvariantCultureIgnoreCase) ||
|
|
"o".Equals(fontName[BDFFontContainer.SLANT], StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
style = FontStyle.Italic;
|
|
}
|
|
if ("bold".Equals(fontName[BDFFontContainer.WEIGHT], StringComparison.InvariantCultureIgnoreCase))
|
|
style |= FontStyle.Bold;
|
|
|
|
font = new BDFFontContainer(fontName, style, size[0]);
|
|
font.setBoundingBox(bBox[0], bBox[1], bBox[2], bBox[3]);
|
|
font.setResolution(size[1], size[2]);
|
|
font.setComments(comments.ToArray());
|
|
font.setProperties(properties.ToArray());
|
|
|
|
if (size != null && size.Length == 4)
|
|
font.setDepth(size[3]);
|
|
|
|
font.setGlyphs(chars.ToArray());
|
|
return font;
|
|
}
|
|
#endregion
|
|
|
|
|
|
public BDFParser(System.IO.Stream stream)
|
|
{
|
|
inStream = new StreamReader(stream, System.Text.ASCIIEncoding.ASCII);
|
|
}
|
|
}
|
|
}
|