/* 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[0]; r <<= 8; r += data[1]; r <<= 8; r += data[2]; r <<= 8; r += data[3]; r <<= 8; r += data[4]; r <<= 8; r += data[5]; r <<= 8; r += data[6]; r <<= 8; r += data[7]; return r; } private Int32 ReadInt32(byte[] data) { Int32 r = 0; r += data[0]; r <<= 8; r += data[1]; r <<= 8; r += data[2]; r <<= 8; r += data[3]; r <<= 8; return r; } private void Load(byte[] data) { 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); Int32 prevCharNumber = 0; for (UInt64 i = 0; i < charsToRead; i++) { // Check if the character number is incremented from the last item. if ((data[curloc] & 1) == 1) // 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); foundChars.AddCharacter(prevCharNumber, im, flags); } else { curloc++; datarr = new byte[4]; Array.Copy(data, curloc, datarr, 0, 4); curloc += 4; prevCharNumber = ReadInt32(datarr); 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(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++) { if ((data[inc] & 1) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 2) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 3) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 4) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 5) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 6) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 7) == 1) { idata[bitnum] = true; } bitnum++; if ((data[inc] & 8) == 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++) { if (idata[bitnum]) { i.SetPixel(x, y, Colors.White); // Color the pixel white } else { i.SetPixel(x, y, Colors.Black); // Color the pixel black } bitnum++; } } return i; } public override Image GetCharacter(Int32 charNumber, FontFlag flags) { return foundChars.GetCharacter(charNumber, flags); } } }