Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
272
Ultima/UnicodeFont.cs
Normal file
272
Ultima/UnicodeFont.cs
Normal file
@@ -0,0 +1,272 @@
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
#endregion
|
||||
|
||||
namespace Ultima
|
||||
{
|
||||
public sealed class UnicodeFont
|
||||
{
|
||||
public UnicodeChar[] Chars { get; set; }
|
||||
|
||||
public UnicodeFont()
|
||||
{
|
||||
Chars = new UnicodeChar[0x10000];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns width of text
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public int GetWidth(string text)
|
||||
{
|
||||
if (text == null || text.Length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int width = 0;
|
||||
for (int i = 0; i < text.Length; ++i)
|
||||
{
|
||||
int c = text[i] % 0x10000;
|
||||
width += Chars[c].Width;
|
||||
width += Chars[c].XOffset;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns max height of text
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public int GetHeight(string text)
|
||||
{
|
||||
if (text == null || text.Length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int height = 0;
|
||||
for (int i = 0; i < text.Length; ++i)
|
||||
{
|
||||
int c = text[i] % 0x10000;
|
||||
height = Math.Max(height, Chars[c].Height + Chars[c].YOffset);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UnicodeChar
|
||||
{
|
||||
public byte[] Bytes { get; set; }
|
||||
public sbyte XOffset { get; set; }
|
||||
public sbyte YOffset { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets Bitmap of Char
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Bitmap GetImage()
|
||||
{
|
||||
return GetImage(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Bitmap of Char with Background -1
|
||||
/// </summary>
|
||||
/// <param name="fill"></param>
|
||||
/// <returns></returns>
|
||||
public unsafe Bitmap GetImage(bool fill)
|
||||
{
|
||||
if ((Width == 0) || (Height == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var bmp = new Bitmap(Width, Height, Settings.PixelFormat);
|
||||
BitmapData bd = bmp.LockBits(
|
||||
new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, Settings.PixelFormat);
|
||||
var line = (ushort*)bd.Scan0;
|
||||
int delta = bd.Stride >> 1;
|
||||
for (int y = 0; y < Height; ++y, line += delta)
|
||||
{
|
||||
ushort* cur = line;
|
||||
for (int x = 0; x < Width; ++x)
|
||||
{
|
||||
if (IsPixelSet(Bytes, Width, x, y))
|
||||
{
|
||||
cur[x] = 0x8000;
|
||||
}
|
||||
else if (fill)
|
||||
{
|
||||
cur[x] = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
bmp.UnlockBits(bd);
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private static bool IsPixelSet(byte[] data, int width, int x, int y)
|
||||
{
|
||||
int offset = x / 8 + y * ((width + 7) / 8);
|
||||
if (offset > data.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (data[offset] & (1 << (7 - (x % 8)))) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets Buffer with Bitmap
|
||||
/// </summary>
|
||||
/// <param name="bmp"></param>
|
||||
public unsafe void SetBuffer(Bitmap bmp)
|
||||
{
|
||||
Bytes = new byte[bmp.Height * (((bmp.Width - 1) / 8) + 1)];
|
||||
BitmapData bd = bmp.LockBits(
|
||||
new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, Settings.PixelFormat);
|
||||
var line = (ushort*)bd.Scan0;
|
||||
//int delta = bd.Stride >> 1;
|
||||
for (int y = 0; y < bmp.Height; ++y)
|
||||
{
|
||||
ushort* cur = line;
|
||||
for (int x = 0; x < bmp.Width; ++x)
|
||||
{
|
||||
if (cur[x] == 0x8000)
|
||||
{
|
||||
int offset = x / 8 + y * ((bmp.Width + 7) / 8);
|
||||
Bytes[offset] |= (byte)(1 << (7 - (x % 8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
bmp.UnlockBits(bd);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnicodeFonts
|
||||
{
|
||||
private static readonly string[] m_files = new[]
|
||||
{
|
||||
"unifont.mul", "unifont1.mul", "unifont2.mul", "unifont3.mul", "unifont4.mul", "unifont5.mul", "unifont6.mul",
|
||||
"unifont7.mul", "unifont8.mul", "unifont9.mul", "unifont10.mul", "unifont11.mul", "unifont12.mul"
|
||||
};
|
||||
|
||||
public static UnicodeFont[] Fonts = new UnicodeFont[13];
|
||||
|
||||
static UnicodeFonts()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads unifont*.mul
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
for (int i = 0; i < m_files.Length; i++)
|
||||
{
|
||||
string filePath = Files.GetFilePath(m_files[i]);
|
||||
if (filePath == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Fonts[i] = new UnicodeFont();
|
||||
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
using (var bin = new BinaryReader(fs))
|
||||
{
|
||||
for (int c = 0; c < 0x10000; ++c)
|
||||
{
|
||||
Fonts[i].Chars[c] = new UnicodeChar();
|
||||
fs.Seek(((c) * 4), SeekOrigin.Begin);
|
||||
int num2 = bin.ReadInt32();
|
||||
if ((num2 >= fs.Length) || (num2 <= 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fs.Seek(num2, SeekOrigin.Begin);
|
||||
sbyte xOffset = bin.ReadSByte();
|
||||
sbyte yOffset = bin.ReadSByte();
|
||||
int Width = bin.ReadByte();
|
||||
int Height = bin.ReadByte();
|
||||
Fonts[i].Chars[c].XOffset = xOffset;
|
||||
Fonts[i].Chars[c].YOffset = yOffset;
|
||||
Fonts[i].Chars[c].Width = Width;
|
||||
Fonts[i].Chars[c].Height = Height;
|
||||
if (!((Width == 0) || (Height == 0)))
|
||||
{
|
||||
Fonts[i].Chars[c].Bytes = bin.ReadBytes(Height * (((Width - 1) / 8) + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws Text with font in Bitmap and returns
|
||||
/// </summary>
|
||||
/// <param name="fontId"></param>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap WriteText(int fontId, string text)
|
||||
{
|
||||
var result = new Bitmap(Fonts[fontId].GetWidth(text) + 2, Fonts[fontId].GetHeight(text) + 2);
|
||||
|
||||
int dx = 2;
|
||||
int dy = 2;
|
||||
using (Graphics graph = Graphics.FromImage(result))
|
||||
{
|
||||
for (int i = 0; i < text.Length; ++i)
|
||||
{
|
||||
int c = text[i] % 0x10000;
|
||||
Bitmap bmp = Fonts[fontId].Chars[c].GetImage();
|
||||
dx += Fonts[fontId].Chars[c].XOffset;
|
||||
graph.DrawImage(bmp, dx, dy + Fonts[fontId].Chars[c].YOffset);
|
||||
dx += bmp.Width;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves Font and returns string Filename
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="filetype"></param>
|
||||
/// <returns></returns>
|
||||
public static string Save(string path, int filetype)
|
||||
{
|
||||
string FileName = Path.Combine(path, m_files[filetype]);
|
||||
using (var fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write))
|
||||
{
|
||||
using (var bin = new BinaryWriter(fs))
|
||||
{
|
||||
fs.Seek(0x10000 * 4, SeekOrigin.Begin);
|
||||
bin.Write(0);
|
||||
// Set first data
|
||||
for (int c = 0; c < 0x10000; ++c)
|
||||
{
|
||||
if (Fonts[filetype].Chars[c].Bytes == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fs.Seek(((c) * 4), SeekOrigin.Begin);
|
||||
bin.Write((int)fs.Length);
|
||||
fs.Seek(fs.Length, SeekOrigin.Begin);
|
||||
bin.Write(Fonts[filetype].Chars[c].XOffset);
|
||||
bin.Write(Fonts[filetype].Chars[c].YOffset);
|
||||
bin.Write((byte)Fonts[filetype].Chars[c].Width);
|
||||
bin.Write((byte)Fonts[filetype].Chars[c].Height);
|
||||
bin.Write(Fonts[filetype].Chars[c].Bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user