public UOChar(UOEncoding enc, sbyte ox, sbyte oy, Bitmap image) { Encoding = enc; XOffset = ox; YOffset = oy; Image = image; Width = (byte)Image.Width; Height = (byte)Image.Height; }
public static UOFont GetFont(UOEncoding enc, byte id) { switch (enc) { case UOEncoding.Ascii: return(LoadAscii(id)); case UOEncoding.Unicode: return(LoadUnicode(id)); } return(null); }
private static UOFont Instantiate(UOEncoding enc, byte id) { int charsWidth = 0, charsHeight = 0; var list = _Chars[(byte)enc][id]; var i = list.Length; while (--i >= 0) { charsWidth = Math.Max(charsWidth, list[i].XOffset + list[i].Width); charsHeight = Math.Max(charsHeight, list[i].YOffset + list[i].Height); } return(new UOFont(enc, id, 1, 4, (byte)charsWidth, (byte)charsHeight, list)); }
public UOFont( UOEncoding enc, byte id, byte charSpacing, byte lineSpacing, byte charsWidth, byte charsHeight, UOChar[] chars) { Encoding = enc; ID = id; CharSpacing = charSpacing; LineSpacing = lineSpacing; MaxCharWidth = charsWidth; MaxCharHeight = charsHeight; Chars = chars; }
public UOFonts(UOEncoding enc) { Encoding = enc; switch (Encoding) { case UOEncoding.Ascii: { Count = _Ascii.Length; DefaultID = 3; } break; case UOEncoding.Unicode: { Count = _Unicode.Length; DefaultID = 1; } break; } }
private static UOFont LoadAscii(byte id) { if (id >= _Ascii.Length) { return(null); } const UOEncoding enc = UOEncoding.Ascii; var idx = (byte)enc; if (_Chars.InBounds(idx, id) && _Chars[idx][id] != null) { return(_Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id))); } var fonts = _Chars[idx] ?? (_Chars[idx] = new UOChar[_Ascii.Length][]); var chars = fonts[id] ?? (fonts[id] = new UOChar[256]); var path = Core.FindDataFile("fonts.mul"); if (path == null || !File.Exists(path)) { chars.SetAll(NewEmptyChar(enc)); return(_Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id))); } using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { using (var bin = new BinaryReader(fs)) { for (var i = 0; i <= id; i++) { bin.ReadByte(); // header if (i == id) { for (var c = 0; c < 32; c++) { chars[c] = NewEmptyChar(enc); } } for (var c = 32; c < chars.Length; c++) { var width = bin.ReadByte(); var height = bin.ReadByte(); bin.ReadByte(); // unk if (i == id) { var buffer = _EmptyBuffer; if (width * height > 0) { buffer = bin.ReadBytes((width * height) * 2); } chars[c] = new UOChar(enc, 0, 0, GetImage(width, height, buffer, enc)); } else { bin.BaseStream.Seek((width * height) * 2, SeekOrigin.Current); } } } } } return(_Ascii[id] ?? (_Ascii[id] = Instantiate(enc, id))); }
private static UOChar NewEmptyChar(UOEncoding enc) { return(new UOChar(enc, 0, 0, NewEmptyImage())); }
public static UOFont GetFont(UOEncoding enc, byte id) { return(UOFonts.GetFont(enc, id)); }
private static unsafe Bitmap GetImage(int width, int height, byte[] buffer, UOEncoding enc) { if (width * height <= 0 || buffer.IsNullOrEmpty()) { return(NewEmptyImage()); } var image = new Bitmap(width, height, UOFont.PixelFormat); var bound = new Rectangle(0, 0, width, height); var data = image.LockBits(bound, ImageLockMode.WriteOnly, UOFont.PixelFormat); var index = 0; var line = (ushort *)data.Scan0; var delta = data.Stride >> 1; int x, y; ushort pixel; for (y = 0; y < height; y++, line += delta) { var cur = line; if (cur == null) { continue; } for (x = 0; x < width; x++) { pixel = 0; if (enc > 0) { index = x / 8 + y * ((width + 7) / 8); } if (index < buffer.Length) { if (enc > 0) { pixel = buffer[index]; } else { pixel = (ushort)(buffer[index++] | (buffer[index++] << 8)); } } if (enc > 0) { pixel &= (ushort)(1 << (7 - (x % 8))); } if (pixel == 0) { cur[x] = 0; } else if (enc > 0) { cur[x] = 0x8000; } else { cur[x] = (ushort)(pixel ^ 0x8000); } } } image.UnlockBits(data); return(image); }
private static UOFont LoadUnicode(byte id) { if (id >= _Unicode.Length) { return(null); } const UOEncoding enc = UOEncoding.Unicode; var idx = (byte)enc; if (_Chars.InBounds(idx, id) && _Chars[idx][id] != null) { return(_Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id))); } var fonts = _Chars[idx] ?? (_Chars[idx] = new UOChar[_Unicode.Length][]); var chars = fonts[id] ?? (fonts[id] = new UOChar[65536]); var filePath = Core.FindDataFile("unifont{0:#}.mul", id); if (filePath == null) { chars.SetAll(NewEmptyChar(enc)); return(_Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id))); } using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { using (var bin = new BinaryReader(fs)) { for (int c = 0, o; c < chars.Length; c++) { fs.Seek(c * 4, SeekOrigin.Begin); o = bin.ReadInt32(); if (o <= 0 || o >= fs.Length) { chars[c] = NewEmptyChar(enc); continue; } fs.Seek(o, SeekOrigin.Begin); var x = bin.ReadSByte(); // x-offset var y = bin.ReadSByte(); // y-offset var width = bin.ReadByte(); var height = bin.ReadByte(); var buffer = _EmptyBuffer; if (width * height > 0) { buffer = bin.ReadBytes(height * (((width - 1) / 8) + 1)); } chars[c] = new UOChar(enc, x, y, GetImage(width, height, buffer, enc)); } } } return(_Unicode[id] ?? (_Unicode[id] = Instantiate(enc, id))); }