public int FindASCIIOffset(byte aI) { int offset; for (offset = 0; offset < _UnicodeMappings.Count; offset++) { UnicodeMapping mapping = _UnicodeMappings[offset]; if (mapping.ASCIICharacters.Contains(aI)) { break; } } return(offset); }
public static PCScreenFont LoadFont(byte[] aFontData) { byte CharHeight; byte CharWidth; byte[] FontData; var UnicodeMappings = new List <UnicodeMapping>(); bool version1 = aFontData[0] == 0x36 && aFontData[1] == 0x04; bool version2 = BitConverter.ToUInt32(aFontData, 0) == 0x864ab572; //Check the header if (!version1 && !version2) { Global.mDebugger.Send($"Invalid magic {aFontData[0]} {aFontData[1]} {aFontData[2]} {aFontData[3]}"); throw new Exception($"Invalid magic {aFontData[0]} {aFontData[1]} {aFontData[2]} {aFontData[3]}"); } if (version1) { byte mode = aFontData[2]; CharHeight = aFontData[3]; CharWidth = 8; //Always 8 in this case int length = (mode & (int)PSFVersion1Mode.MODE512) == 1 ? 512 : 256; bool hasUnicodeTable = (mode & (int)PSFVersion1Mode.HASTAB) > 0; ushort seperator = 0xFFFF; ushort sequenceStart = 0xFFFE; FontData = new byte[length * CharHeight]; //Every row is one byte for (int i = 0; i < length; i++) { for (int k = 0; k < CharHeight; k++) { FontData[i * CharHeight + k] = aFontData[4 + i * CharHeight + k]; } } int position = 4 + length * CharHeight; if (hasUnicodeTable) { UnicodeMappings = new List <UnicodeMapping>(); var currentEntry = new List <byte>(); while (position < aFontData.Length) { if (BitConverter.ToUInt16(aFontData, position) == seperator) { var mapping = new UnicodeMapping { FontPosition = UnicodeMappings.Count, UnicodeCharacters = new List <ushort>(), UnicodeCharactersWithModifiers = new List <ushort[]>(), ASCIICharacters = new List <byte>() }; mapping.ASCIICharacters.Add((byte)mapping.FontPosition); for (int i = 0; i < currentEntry.Count / 2; i++) { mapping.UnicodeCharacters.Add(BitConverter.ToUInt16(currentEntry.ToArray(), i * 2)); } //At this point we filter combined unicode letters out of the unicode charactesr bool reachedFirstSeperator = false; var unicodeCombination = new List <ushort>(); int index = 0; while (index < mapping.UnicodeCharacters.Count) { if (mapping.UnicodeCharacters[index] == sequenceStart) { mapping.UnicodeCharacters.RemoveAt(index); if (!reachedFirstSeperator) { reachedFirstSeperator = true; } else { mapping.UnicodeCharactersWithModifiers.Add(unicodeCombination.ToArray()); } } else { if (reachedFirstSeperator) { unicodeCombination.Add(mapping.UnicodeCharacters[index]); mapping.UnicodeCharacters.RemoveAt(index); } else { index++; } } } // Now convert all the unicode characters we can to ASCII foreach (var uc in mapping.UnicodeCharacters) { byte ac = Encoding.ASCII.GetBytes(Encoding.Unicode.GetString(BitConverter.GetBytes(uc)))[0]; if (ac == 63 && uc != 0x003F) { //ignore } else { if (!mapping.ASCIICharacters.Contains(ac)) { mapping.ASCIICharacters.Add(ac); } } } UnicodeMappings.Add(mapping); currentEntry.Clear(); position++; //Skip the second seperator character as well } else { currentEntry.Add(aFontData[position]); } position++; } } return(new PCScreenFont(CharWidth, CharHeight, FontData, UnicodeMappings)); } if (version2) { throw new NotImplementedException(); } throw new ArgumentException(nameof(aFontData)); }