Пример #1
0
        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;
        }
Пример #2
0
        public static UOFont GetFont(UOEncoding enc, byte id)
        {
            switch (enc)
            {
            case UOEncoding.Ascii:
                return(LoadAscii(id));

            case UOEncoding.Unicode:
                return(LoadUnicode(id));
            }

            return(null);
        }
Пример #3
0
        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));
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
            }
        }
Пример #6
0
        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)));
        }
Пример #7
0
 private static UOChar NewEmptyChar(UOEncoding enc)
 {
     return(new UOChar(enc, 0, 0, NewEmptyImage()));
 }
Пример #8
0
 public static UOFont GetFont(UOEncoding enc, byte id)
 {
     return(UOFonts.GetFont(enc, id));
 }
Пример #9
0
        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);
        }
Пример #10
0
        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)));
        }