Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
114
Scripts/SubSystem/VitaNex/Core/Text/BBCodeUtility.cs
Normal file
114
Scripts/SubSystem/VitaNex/Core/Text/BBCodeUtility.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public static class BBCodeUtility
|
||||
{
|
||||
/*
|
||||
(Description) (Syntax) (Args) (Examples)
|
||||
Line Break: [br] [br]
|
||||
URL: [url] link [/url] [url]http://www.google.com[/url]
|
||||
URL Labeled: [url=arg] text [/url] hyperlink [url=http://www.google.com]Google Search[/url]
|
||||
Center Align: [center] text [/center] [center]Hello World[/center]
|
||||
Left Align: [left] text [/left] [left]Hello World[/left]
|
||||
Right Align: [right] text [/right] [right]Hello World[/right]
|
||||
Small Font: [small] text [/small] [small]Hello World[/small]
|
||||
Big Font: [big] text [/big] [big]Hello World[/big]
|
||||
Bold: [b] text [/b] [b]Hello World[/b]
|
||||
Italic: [i] text [/i] [i]Hello World[/i]
|
||||
Underline: [u] text [/u] [u]Hello World[/u]
|
||||
Strikeout: [s] text [/s] [s]Hello World[/s]
|
||||
Font Size: [size=arg] text [/size] int 1 - 4 [size=4]Hello World[/color]
|
||||
Font Color: [color=arg] text [/color] hex x6 [color=#FFFFFF]Hello World[/color]
|
||||
**********: ************************* named color [color=white]Hello World[/color]
|
||||
*/
|
||||
|
||||
public static RegexOptions DefaultRegexOptions = RegexOptions.IgnoreCase | RegexOptions.Singleline;
|
||||
|
||||
public static readonly Regex RegexLineBreak = new Regex(@"\[br\]", DefaultRegexOptions),
|
||||
RegexCenterText = new Regex(@"\[center\](.+?)\[\/center\]", DefaultRegexOptions),
|
||||
RegexLeftText = new Regex(@"\[left\](.+?)\[\/left\]", DefaultRegexOptions),
|
||||
RegexRightText = new Regex(@"\[right\](.+?)\[\/right\]", DefaultRegexOptions),
|
||||
RegexSmallText = new Regex(@"\[small\](.+?)\[\/small\]", DefaultRegexOptions),
|
||||
RegexBigText = new Regex(@"\[big\](.+?)\[\/big\]", DefaultRegexOptions),
|
||||
RegexBoldText = new Regex(@"\[b\](.+?)\[\/b\]", DefaultRegexOptions),
|
||||
RegexItalicText = new Regex(@"\[i\](.+?)\[\/i\]", DefaultRegexOptions),
|
||||
RegexUnderlineText = new Regex(@"\[u\](.+?)\[\/u\]", DefaultRegexOptions),
|
||||
RegexStrikeOutText = new Regex(@"\[s\](.+?)\[\/s\]", DefaultRegexOptions),
|
||||
RegexUrl = new Regex(@"\[url\](.+?)\[\/url\]", DefaultRegexOptions),
|
||||
RegexUrlAnchored = new Regex(@"\[url=([^\]]+)\]([^\]]+)\[\/url\]", DefaultRegexOptions),
|
||||
RegexColorAnchored = new Regex(@"\[color=([^\]]+)\]([^\]]+)\[\/color\]", DefaultRegexOptions),
|
||||
RegexSizeAnchored = new Regex(@"\[size=([^\]]+)\]([^\]]+)\[\/size\]", DefaultRegexOptions),
|
||||
RegexImage = new Regex(@"\[img\](.+?)\[\/img\]", DefaultRegexOptions),
|
||||
RegexImageAnchored = new Regex(@"\[img=([^\]]+)\]([^\]]+)\[\/img\]", DefaultRegexOptions),
|
||||
RegexStripMisc = new Regex(@"\[([^\]]+)\]([^\]]+)\[\/[^\]]+\]", DefaultRegexOptions);
|
||||
|
||||
public static string ParseBBCode(
|
||||
this string input,
|
||||
Color? defaultColor = null,
|
||||
int defaultSize = 2,
|
||||
bool imgAsLink = true,
|
||||
bool stripMisc = false)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
return input ?? String.Empty;
|
||||
}
|
||||
|
||||
input = RegexLineBreak.Replace(input, "<br>");
|
||||
input = RegexCenterText.Replace(input, "<center>$1</center>");
|
||||
input = RegexLeftText.Replace(input, "<left>$1</left>");
|
||||
input = RegexRightText.Replace(input, "<right>$1</right>");
|
||||
input = RegexSmallText.Replace(input, "<small>$1</small>");
|
||||
input = RegexBigText.Replace(input, "<big>$1</big>");
|
||||
input = RegexBoldText.Replace(input, "<b>$1</b>");
|
||||
input = RegexItalicText.Replace(input, "<i>$1</i>");
|
||||
input = RegexUnderlineText.Replace(input, "<u>$1</u>");
|
||||
input = RegexStrikeOutText.Replace(input, "<s>$1</s>");
|
||||
|
||||
input = RegexUrl.Replace(input, "<a href=\"$1\">$1</a>");
|
||||
input = RegexUrlAnchored.Replace(input, "<a href=\"$1\">$2</a>");
|
||||
|
||||
if (imgAsLink)
|
||||
{
|
||||
input = RegexImage.Replace(input, "<a href=\"$1\">$1</a>");
|
||||
input = RegexImageAnchored.Replace(input, "<a href=\"$1\">$2</a>");
|
||||
}
|
||||
|
||||
input = RegexSizeAnchored.Replace(input, "<basefont size=$1>$2<basefont size=" + defaultSize + ">");
|
||||
|
||||
if (defaultColor != null)
|
||||
{
|
||||
input = RegexColorAnchored.Replace(
|
||||
input,
|
||||
"<basefont color=$1>$2<basefont color=#" + defaultColor.Value.ToRgb().ToString("X6") + ">");
|
||||
}
|
||||
else
|
||||
{
|
||||
input = RegexColorAnchored.Replace(input, "<basefont color=$1>$2");
|
||||
}
|
||||
|
||||
if (stripMisc)
|
||||
{
|
||||
input = RegexStripMisc.Replace(input, "($1) $2");
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Scripts/SubSystem/VitaNex/Core/Text/Encoding.cs
Normal file
52
Scripts/SubSystem/VitaNex/Core/Text/Encoding.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Text;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public enum EncodingType
|
||||
{
|
||||
Default,
|
||||
ASCII,
|
||||
Unicode,
|
||||
BigEndianUnicode,
|
||||
UTF7,
|
||||
UTF8,
|
||||
UTF32
|
||||
}
|
||||
|
||||
public static class EncodingUtility
|
||||
{
|
||||
public static Encoding GetEncoding(this EncodingType e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case EncodingType.ASCII:
|
||||
return Encoding.ASCII;
|
||||
case EncodingType.Unicode:
|
||||
return Encoding.Unicode;
|
||||
case EncodingType.BigEndianUnicode:
|
||||
return Encoding.BigEndianUnicode;
|
||||
case EncodingType.UTF7:
|
||||
return Encoding.UTF7;
|
||||
case EncodingType.UTF8:
|
||||
return Encoding.UTF8;
|
||||
case EncodingType.UTF32:
|
||||
return Encoding.UTF32;
|
||||
default:
|
||||
return Encoding.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
762
Scripts/SubSystem/VitaNex/Core/Text/Json/Json.cs
Normal file
762
Scripts/SubSystem/VitaNex/Core/Text/Json/Json.cs
Normal file
@@ -0,0 +1,762 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public static class Json
|
||||
{
|
||||
public static Encoding DefaultEncoding = Encoding.UTF8;
|
||||
|
||||
/// <summary>
|
||||
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
|
||||
/// </summary>
|
||||
public static string Encode(object value)
|
||||
{
|
||||
return Encode(value, out JsonException _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
|
||||
/// </summary>
|
||||
public static string Encode(object value, out JsonException e)
|
||||
{
|
||||
if (Encode(value, out var json, out e))
|
||||
{
|
||||
return json;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
|
||||
/// </summary>
|
||||
public static bool Encode(object value, out string json)
|
||||
{
|
||||
return Encode(value, out json, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input: IDictionary (Object), IEnumerable (Array), Simple Types
|
||||
/// </summary>
|
||||
public static bool Encode(object value, out string json, out JsonException e)
|
||||
{
|
||||
json = null;
|
||||
e = null;
|
||||
|
||||
try
|
||||
{
|
||||
var sb = new StringBuilder(0x800);
|
||||
|
||||
if (SerializeValue(0, value, sb))
|
||||
{
|
||||
json = sb.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int line;
|
||||
int col;
|
||||
|
||||
var sub = sb.ToString();
|
||||
var idx = Math.Max(sub.LastIndexOf('\r'), sub.LastIndexOf('\n'));
|
||||
|
||||
if (idx > -1)
|
||||
{
|
||||
line = 1 + sub.Count(c => c == '\r' || c == '\n');
|
||||
col = sub.Length - idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = 1;
|
||||
col = sub.Length;
|
||||
}
|
||||
|
||||
sub = sub.Substring(Math.Max(0, sub.Length - 16));
|
||||
|
||||
e = new JsonException(String.Format("Encoding failed at line {0} col {1} near {2}", line, col, sub));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
if (x is JsonException)
|
||||
{
|
||||
e = (JsonException)x;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = new JsonException("Encoding failed", x);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
|
||||
/// </summary>
|
||||
public static object Decode(string json)
|
||||
{
|
||||
return Decode(json, out JsonException _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
|
||||
/// </summary>
|
||||
public static object Decode(string json, out JsonException e)
|
||||
{
|
||||
if (Decode(json, out var value, out e))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
|
||||
/// </summary>
|
||||
public static bool Decode(string json, out object value)
|
||||
{
|
||||
return Decode(json, out value, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Output: Dictionary[string, object] (Object), IEnumerable[object] (Array), Simple Types
|
||||
/// </summary>
|
||||
public static bool Decode(string json, out object value, out JsonException e)
|
||||
{
|
||||
value = null;
|
||||
e = null;
|
||||
|
||||
try
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
if (DeserializeValue(json, ref index, out value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int line;
|
||||
int col;
|
||||
|
||||
var sub = json.Substring(0, index);
|
||||
var idx = Math.Max(sub.LastIndexOf('\r'), sub.LastIndexOf('\n'));
|
||||
|
||||
if (idx > -1)
|
||||
{
|
||||
line = 1 + sub.Count(c => c == '\r' || c == '\n');
|
||||
col = index - idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = 1;
|
||||
col = index;
|
||||
}
|
||||
|
||||
sub = json.Substring(index, Math.Min(16, json.Length - index));
|
||||
|
||||
e = new JsonException(String.Format("Decoding failed at line {0} col {1} near {2}", line, col, sub));
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
if (x is JsonException)
|
||||
{
|
||||
e = (JsonException)x;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = new JsonException("Decoding failed", x);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SerializeValue(int depth, object val, StringBuilder json)
|
||||
{
|
||||
if (val is string)
|
||||
{
|
||||
return SerializeString((string)val, json);
|
||||
}
|
||||
|
||||
if (val is IDictionary)
|
||||
{
|
||||
return SerializeObject(depth, (IDictionary)val, json);
|
||||
}
|
||||
|
||||
if (val is IEnumerable)
|
||||
{
|
||||
return SerializeArray(depth, (IEnumerable)val, json);
|
||||
}
|
||||
|
||||
if (val is bool && (bool)val)
|
||||
{
|
||||
json.Append("true");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val is bool && !(bool)val)
|
||||
{
|
||||
json.Append("false");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val is char)
|
||||
{
|
||||
return SerializeString(val.ToString(), json);
|
||||
}
|
||||
|
||||
if (val is ValueType)
|
||||
{
|
||||
if (!(val is IConvertible))
|
||||
{
|
||||
return SerializeString(val.ToString(), json);
|
||||
}
|
||||
|
||||
return SerializeNumber(Convert.ToDouble(val), json);
|
||||
}
|
||||
|
||||
if (val == null)
|
||||
{
|
||||
json.Append("null");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return SerializeString(val.ToString(), json);
|
||||
}
|
||||
|
||||
private static bool DeserializeValue(string json, ref int index, out object value)
|
||||
{
|
||||
value = null;
|
||||
|
||||
switch (PeekToken(json, index))
|
||||
{
|
||||
case JsonToken.Number:
|
||||
return DeserializeNumber(json, ref index, out value);
|
||||
case JsonToken.String:
|
||||
return DeserializeString(json, ref index, out value);
|
||||
case JsonToken.ArrayOpen:
|
||||
return DeserializeArray(json, ref index, out value);
|
||||
case JsonToken.ObjectOpen:
|
||||
return DeserializeObject(json, ref index, out value);
|
||||
case JsonToken.True:
|
||||
{
|
||||
PeekToken(json, ref index);
|
||||
value = true;
|
||||
}
|
||||
return true;
|
||||
case JsonToken.False:
|
||||
{
|
||||
PeekToken(json, ref index);
|
||||
value = false;
|
||||
}
|
||||
return true;
|
||||
case JsonToken.Null:
|
||||
PeekToken(json, ref index);
|
||||
return true;
|
||||
case JsonToken.None:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SerializeNumber(double num, StringBuilder json)
|
||||
{
|
||||
json.Append(Convert.ToString(num, CultureInfo.InvariantCulture));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeNumber(string json, ref int index, out object value)
|
||||
{
|
||||
value = null;
|
||||
|
||||
index = SkipWhiteSpace(json, index);
|
||||
|
||||
index = PeekNumber(json, index, out var len);
|
||||
|
||||
var val = json.Substring(index, len);
|
||||
|
||||
if (Double.TryParse(val, NumberStyles.Any, CultureInfo.InvariantCulture, out var num))
|
||||
{
|
||||
index += len;
|
||||
value = num;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SerializeString(string str, StringBuilder json)
|
||||
{
|
||||
json.Append('"');
|
||||
|
||||
foreach (var c in str)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
json.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
json.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
json.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
json.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
json.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
json.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
json.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
var sur = Convert.ToInt32(c);
|
||||
|
||||
if (sur >= 32 && sur <= 126)
|
||||
{
|
||||
json.Append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
json.Append("\\u" + Convert.ToString(sur, 16).PadLeft(4, '0'));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
json.Append('"');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool DeserializeString(string json, ref int index, out object value)
|
||||
{
|
||||
value = null;
|
||||
|
||||
PeekToken(json, ref index); // " or '
|
||||
|
||||
var o = json[index - 1];
|
||||
|
||||
var str = new StringBuilder(0x20);
|
||||
|
||||
char c;
|
||||
|
||||
while (index < json.Length)
|
||||
{
|
||||
c = json[index++];
|
||||
|
||||
if (c == o)
|
||||
{
|
||||
value = str.ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (c == '\\')
|
||||
{
|
||||
if (index == json.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
c = json[index++];
|
||||
|
||||
var found = true;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
str.Append('"');
|
||||
break;
|
||||
case '\\':
|
||||
str.Append('\\');
|
||||
break;
|
||||
case '/':
|
||||
str.Append('/');
|
||||
break;
|
||||
case 'b':
|
||||
str.Append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
str.Append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
str.Append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
str.Append('\r');
|
||||
break;
|
||||
case 't':
|
||||
str.Append('\t');
|
||||
break;
|
||||
default:
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found && c == 'u')
|
||||
{
|
||||
var length = json.Length - index;
|
||||
|
||||
if (length < 4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var sub = json.Substring(index, 4);
|
||||
|
||||
if (!UInt32.TryParse(sub, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var sur))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
str.Append(Char.ConvertFromUtf32((int)sur));
|
||||
index += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
str.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SerializeArray(int depth, IEnumerable arr, StringBuilder json)
|
||||
{
|
||||
var tabs = new string('\t', depth++);
|
||||
var line = "\r\n" + tabs;
|
||||
|
||||
var success = true;
|
||||
|
||||
json.Append((depth > 1 ? line : String.Empty) + '[');
|
||||
|
||||
var first = true;
|
||||
|
||||
foreach (var value in arr)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
json.Append(", ");
|
||||
}
|
||||
|
||||
json.Append(line + '\t');
|
||||
|
||||
if (!SerializeValue(depth, value, json))
|
||||
{
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
json.Append(line + ']');
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private static bool DeserializeArray(string json, ref int index, out object value)
|
||||
{
|
||||
value = null;
|
||||
|
||||
PeekToken(json, ref index); // [
|
||||
|
||||
var arr = new List<object>();
|
||||
|
||||
while (index < json.Length)
|
||||
{
|
||||
switch (PeekToken(json, index))
|
||||
{
|
||||
case JsonToken.None:
|
||||
return false;
|
||||
case JsonToken.Comma:
|
||||
PeekToken(json, ref index); // ,
|
||||
break;
|
||||
case JsonToken.ArrayClose:
|
||||
{
|
||||
PeekToken(json, ref index); // ]
|
||||
value = arr;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
{
|
||||
if (!DeserializeValue(json, ref index, out var val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
arr.Add(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SerializeObject(int depth, IDictionary obj, StringBuilder json)
|
||||
{
|
||||
var tabs = new string('\t', depth++);
|
||||
var line = "\r\n" + tabs;
|
||||
|
||||
var success = true;
|
||||
|
||||
json.Append((depth > 1 ? line : String.Empty) + '{');
|
||||
|
||||
var first = true;
|
||||
|
||||
var e = obj.GetEnumerator();
|
||||
|
||||
while (e.MoveNext())
|
||||
{
|
||||
var key = e.Key?.ToString() ?? String.Empty;
|
||||
var value = e.Value;
|
||||
|
||||
if (!first)
|
||||
{
|
||||
json.Append(", ");
|
||||
}
|
||||
|
||||
json.Append(line + '\t');
|
||||
|
||||
if (!SerializeString(key, json))
|
||||
{
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
json.Append(": ");
|
||||
|
||||
if (!SerializeValue(depth, value, json))
|
||||
{
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
json.Append(line + '}');
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private static bool DeserializeObject(string json, ref int index, out object value)
|
||||
{
|
||||
value = null;
|
||||
|
||||
PeekToken(json, ref index); // {
|
||||
|
||||
var obj = new Dictionary<string, object>();
|
||||
|
||||
while (index < json.Length)
|
||||
{
|
||||
switch (PeekToken(json, index))
|
||||
{
|
||||
case JsonToken.None:
|
||||
return false;
|
||||
case JsonToken.Comma:
|
||||
PeekToken(json, ref index); // ,
|
||||
break;
|
||||
case JsonToken.ObjectClose:
|
||||
{
|
||||
PeekToken(json, ref index); // }
|
||||
value = obj;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
{
|
||||
if (!DeserializeString(json, ref index, out var name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PeekToken(json, ref index) != JsonToken.Colon) // :
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DeserializeValue(json, ref index, out var val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
obj[(string)name] = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int SkipWhiteSpace(string json, int index)
|
||||
{
|
||||
while (index < json.Length)
|
||||
{
|
||||
if (Char.IsWhiteSpace(json[index]) || json[index] == '\r' || json[index] == '\n')
|
||||
{
|
||||
++index;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
private static int PeekNumber(string json, int index, out int length)
|
||||
{
|
||||
length = 0;
|
||||
|
||||
while (index < json.Length)
|
||||
{
|
||||
var c = json[index];
|
||||
|
||||
if (c == '-' && length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Char.IsDigit(c) && c != '-')
|
||||
{
|
||||
if ((c == 'e' || c == 'E') && index + 1 < json.Length && json[index + 1] == '+')
|
||||
{
|
||||
length += 2;
|
||||
index += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '.' && index + 1 < json.Length && Char.IsDigit(json[index + 1]))
|
||||
{
|
||||
length += 2;
|
||||
index += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++length;
|
||||
++index;
|
||||
}
|
||||
|
||||
return index - length;
|
||||
}
|
||||
|
||||
private static JsonToken PeekToken(string json, int index)
|
||||
{
|
||||
return PeekToken(json, ref index);
|
||||
}
|
||||
|
||||
private static JsonToken PeekToken(string json, ref int index)
|
||||
{
|
||||
index = SkipWhiteSpace(json, index);
|
||||
|
||||
if (index >= json.Length)
|
||||
{
|
||||
return JsonToken.None;
|
||||
}
|
||||
|
||||
var c = json[index++];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '{':
|
||||
return JsonToken.ObjectOpen;
|
||||
case '}':
|
||||
return JsonToken.ObjectClose;
|
||||
case '[':
|
||||
return JsonToken.ArrayOpen;
|
||||
case ']':
|
||||
return JsonToken.ArrayClose;
|
||||
case ',':
|
||||
return JsonToken.Comma;
|
||||
case '"':
|
||||
case '\'':
|
||||
return JsonToken.String;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
return JsonToken.Number;
|
||||
case ':':
|
||||
return JsonToken.Colon;
|
||||
}
|
||||
|
||||
--index;
|
||||
|
||||
var length = json.Length - index;
|
||||
|
||||
// false
|
||||
if (length >= 5 && json.IndexOf("false", index, StringComparison.OrdinalIgnoreCase) == index)
|
||||
{
|
||||
index += 5;
|
||||
return JsonToken.False;
|
||||
}
|
||||
|
||||
// true
|
||||
if (length >= 4 && json.IndexOf("true", index, StringComparison.OrdinalIgnoreCase) == index)
|
||||
{
|
||||
index += 4;
|
||||
return JsonToken.True;
|
||||
}
|
||||
|
||||
// null
|
||||
if (length >= 4 && json.IndexOf("null", index, StringComparison.OrdinalIgnoreCase) == index)
|
||||
{
|
||||
index += 4;
|
||||
return JsonToken.Null;
|
||||
}
|
||||
|
||||
return JsonToken.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Scripts/SubSystem/VitaNex/Core/Text/Json/JsonException.cs
Normal file
36
Scripts/SubSystem/VitaNex/Core/Text/Json/JsonException.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public class JsonException : Exception
|
||||
{
|
||||
public JsonException()
|
||||
{ }
|
||||
|
||||
public JsonException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
public JsonException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{ }
|
||||
|
||||
protected JsonException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
29
Scripts/SubSystem/VitaNex/Core/Text/Json/JsonToken.cs
Normal file
29
Scripts/SubSystem/VitaNex/Core/Text/Json/JsonToken.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public enum JsonToken
|
||||
{
|
||||
None = 0,
|
||||
ObjectOpen,
|
||||
ObjectClose,
|
||||
ArrayOpen,
|
||||
ArrayClose,
|
||||
Colon,
|
||||
Comma,
|
||||
String,
|
||||
Number,
|
||||
True,
|
||||
False,
|
||||
Null
|
||||
}
|
||||
}
|
||||
165
Scripts/SubSystem/VitaNex/Core/Text/LanguagePack.cs
Normal file
165
Scripts/SubSystem/VitaNex/Core/Text/LanguagePack.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public class IndependentLanguagePack
|
||||
{
|
||||
private readonly Dictionary<int, string> _Definitions = new Dictionary<int, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string at the given index, or String.Empty if undefined
|
||||
/// </summary>
|
||||
public virtual string this[int index]
|
||||
{
|
||||
get => _Definitions.ContainsKey(index) ? _Definitions[index] ?? String.Empty : String.Empty;
|
||||
set
|
||||
{
|
||||
if (_Definitions.ContainsKey(index))
|
||||
{
|
||||
_Definitions[index] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Definitions.Add(index, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given index has a defined entry.
|
||||
/// </summary>
|
||||
public bool IsDefined(int index)
|
||||
{
|
||||
return !String.IsNullOrEmpty(this[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the given index
|
||||
/// </summary>
|
||||
public void Define(int index, string value)
|
||||
{
|
||||
this[index] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the given index
|
||||
/// </summary>
|
||||
public string ToString(int index)
|
||||
{
|
||||
return this[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a formatted message string at the given index using the specified optional parameters to be included during
|
||||
/// formatting
|
||||
/// </summary>
|
||||
public string Format(int index, params object[] args)
|
||||
{
|
||||
return String.Format(this[index], args);
|
||||
}
|
||||
}
|
||||
|
||||
public class LanguagePack
|
||||
{
|
||||
/// <summary>
|
||||
/// A table used for overriding cliloc text for each language
|
||||
/// </summary>
|
||||
private readonly Dictionary<ClilocLNG, Dictionary<int, string>> _TableMutations =
|
||||
new Dictionary<ClilocLNG, Dictionary<int, string>>
|
||||
{
|
||||
{ClilocLNG.ENU, new Dictionary<int, string>()},
|
||||
{ClilocLNG.DEU, new Dictionary<int, string>()},
|
||||
{ClilocLNG.ESP, new Dictionary<int, string>()},
|
||||
{ClilocLNG.FRA, new Dictionary<int, string>()},
|
||||
{ClilocLNG.JPN, new Dictionary<int, string>()},
|
||||
{ClilocLNG.KOR, new Dictionary<int, string>()},
|
||||
{ClilocLNG.CHT, new Dictionary<int, string>()}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public LanguagePack(ClilocLNG lng = ClilocLNG.ENU)
|
||||
{
|
||||
Language = lng;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current language used by this instance
|
||||
/// </summary>
|
||||
public virtual ClilocLNG Language { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a cliloc table using this instance' selected language
|
||||
/// </summary>
|
||||
protected virtual ClilocTable Table => Clilocs.Tables[Language];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string at the given index, or String.Empty if undefined
|
||||
/// </summary>
|
||||
public virtual string this[int index]
|
||||
{
|
||||
get => !Table.IsNullOrWhiteSpace(index)
|
||||
? (_TableMutations[Language].ContainsKey(index) ? _TableMutations[Language][index] : Table[index].Text)
|
||||
: (_TableMutations[Language].ContainsKey(index) ? _TableMutations[Language][index] : String.Empty);
|
||||
set
|
||||
{
|
||||
if (_TableMutations[Language].ContainsKey(index))
|
||||
{
|
||||
_TableMutations[Language][index] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_TableMutations[Language].Add(index, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given index has a defined entry.
|
||||
/// </summary>
|
||||
public bool IsDefined(int index)
|
||||
{
|
||||
return !String.IsNullOrEmpty(this[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the given index
|
||||
/// </summary>
|
||||
public void Define(int index, string value)
|
||||
{
|
||||
this[index] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the given index
|
||||
/// </summary>
|
||||
public string ToString(int index)
|
||||
{
|
||||
return this[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a formatted message string at the given index using the specified optional parameters to be included during
|
||||
/// formatting
|
||||
/// </summary>
|
||||
public string Format(int index, params object[] args)
|
||||
{
|
||||
return String.Format(this[index], args);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Scripts/SubSystem/VitaNex/Core/Text/StringSearch.cs
Normal file
66
Scripts/SubSystem/VitaNex/Core/Text/StringSearch.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
[Flags]
|
||||
public enum StringSearchFlags
|
||||
{
|
||||
None = 0x0,
|
||||
Equals = 0x1,
|
||||
Contains = 0x2,
|
||||
StartsWith = 0x4,
|
||||
EndsWith = 0x8
|
||||
}
|
||||
|
||||
public static class StringSearch
|
||||
{
|
||||
public static bool Execute(this StringSearchFlags flags, string haystack, string needle, bool ignoreCase)
|
||||
{
|
||||
if (flags == StringSearchFlags.None || haystack == null || needle == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(StringSearchFlags.Equals) &&
|
||||
(ignoreCase ? Insensitive.Equals(haystack, needle) : haystack.Equals(needle)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(StringSearchFlags.Contains) &&
|
||||
(ignoreCase ? Insensitive.Contains(haystack, needle) : haystack.Contains(needle)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(StringSearchFlags.StartsWith) &&
|
||||
(ignoreCase ? Insensitive.StartsWith(haystack, needle) : haystack.StartsWith(needle)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(StringSearchFlags.EndsWith) &&
|
||||
(ignoreCase ? Insensitive.EndsWith(haystack, needle) : haystack.EndsWith(needle)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Scripts/SubSystem/VitaNex/Core/Text/SystemFonts.cs
Normal file
57
Scripts/SubSystem/VitaNex/Core/Text/SystemFonts.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System.Drawing;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public enum SystemFont
|
||||
{
|
||||
Default,
|
||||
Arial,
|
||||
Tahoma,
|
||||
Terminal,
|
||||
Verdana
|
||||
}
|
||||
|
||||
public static class Fonts
|
||||
{
|
||||
public static readonly Font Default = new Font("Arial", 12);
|
||||
public static readonly Font Arial = new Font("Arial", 12);
|
||||
public static readonly Font Tahoma = new Font("Tahoma", 12);
|
||||
public static readonly Font Terminal = new Font("Terminal", 12);
|
||||
public static readonly Font Verdana = new Font("Verdana", 12);
|
||||
|
||||
public static Font Dupe(this Font font, float emSize = 12, FontStyle style = FontStyle.Regular)
|
||||
{
|
||||
return new Font(font.FontFamily.Name, emSize, style);
|
||||
}
|
||||
|
||||
public static Font ToFont(this SystemFont font, float emSize = 12, FontStyle style = FontStyle.Regular)
|
||||
{
|
||||
switch (font)
|
||||
{
|
||||
case SystemFont.Arial:
|
||||
return Dupe(Arial, emSize, style);
|
||||
case SystemFont.Tahoma:
|
||||
return Dupe(Tahoma, emSize, style);
|
||||
case SystemFont.Terminal:
|
||||
return Dupe(Terminal, emSize, style);
|
||||
case SystemFont.Verdana:
|
||||
return Dupe(Verdana, emSize, style);
|
||||
default:
|
||||
return Dupe(Default, emSize, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
769
Scripts/SubSystem/VitaNex/Core/Text/UOFont.cs
Normal file
769
Scripts/SubSystem/VitaNex/Core/Text/UOFont.cs
Normal file
@@ -0,0 +1,769 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
|
||||
using PF = System.Drawing.Imaging.PixelFormat;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public enum UOEncoding : byte
|
||||
{
|
||||
Ascii,
|
||||
Unicode
|
||||
}
|
||||
|
||||
public enum UOFontStyle
|
||||
{
|
||||
Big = 0,
|
||||
Normal = 1,
|
||||
Small = 2
|
||||
}
|
||||
|
||||
public sealed class UOFonts
|
||||
{
|
||||
private static readonly UOFont[] _Ascii;
|
||||
private static readonly UOFont[] _Unicode;
|
||||
|
||||
private static readonly UOChar[][][] _Chars;
|
||||
|
||||
private static readonly byte[] _EmptyBuffer = new byte[0];
|
||||
|
||||
static UOFonts()
|
||||
{
|
||||
_Ascii = new UOFont[10];
|
||||
_Unicode = new UOFont[13];
|
||||
|
||||
_Chars = new UOChar[2][][];
|
||||
}
|
||||
|
||||
private static string FindFontFile(string file, params object[] args)
|
||||
{
|
||||
if (!args.IsNullOrEmpty())
|
||||
{
|
||||
file = String.Format(file, args);
|
||||
}
|
||||
|
||||
var path = Path.Combine(Core.BaseDirectory, "Data", "Fonts", file);
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
path = Core.FindDataFile(file);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private static Bitmap NewEmptyImage()
|
||||
{
|
||||
return new Bitmap(UOFont.DefaultCharSize.Width, UOFont.DefaultCharSize.Height, UOFont.PixelFormat);
|
||||
}
|
||||
|
||||
private static UOChar NewEmptyChar(UOEncoding enc)
|
||||
{
|
||||
return new UOChar(enc, 0, 0, NewEmptyImage());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 = FindFontFile("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.Read, FileShare.Read))
|
||||
{
|
||||
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 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 = FindFontFile("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.Read, FileShare.Read))
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static UOFont GetFont(UOEncoding enc, byte id)
|
||||
{
|
||||
switch (enc)
|
||||
{
|
||||
case UOEncoding.Ascii:
|
||||
return LoadAscii(id);
|
||||
case UOEncoding.Unicode:
|
||||
return LoadUnicode(id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UOFont GetAscii(byte id)
|
||||
{
|
||||
return GetFont(UOEncoding.Ascii, id);
|
||||
}
|
||||
|
||||
public static UOFont GetUnicode(byte id)
|
||||
{
|
||||
return GetFont(UOEncoding.Unicode, id);
|
||||
}
|
||||
|
||||
public static Bitmap GetImage(UOFont font, char c)
|
||||
{
|
||||
return font[c].GetImage();
|
||||
}
|
||||
|
||||
public UOEncoding Encoding { get; private set; }
|
||||
|
||||
public UOFont this[int id] => GetFont(Encoding, (byte)id);
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public byte DefaultID { get; private set; }
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap GetImage(byte font, char c)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return GetImage(this[font], c);
|
||||
}
|
||||
|
||||
public int GetWidth(byte font, string text)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetWidth(text);
|
||||
}
|
||||
|
||||
public int GetHeight(byte font, string text)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetHeight(text);
|
||||
}
|
||||
|
||||
public Size GetSize(byte font, string text)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetSize(text);
|
||||
}
|
||||
|
||||
public int GetWidth(byte font, params string[] lines)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetWidth(lines);
|
||||
}
|
||||
|
||||
public int GetHeight(byte font, params string[] lines)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetHeight(lines);
|
||||
}
|
||||
|
||||
public Size GetSize(byte font, params string[] lines)
|
||||
{
|
||||
if (font >= Count)
|
||||
{
|
||||
font = DefaultID;
|
||||
}
|
||||
|
||||
return this[font].GetSize(lines);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UOFont
|
||||
{
|
||||
#if MONO
|
||||
public const PF PixelFormat = PF.Format32bppArgb;
|
||||
#else
|
||||
public const PF PixelFormat = PF.Format16bppArgb1555;
|
||||
#endif
|
||||
|
||||
public static Size DefaultCharSize = new Size(8, 10);
|
||||
|
||||
public static UOFonts Ascii { get; private set; }
|
||||
public static UOFonts Unicode { get; private set; }
|
||||
|
||||
static UOFont()
|
||||
{
|
||||
Ascii = new UOFonts(UOEncoding.Ascii);
|
||||
Unicode = new UOFonts(UOEncoding.Unicode);
|
||||
|
||||
for (var i = 0; i <= 1; i++)
|
||||
{
|
||||
VitaNexCore.ToConsole("[UOFont]: Preloaded {0}", Unicode[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Configure()
|
||||
{ }
|
||||
|
||||
public static UOFont GetFont(UOEncoding enc, byte id)
|
||||
{
|
||||
return UOFonts.GetFont(enc, id);
|
||||
}
|
||||
|
||||
public static UOFont GetAscii(byte id)
|
||||
{
|
||||
return UOFonts.GetFont(UOEncoding.Ascii, id);
|
||||
}
|
||||
|
||||
public static UOFont GetUnicode(byte id)
|
||||
{
|
||||
return UOFonts.GetFont(UOEncoding.Unicode, id);
|
||||
}
|
||||
|
||||
public static Bitmap GetImage(UOFont font, char c)
|
||||
{
|
||||
return UOFonts.GetImage(font, c);
|
||||
}
|
||||
|
||||
public static Bitmap GetAsciiImage(byte font, char c)
|
||||
{
|
||||
return Ascii.GetImage(font, c);
|
||||
}
|
||||
|
||||
public static Bitmap GetUnicodeImage(byte font, char c)
|
||||
{
|
||||
return Unicode.GetImage(font, c);
|
||||
}
|
||||
|
||||
public static int GetAsciiWidth(byte font, string text)
|
||||
{
|
||||
return Ascii.GetWidth(font, text);
|
||||
}
|
||||
|
||||
public static int GetAsciiHeight(byte font, string text)
|
||||
{
|
||||
return Ascii.GetHeight(font, text);
|
||||
}
|
||||
|
||||
public static Size GetAsciiSize(byte font, string text)
|
||||
{
|
||||
return Ascii.GetSize(font, text);
|
||||
}
|
||||
|
||||
public static int GetAsciiWidth(byte font, params string[] lines)
|
||||
{
|
||||
return Ascii.GetWidth(font, lines);
|
||||
}
|
||||
|
||||
public static int GetAsciiHeight(byte font, params string[] lines)
|
||||
{
|
||||
return Ascii.GetHeight(font, lines);
|
||||
}
|
||||
|
||||
public static Size GetAsciiSize(byte font, params string[] lines)
|
||||
{
|
||||
return Ascii.GetSize(font, lines);
|
||||
}
|
||||
|
||||
public static int GetUnicodeWidth(byte font, string text)
|
||||
{
|
||||
return Unicode.GetWidth(font, text);
|
||||
}
|
||||
|
||||
public static int GetUnicodeHeight(byte font, string text)
|
||||
{
|
||||
return Unicode.GetHeight(font, text);
|
||||
}
|
||||
|
||||
public static Size GetUnicodeSize(byte font, string text)
|
||||
{
|
||||
return Unicode.GetSize(font, text);
|
||||
}
|
||||
|
||||
public static int GetUnicodeWidth(byte font, params string[] lines)
|
||||
{
|
||||
return Unicode.GetWidth(font, lines);
|
||||
}
|
||||
|
||||
public static int GetUnicodeHeight(byte font, params string[] lines)
|
||||
{
|
||||
return Unicode.GetHeight(font, lines);
|
||||
}
|
||||
|
||||
public static Size GetUnicodeSize(byte font, params string[] lines)
|
||||
{
|
||||
return Unicode.GetSize(font, lines);
|
||||
}
|
||||
|
||||
public UOEncoding Encoding { get; private set; }
|
||||
|
||||
public byte ID { get; private set; }
|
||||
|
||||
public byte MaxCharWidth { get; private set; }
|
||||
public byte MaxCharHeight { get; private set; }
|
||||
|
||||
public byte CharSpacing { get; private set; }
|
||||
public byte LineSpacing { get; private set; }
|
||||
|
||||
public byte LineHeight { get; private set; }
|
||||
|
||||
public UOChar[] Chars { get; private set; }
|
||||
|
||||
public int Length => Chars.Length;
|
||||
|
||||
public UOChar this[char c] => Chars[c % Length];
|
||||
public UOChar this[int i] => Chars[i % Length];
|
||||
|
||||
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 int GetWidth(string value)
|
||||
{
|
||||
return GetSize(value).Width;
|
||||
}
|
||||
|
||||
public int GetHeight(string value)
|
||||
{
|
||||
return GetSize(value).Height;
|
||||
}
|
||||
|
||||
public Size GetSize(string value)
|
||||
{
|
||||
var lines = value.Split('\n');
|
||||
|
||||
if (lines.Length == 0)
|
||||
{
|
||||
lines = new[] { value };
|
||||
}
|
||||
|
||||
return GetSize(lines);
|
||||
}
|
||||
|
||||
public int GetWidth(params string[] lines)
|
||||
{
|
||||
return GetSize(lines).Width;
|
||||
}
|
||||
|
||||
public int GetHeight(params string[] lines)
|
||||
{
|
||||
return GetSize(lines).Height;
|
||||
}
|
||||
|
||||
public Size GetSize(params string[] lines)
|
||||
{
|
||||
var w = 0;
|
||||
var h = 0;
|
||||
|
||||
var space = Chars[' '];
|
||||
|
||||
UOChar ci;
|
||||
|
||||
foreach (var line in lines.SelectMany(o => o.Contains('\n') ? o.Split('\n') : o.ToEnumerable()))
|
||||
{
|
||||
var lw = 0;
|
||||
var lh = 0;
|
||||
|
||||
foreach (var c in line)
|
||||
{
|
||||
if (c == '\t')
|
||||
{
|
||||
lw += (CharSpacing + space.Width) * 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
ci = this[c];
|
||||
|
||||
if (ci == null)
|
||||
{
|
||||
lw += (CharSpacing + space.Width);
|
||||
continue;
|
||||
}
|
||||
|
||||
lw += (CharSpacing + ci.XOffset + ci.Width);
|
||||
lh = Math.Max(lh, ci.YOffset + ci.Height);
|
||||
}
|
||||
|
||||
w = Math.Max(w, lw);
|
||||
h += lh + LineSpacing;
|
||||
}
|
||||
|
||||
return new Size(w, h);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("({0}, {1}, {2})", Encoding, ID, Length);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UOChar
|
||||
{
|
||||
public Bitmap Image { get; private set; }
|
||||
|
||||
public UOEncoding Encoding { get; private set; }
|
||||
|
||||
public sbyte XOffset { get; private set; }
|
||||
public sbyte YOffset { get; private set; }
|
||||
|
||||
public byte Width { get; private set; }
|
||||
public byte Height { get; private set; }
|
||||
|
||||
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 Bitmap GetImage()
|
||||
{
|
||||
return GetImage(false);
|
||||
}
|
||||
|
||||
public Bitmap GetImage(bool fill)
|
||||
{
|
||||
return GetImage(fill, Color555.White);
|
||||
}
|
||||
|
||||
public Bitmap GetImage(bool fill, Color555 bgColor)
|
||||
{
|
||||
return GetImage(fill, bgColor, Color555.Black);
|
||||
}
|
||||
|
||||
public unsafe Bitmap GetImage(bool fill, Color555 bgColor, Color555 textColor)
|
||||
{
|
||||
if (Width * Height <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var image = new Bitmap(Width, Height, UOFont.PixelFormat);
|
||||
|
||||
var bound = new Rectangle(0, 0, Width, Height);
|
||||
|
||||
var dataSrc = Image.LockBits(bound, ImageLockMode.ReadOnly, UOFont.PixelFormat);
|
||||
var lineSrc = (ushort*)dataSrc.Scan0;
|
||||
var deltaSrc = dataSrc.Stride >> 1;
|
||||
|
||||
var dataTrg = image.LockBits(bound, ImageLockMode.WriteOnly, UOFont.PixelFormat);
|
||||
var lineTrg = (ushort*)dataTrg.Scan0;
|
||||
var deltaTrg = dataTrg.Stride >> 1;
|
||||
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < Height; y++, lineSrc += deltaSrc, lineTrg += deltaTrg)
|
||||
{
|
||||
var source = lineSrc;
|
||||
var target = lineTrg;
|
||||
|
||||
if (source == null || target == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (x = 0; x < Width; x++)
|
||||
{
|
||||
if (source[x] != 0)
|
||||
{
|
||||
target[x] = textColor;
|
||||
}
|
||||
else if (fill)
|
||||
{
|
||||
target[x] = bgColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image.UnlockBits(dataSrc);
|
||||
image.UnlockBits(dataTrg);
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
107
Scripts/SubSystem/VitaNex/Core/Text/UniGlyph.cs
Normal file
107
Scripts/SubSystem/VitaNex/Core/Text/UniGlyph.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.Text
|
||||
{
|
||||
public static class UniGlyph
|
||||
{
|
||||
public const char Infinity = '\u221E';
|
||||
|
||||
public const char Cross1 = '\u2020';
|
||||
public const char Cross2 = '\u2021';
|
||||
|
||||
public const char WingLeft = '\u261C';
|
||||
public const char WingRight = '\u261E';
|
||||
|
||||
public const char ChevronLeft = '\u00AB';
|
||||
public const char ChevronRight = '\u00BB';
|
||||
|
||||
public const char ChevronLeftLarge = '\u226A';
|
||||
public const char ChevronRightLarge = '\u226B';
|
||||
|
||||
public const char ArrowLeft = '\u2190';
|
||||
public const char ArrowUp = '\u2191';
|
||||
public const char ArrowRight = '\u2192';
|
||||
public const char ArrowDown = '\u2193';
|
||||
|
||||
public const char ArrowLeftRight = '\u2194';
|
||||
public const char ArrowUpDown = '\u2195';
|
||||
|
||||
public const char ArrowNW = '\u2196';
|
||||
public const char ArrowNE = '\u2197';
|
||||
public const char ArrowSE = '\u2198';
|
||||
public const char ArrowSW = '\u2199';
|
||||
|
||||
public const char CircleX = '\u203B';
|
||||
public const char CircleDot = '\u25C9';
|
||||
|
||||
public const char CircleFill = '\u25CF';
|
||||
public const char CircleEmpty = '\u25CB';
|
||||
|
||||
public const char CircleLeftFill = '\u25D0';
|
||||
public const char CircleRightFill = '\u25D1';
|
||||
|
||||
public const char TriUpEmpty = '\u25B3';
|
||||
public const char TriUpFill = '\u25B2';
|
||||
public const char TriRightEmpty = '\u25B7';
|
||||
public const char TriRightFill = '\u25B6';
|
||||
public const char TriDownEmpty = '\u25BD';
|
||||
public const char TriDownFill = '\u25BC';
|
||||
public const char TriLeftEmpty = '\u25C1';
|
||||
public const char TriLeftFill = '\u25C0';
|
||||
|
||||
public const char StarFill = '\u2605';
|
||||
public const char StarEmpty = '\u2606';
|
||||
public const char DiamondFill = '\u25C6';
|
||||
public const char DiamondEmpty = '\u25C7';
|
||||
public const char SpadeFill = '\u2660';
|
||||
public const char SpadeEmpty = '\u2664';
|
||||
public const char HeartFill = '\u2665';
|
||||
public const char HeartEmpty = '\u2661';
|
||||
public const char ClubFill = '\u2663';
|
||||
public const char ClubEmpty = '\u2667';
|
||||
|
||||
public const char NoteCrotchet = '\u2669';
|
||||
public const char NoteQuaver = '\u266A';
|
||||
public const char NoteQuaver2 = '\u266C';
|
||||
|
||||
public const char Coffee = '\u2668';
|
||||
public const char HashTag = '\u266F';
|
||||
|
||||
public const char CurrencyCent = '\u00A2';
|
||||
public const char CurrencyUSD = '\u0024';
|
||||
public const char CurrencyGBP = '\u00A3';
|
||||
public const char CurrencyYEN = '\u00A5';
|
||||
public const char CurrencySIM = '\u00A7';
|
||||
public const char CurrencyEUR = '\u0404';
|
||||
|
||||
public const char CircleNum1 = '\u2460';
|
||||
public const char CircleNum2 = '\u2461';
|
||||
public const char CircleNum3 = '\u2462';
|
||||
public const char CircleNum4 = '\u2463';
|
||||
public const char CircleNum5 = '\u2464';
|
||||
public const char CircleNum6 = '\u2465';
|
||||
public const char CircleNum7 = '\u2466';
|
||||
public const char CircleNum8 = '\u2467';
|
||||
public const char CircleNum9 = '\u2468';
|
||||
public const char CircleNum10 = '\u2469';
|
||||
public const char CircleNum11 = '\u246A';
|
||||
public const char CircleNum12 = '\u246B';
|
||||
public const char CircleNum13 = '\u246C';
|
||||
public const char CircleNum14 = '\u246D';
|
||||
public const char CircleNum15 = '\u246E';
|
||||
public const char CircleNum16 = '\u246F';
|
||||
public const char CircleNum17 = '\u2470';
|
||||
public const char CircleNum18 = '\u2471';
|
||||
public const char CircleNum19 = '\u2472';
|
||||
public const char CircleNum20 = '\u2473';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user