Dashboard/QuikTestApplication/TestFont.cs

122 lines
4.6 KiB
C#
Raw Normal View History

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
}
}
}