mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 14:02:19 +00:00
241 lines
7.8 KiB
C#
241 lines
7.8 KiB
C#
/* This file will eventually hold an implementation
|
|
* of the Orvid Precompiled Font Format. The use of
|
|
* this format is to provide a much easier to
|
|
* implement format for loading fonts. It is meant
|
|
* to eliminate the Pre-Rendering step required
|
|
* for most current font formats. It will achieve
|
|
* this by using a bit-based format, where each bit
|
|
* will represent a single pixel. It will also merge
|
|
* the multiple files required for Bold, Italic, and
|
|
* other such formatting, support, into a single
|
|
* file.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace Orvid.Graphics.FontSupport
|
|
{
|
|
public class OPFF : Font
|
|
{
|
|
private string name;
|
|
public override string Name
|
|
{
|
|
get { return name; }
|
|
}
|
|
|
|
FontCharacterSet foundChars = new FontCharacterSet();
|
|
|
|
public OPFF(byte[] data)
|
|
{
|
|
Load(data);
|
|
}
|
|
|
|
private UInt64 ReadUInt64(byte[] data)
|
|
{
|
|
UInt64 r = 0;
|
|
|
|
r += data[7];
|
|
r <<= 8;
|
|
r += data[6];
|
|
r <<= 8;
|
|
r += data[5];
|
|
r <<= 8;
|
|
r += data[4];
|
|
r <<= 8;
|
|
r += data[3];
|
|
r <<= 8;
|
|
r += data[2];
|
|
r <<= 8;
|
|
r += data[1];
|
|
r <<= 8;
|
|
r += data[0];
|
|
|
|
return r;
|
|
}
|
|
|
|
private UInt32 ReadInt32(byte[] data)
|
|
{
|
|
UInt32 r = 0;
|
|
|
|
r += data[3];
|
|
r <<= 8;
|
|
r += data[2];
|
|
r <<= 8;
|
|
r += data[1];
|
|
r <<= 8;
|
|
r += data[0];
|
|
|
|
return r;
|
|
}
|
|
|
|
private void Load(byte[] data)
|
|
{
|
|
if (data[0] == 0xFF) // this means it's been compressed in LZMA format.
|
|
{
|
|
byte[] tmp = new byte[data.Length - 1];
|
|
Array.Copy(data, 1, tmp, 0, tmp.Length);
|
|
data = Orvid.Compression.LZMA.Decompress(tmp);
|
|
tmp = null;
|
|
}
|
|
|
|
int curloc = 8; // There are 8 empty bytes at the start of the header.
|
|
|
|
byte[] datarr = new byte[256];
|
|
Array.Copy(data, curloc, datarr, 0, 256);
|
|
curloc += 256;
|
|
name = new String(ASCIIEncoding.ASCII.GetChars(datarr));
|
|
|
|
datarr = new byte[8];
|
|
Array.Copy(data, curloc, datarr, 0, 8);
|
|
curloc += 8;
|
|
UInt64 charsToRead = ReadUInt64(datarr);
|
|
|
|
UInt32 prevCharNumber = 0;
|
|
for (UInt64 i = 0; i < charsToRead; i++)
|
|
{
|
|
// Check if the character number is incremented from the last item.
|
|
if (data[curloc] == 255) // this means increment it.
|
|
{
|
|
curloc++;
|
|
prevCharNumber++;
|
|
FontFlag flags = (FontFlag)data[curloc];
|
|
curloc++;
|
|
byte height = data[curloc];
|
|
curloc++;
|
|
byte width = data[curloc];
|
|
curloc++;
|
|
int len = (Int32)Math.Ceiling((double)((width * height) / 8));
|
|
datarr = new byte[len];
|
|
Array.Copy(data, curloc, datarr, 0, len);
|
|
curloc += len;
|
|
Image im = LoadFromBinary(datarr, height, width);
|
|
if (prevCharNumber > ushort.MaxValue)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
foundChars.AddCharacter((int)prevCharNumber, im, flags);
|
|
}
|
|
else
|
|
{
|
|
curloc++;
|
|
datarr = new byte[4];
|
|
Array.Copy(data, curloc, datarr, 0, 4);
|
|
curloc += 4;
|
|
prevCharNumber = ReadInt32(datarr);
|
|
if (prevCharNumber > ushort.MaxValue)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
FontFlag flags = (FontFlag)data[curloc];
|
|
curloc++;
|
|
byte height = data[curloc];
|
|
curloc++;
|
|
byte width = data[curloc];
|
|
curloc++;
|
|
int len = (Int32)Math.Ceiling((double)((width * height) / 8));
|
|
datarr = new byte[len];
|
|
Array.Copy(data, curloc, datarr, 0, len);
|
|
curloc += len;
|
|
Image im = LoadFromBinary(datarr, height, width);
|
|
foundChars.AddCharacter((int)prevCharNumber, im, flags);
|
|
}
|
|
}
|
|
}
|
|
|
|
private Image LoadFromBinary(byte[] data, byte height, byte width)
|
|
{
|
|
#region LoadData
|
|
bool[] idata = new bool[height * width];
|
|
int bitnum = 0;
|
|
for (int inc = 0; inc < data.Length; inc++)
|
|
{
|
|
//int a1 = (data[inc] >> 7);
|
|
//int a2 = ((byte)(data[inc] << 1) >> 7);
|
|
//int a3 = ((byte)(data[inc] << 2) >> 7);
|
|
//int a4 = ((byte)(data[inc] << 3) >> 7);
|
|
//int a5 = ((byte)(data[inc] << 4) >> 7);
|
|
//int a6 = ((byte)(data[inc] << 5) >> 7);
|
|
//int a7 = ((byte)(data[inc] << 6) >> 7);
|
|
//int a8 = ((byte)(data[inc] << 7) >> 7);
|
|
|
|
//int aFinal = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
|
|
//if (aFinal >= 8)
|
|
//{
|
|
// throw new Exception();
|
|
//}
|
|
|
|
if (((byte)(data[inc] << 7) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 6) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 5) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 4) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 3) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 2) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if (((byte)(data[inc] << 1) >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
if ((data[inc] >> 7) == 1)
|
|
{
|
|
idata[bitnum] = true;
|
|
}
|
|
bitnum++;
|
|
}
|
|
#endregion
|
|
|
|
bitnum = 0;
|
|
Image i = new Image(width, height);
|
|
|
|
//for (uint y = 0; y < height; y++)
|
|
for (uint x = 0; x < width; x++)
|
|
{
|
|
//for (uint x = 0; x < width; x++)
|
|
for (uint y = 0; y < height; y++)
|
|
{
|
|
if (idata[bitnum])
|
|
{
|
|
i.SetPixel(x, y, Colors.Black); // Color the pixel white
|
|
}
|
|
else
|
|
{
|
|
i.SetPixel(x, y, Colors.White); // Color the pixel black
|
|
}
|
|
bitnum++;
|
|
}
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
public override Image GetCharacter(Int32 charNumber, FontFlag flags)
|
|
{
|
|
return foundChars.GetCharacter(charNumber, flags);
|
|
}
|
|
}
|
|
}
|