2022-08-19 15:13:19 +02:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
2022-08-20 11:57:57 +02:00
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
using System.Runtime.InteropServices;
|
2022-08-19 15:13:19 +02:00
|
|
|
using System.Xml;
|
|
|
|
using Quik;
|
|
|
|
using Quik.Typography;
|
|
|
|
|
|
|
|
namespace QuikTestApplication
|
|
|
|
{
|
|
|
|
public class TestFont : QuikFont
|
|
|
|
{
|
|
|
|
public override QuikFontStyle Style => _style;
|
|
|
|
|
|
|
|
private static QuikFontStyle _style;
|
|
|
|
private static HashSet<int> _characters = new HashSet<int>();
|
|
|
|
private static Dictionary<int, QuikGlyph> _glyphs = new Dictionary<int, QuikGlyph>();
|
|
|
|
|
2022-08-20 11:57:57 +02:00
|
|
|
public static byte[] TextureData { get; private set; } = Array.Empty<byte>();
|
2022-08-19 15:13:19 +02:00
|
|
|
public static QuikVec2 TextureSize { get; private set; }
|
|
|
|
|
2022-08-20 11:57:57 +02:00
|
|
|
public IQuikTexture Texture { get; }
|
|
|
|
|
|
|
|
public TestFont(QuikContext context)
|
|
|
|
{
|
|
|
|
Texture = context.TextureManager.CreateTexture(TextureSize, false, QuikImageFormat.RgbaU8);
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
fixed (byte* ptr = &TextureData[0])
|
|
|
|
{
|
|
|
|
Texture.Image((IntPtr)ptr, QuikImageFormat.RgbaU8, TextureSize, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-08-19 15:13:19 +02:00
|
|
|
|
|
|
|
static TestFont()
|
|
|
|
{
|
|
|
|
using (Stream str = typeof(TestFont).Assembly.GetManifestResourceStream("QuikTestApplication.font.xml"))
|
|
|
|
{
|
|
|
|
XmlDocument document = new XmlDocument();
|
|
|
|
document.Load(str);
|
|
|
|
|
|
|
|
string family = document.DocumentElement.Attributes["name"].Value;
|
|
|
|
float fontSize = float.Parse(document.DocumentElement.Attributes["size"].Value);
|
|
|
|
QuikFontType style = QuikFontType.Normal;
|
|
|
|
if (document.DocumentElement.Attributes["bold"].Value == "true")
|
|
|
|
style = QuikFontType.Bold;
|
|
|
|
if (document.DocumentElement.Attributes["italic"].Value == "true")
|
|
|
|
style = QuikFontType.Italic;
|
|
|
|
|
|
|
|
_style = new QuikFontStyle(family, fontSize, style);
|
|
|
|
|
|
|
|
QuikVec2 atlasSize = default;
|
|
|
|
atlasSize.X = float.Parse(document.DocumentElement.Attributes["width"].Value);
|
|
|
|
atlasSize.Y = float.Parse(document.DocumentElement.Attributes["height"].Value);
|
|
|
|
|
|
|
|
TextureSize = atlasSize;
|
|
|
|
|
|
|
|
foreach (XmlElement element in document.SelectNodes("/font/character"))
|
|
|
|
{
|
|
|
|
QuikRectangle UVs;
|
|
|
|
QuikVec2 origin;
|
|
|
|
float advance;
|
|
|
|
int chr = element.Attributes["text"].Value[0];
|
|
|
|
|
|
|
|
QuikVec2 pos;
|
|
|
|
QuikVec2 size;
|
|
|
|
pos.X = float.Parse(element.Attributes["x"].Value);
|
|
|
|
pos.Y = float.Parse(element.Attributes["y"].Value);
|
|
|
|
size.X = float.Parse(element.Attributes["width"].Value);
|
|
|
|
size.Y = float.Parse(element.Attributes["height"].Value);
|
|
|
|
UVs = new QuikRectangle(
|
|
|
|
(pos.X + size.X)/atlasSize.X,
|
|
|
|
pos.Y/atlasSize.Y,
|
|
|
|
pos.X/atlasSize.X,
|
|
|
|
(size.Y + pos.Y)/atlasSize.Y);
|
|
|
|
|
|
|
|
origin.X = float.Parse(element.Attributes["origin-x"].Value);
|
|
|
|
origin.Y = float.Parse(element.Attributes["origin-y"].Value);
|
|
|
|
|
|
|
|
advance = float.Parse(element.Attributes["advance"].Value);
|
|
|
|
|
|
|
|
QuikGlyph glyph = new QuikGlyph(chr, UVs, size, origin, default, new QuikVec2(advance, 0));
|
|
|
|
_glyphs.Add(chr, glyph);
|
|
|
|
_characters.Add(chr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
using (Stream str = typeof(TestFont).Assembly.GetManifestResourceStream("QuikTestApplication.font.dat"))
|
|
|
|
{
|
2022-08-20 11:57:57 +02:00
|
|
|
TextureData = new byte[(int)str.Length];
|
|
|
|
str.Read(TextureData, 0, (int)str.Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evil pointer stuff. Beware!
|
|
|
|
Span<uint> head = MemoryMarshal.Cast<byte, uint>(TextureData);
|
|
|
|
for (int i = 0; i < head.Length; i++)
|
|
|
|
{
|
|
|
|
if (head[i] == 0xff000000)
|
|
|
|
{
|
|
|
|
head[i] = 0x00000000;
|
|
|
|
}
|
2022-08-19 15:13:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override bool HasCharacter(int character)
|
|
|
|
{
|
|
|
|
return _characters.Contains((char) character);
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:57:57 +02:00
|
|
|
public override void GetCharacter(int character, out IQuikTexture texture, out QuikGlyph glyph)
|
2022-08-19 15:13:19 +02:00
|
|
|
{
|
|
|
|
if (!_glyphs.TryGetValue(character, out glyph))
|
|
|
|
{
|
|
|
|
glyph = _glyphs['?'];
|
|
|
|
}
|
|
|
|
|
2022-08-20 11:57:57 +02:00
|
|
|
texture = Texture;
|
2022-08-19 15:13:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|