Very quick test text implementation.
This commit is contained in:
parent
a0473d9e83
commit
bf47915491
@ -1,4 +1,6 @@
|
||||
namespace Quik
|
||||
using Quik.Typography;
|
||||
|
||||
namespace Quik
|
||||
{
|
||||
/// <summary>
|
||||
/// An object which QUIK commands may be issued to.
|
||||
@ -10,11 +12,13 @@
|
||||
/// </summary>
|
||||
public QuikDraw Draw { get; } = new QuikDraw();
|
||||
|
||||
public QuikStrokeStyle DefaultStroke { get; set; } = new QuikStrokeStyle(new QuikColor(0x000000FF), 4);
|
||||
public QuikStrokeStyle DefaultStroke { get; set; } = new QuikStrokeStyle(new QuikColor(0xaaaaaaff), 4);
|
||||
|
||||
public QuikFillStyle DefaultFill { get; set; } = new QuikFillStyle()
|
||||
{
|
||||
Color = new QuikColor(0xA0A0A0FF)
|
||||
Color = new QuikColor(0xeeeeeeff)
|
||||
};
|
||||
|
||||
public QuikFont DefaultFont { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
|
||||
namespace Quik
|
||||
@ -33,5 +34,8 @@ namespace Quik
|
||||
public void StencilClear() => Commands.Enqueue(new QuikCommandStencilClear());
|
||||
public void StencilBegin() => Commands.Enqueue(new QuikCommandStencilBegin());
|
||||
public void StencilEnd() => Commands.Enqueue(new QuikCommandStencilEnd());
|
||||
public void PutChar(char chr, QuikVec2 position) => Commands.Enqueue(new QuikCommandPutChar(chr, position));
|
||||
public void PutText(string text, QuikVec2 position) => Commands.Enqueue(new QuikCommandPutText(text, position));
|
||||
public void FlowText(string text, QuikRectangle bounds) => Commands.Enqueue(new QuikCommandFlowText(text, bounds));
|
||||
}
|
||||
}
|
14
Quik/Typography/QuikFont.cs
Normal file
14
Quik/Typography/QuikFont.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Quik.Typography
|
||||
{
|
||||
public abstract class QuikFont
|
||||
{
|
||||
public abstract QuikFontStyle Style { get; }
|
||||
|
||||
public string FontFamily => Style.Family;
|
||||
public float FontSize => Style.Size;
|
||||
public QuikFontStyle FontStyle => Style;
|
||||
|
||||
public abstract bool HasCharacter(int character);
|
||||
public abstract void GetCharacter(int character, out int texture, out QuikGlyph glyph);
|
||||
}
|
||||
}
|
23
Quik/Typography/QuikFontStyle.cs
Normal file
23
Quik/Typography/QuikFontStyle.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Quik.Typography
|
||||
{
|
||||
public class QuikFontStyle
|
||||
{
|
||||
public string Family { get; }
|
||||
public QuikFontType Type { get; }
|
||||
public float Size { get; }
|
||||
|
||||
public QuikFontStyle(string family, float size, QuikFontType type = QuikFontType.Normal)
|
||||
{
|
||||
Family = family;
|
||||
Size = size;
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public enum QuikFontType
|
||||
{
|
||||
Normal,
|
||||
Italic,
|
||||
Bold
|
||||
}
|
||||
}
|
54
Quik/Typography/QuikGlyph.cs
Normal file
54
Quik/Typography/QuikGlyph.cs
Normal file
@ -0,0 +1,54 @@
|
||||
namespace Quik.Typography
|
||||
{
|
||||
/// <summary>
|
||||
/// Glyph properties with metrics based on FreeType glyph metrics.
|
||||
/// </summary>
|
||||
public struct QuikGlyph
|
||||
{
|
||||
/// <summary>
|
||||
/// The code point for the character.
|
||||
/// </summary>
|
||||
public int Character { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Location of the glyph on the atlas.
|
||||
/// </summary>
|
||||
public QuikRectangle Location { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the glyph in units.
|
||||
/// </summary>
|
||||
public QuikVec2 Size { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Bearing vector for horizontal layout.
|
||||
/// </summary>
|
||||
public QuikVec2 HorizontalBearing { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Bearing vector for vertical layout.
|
||||
/// </summary>
|
||||
public QuikVec2 VerticalBearing { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Advance vector for vertical and horizontal layouts.
|
||||
/// </summary>
|
||||
public QuikVec2 Advance { get; }
|
||||
|
||||
public QuikGlyph(
|
||||
int character,
|
||||
QuikRectangle location,
|
||||
QuikVec2 size,
|
||||
QuikVec2 horizontalBearing,
|
||||
QuikVec2 verticalBearing,
|
||||
QuikVec2 advance)
|
||||
{
|
||||
Character = character;
|
||||
Location = location;
|
||||
Size = size;
|
||||
HorizontalBearing = horizontalBearing;
|
||||
VerticalBearing = verticalBearing;
|
||||
Advance = advance;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Quik.Typography;
|
||||
|
||||
namespace Quik.VertexGenerator
|
||||
{
|
||||
@ -223,9 +224,17 @@ namespace Quik.VertexGenerator
|
||||
case QuikCommandType.Rectangles:
|
||||
RenderRectangles(command as QuikCommandRectangles);
|
||||
goto exit_with_call;
|
||||
|
||||
case QuikCommandType.PutChar:
|
||||
RenderCharacter(command as QuikCommandPutChar);
|
||||
goto exit_with_call;
|
||||
|
||||
case QuikCommandType.PutText:
|
||||
RenderTextPut(command as QuikCommandPutText);
|
||||
goto exit_with_call;
|
||||
|
||||
default:
|
||||
{
|
||||
QuikDrawCall? subcall = null;
|
||||
if (OnHandleCommand(this, command))
|
||||
goto exit_with_call;
|
||||
break;
|
||||
@ -1393,6 +1402,97 @@ namespace Quik.VertexGenerator
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Text
|
||||
|
||||
private void RenderCharacter(QuikCommandPutChar chr)
|
||||
{
|
||||
Context.DefaultFont.GetCharacter(chr.Character, out int texture, out QuikGlyph metrics);
|
||||
|
||||
QuikVertex a, b, c, d;
|
||||
a = b = c = d = new QuikVertex() {Color = new QuikColor(0xffffffff)};
|
||||
|
||||
a.Position = chr.Position + new QuikVec2(0, metrics.HorizontalBearing.Y - metrics.Size.Y);
|
||||
a.TextureCoordinates = metrics.Location.Min;
|
||||
|
||||
b.Position = a.Position + new QuikVec2(metrics.Size.X, 0);
|
||||
c.Position = a.Position + metrics.Size;
|
||||
d.Position = a.Position + new QuikVec2(0, metrics.Size.Y);
|
||||
|
||||
b.TextureCoordinates = new QuikVec2(metrics.Location.Right, metrics.Location.Bottom);
|
||||
c.TextureCoordinates = metrics.Location.Max;
|
||||
d.TextureCoordinates = new QuikVec2(metrics.Location.Left, metrics.Location.Top);
|
||||
|
||||
short startVertex = (short)_vertexBufferPointer;
|
||||
short startElement = (short) _elementBufferPointer;
|
||||
AddVertex(a, b, c, d);
|
||||
AddElement(startVertex, (short)(startVertex + 1), (short)(startVertex + 2), startVertex, (short)(startVertex + 2), (short)(startVertex + 3));
|
||||
|
||||
QuikDrawCall call = CallTemplate;
|
||||
call.Texture = texture;
|
||||
call.Offset = (short) (startElement * 2);
|
||||
call.Count = 6;
|
||||
DrawCalls.Add(call);
|
||||
}
|
||||
|
||||
private void RenderTextPut(QuikCommandPutText text)
|
||||
{
|
||||
short startElement = (short)_elementBufferPointer;
|
||||
QuikFont font = Context.DefaultFont;
|
||||
QuikVertex vertex = new QuikVertex() {Color = new QuikColor(0xff7777ff)};
|
||||
QuikVec2 pointer = text.Position;
|
||||
int texture = -1;
|
||||
|
||||
for (int i = 0; i < text.Text.Length; i++)
|
||||
{
|
||||
int chr = text.Text[i];
|
||||
QuikGlyph metrics;
|
||||
|
||||
int ntex;
|
||||
font.GetCharacter(chr, out ntex, out metrics);
|
||||
|
||||
if (ntex != texture && texture != -1)
|
||||
{
|
||||
QuikDrawCall call = CallTemplate;
|
||||
call.Texture = texture;
|
||||
call.Offset = (short) (startElement * 2);
|
||||
call.Count = (short)(_elementBufferPointer - startElement);
|
||||
DrawCalls.Add(call);
|
||||
|
||||
startElement = (short) _elementBufferPointer;
|
||||
}
|
||||
|
||||
texture = ntex;
|
||||
QuikVertex a, b, c, d;
|
||||
a = b = c = d = vertex;
|
||||
|
||||
a.Position = pointer + new QuikVec2(0, metrics.HorizontalBearing.Y - metrics.Size.Y);
|
||||
a.TextureCoordinates = metrics.Location.Min;
|
||||
|
||||
b.Position = a.Position + new QuikVec2(metrics.Size.X, 0);
|
||||
c.Position = a.Position + metrics.Size;
|
||||
d.Position = a.Position + new QuikVec2(0, metrics.Size.Y);
|
||||
|
||||
b.TextureCoordinates = new QuikVec2(metrics.Location.Right, metrics.Location.Bottom);
|
||||
c.TextureCoordinates = metrics.Location.Max;
|
||||
d.TextureCoordinates = new QuikVec2(metrics.Location.Left, metrics.Location.Top);
|
||||
|
||||
pointer.X += metrics.Advance.X;
|
||||
|
||||
short startVertex = (short)_vertexBufferPointer;
|
||||
AddVertex(a, b, c, d);
|
||||
AddElement(startVertex, (short)(startVertex + 1), (short)(startVertex + 2), startVertex, (short)(startVertex + 2), (short)(startVertex + 3));
|
||||
}
|
||||
|
||||
{
|
||||
QuikDrawCall call = CallTemplate;
|
||||
call.Texture = texture;
|
||||
call.Offset = (short) (startElement * 2);
|
||||
call.Count = (short)(_elementBufferPointer - startElement);
|
||||
DrawCalls.Add(call);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public delegate void VertexGeneratorCommandHandler(QuikVertexGenerator generator, QuikCommand command, ref bool anyCalls);
|
||||
@ -1410,5 +1510,6 @@ namespace Quik.VertexGenerator
|
||||
public short Count;
|
||||
public QuikRectangle Bounds;
|
||||
public bool ClearStencil;
|
||||
public int Texture;
|
||||
}
|
||||
}
|
@ -35,9 +35,11 @@ in vec2 ftexcoord;
|
||||
in vec4 fcolor;
|
||||
out vec4 outcolor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
void main()
|
||||
{
|
||||
outcolor = fcolor;
|
||||
outcolor = fcolor * texture(texture0, ftexcoord);
|
||||
}
|
||||
";
|
||||
|
||||
@ -96,7 +98,7 @@ void main()
|
||||
QuikVertex.PositionOffset);
|
||||
GL.EnableVertexAttribArray(loc);
|
||||
GL.VertexAttribPointer(
|
||||
loc = GL.GetAttribLocation(sp, "texcoords"),
|
||||
loc = GL.GetAttribLocation(sp, "texcoord"),
|
||||
2,
|
||||
VertexAttribPointerType.Float,
|
||||
false,
|
||||
@ -133,6 +135,31 @@ void main()
|
||||
Color = new QuikColor(0xeeeeeeff)
|
||||
};
|
||||
|
||||
|
||||
int whiteTexture = GL.GenTexture();
|
||||
uint[] whitePixel = {0xFFFFFFFF};
|
||||
GL.BindTexture(TextureTarget.Texture2D, whiteTexture);
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 1, 1, 0, PixelFormat.Rgba, PixelType.UnsignedByte, whitePixel);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
|
||||
|
||||
TestFont font = new TestFont();
|
||||
font.TextureBase = GL.GenTexture();
|
||||
GL.BindTexture(TextureTarget.Texture2D, font.TextureBase);
|
||||
GL.TexImage2D(
|
||||
TextureTarget.Texture2D,
|
||||
0,
|
||||
PixelInternalFormat.Rgb,
|
||||
(int)TestFont.TextureSize.X, (int)TestFont.TextureSize.Y, 0,
|
||||
PixelFormat.Rgba, PixelType.UnsignedByte,
|
||||
TestFont.Texture);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
|
||||
|
||||
context.DefaultFont = font;
|
||||
|
||||
window.Context.SwapInterval = 0;
|
||||
|
||||
for (;!window.IsExiting;)
|
||||
{
|
||||
NativeWindow.ProcessWindowEvents(false);
|
||||
@ -144,9 +171,9 @@ void main()
|
||||
|
||||
Matrix4 matrix = Matrix4.CreateOrthographicOffCenter(
|
||||
0,
|
||||
(float)window.Size.X / 2,
|
||||
(float)window.Size.X,
|
||||
0,
|
||||
(float)window.Size.Y / 2,
|
||||
(float)window.Size.Y,
|
||||
1,
|
||||
-1);
|
||||
GL.UniformMatrix4(loc, false, ref matrix);
|
||||
@ -199,6 +226,8 @@ void main()
|
||||
StrokeStyle = strokeBorder
|
||||
});
|
||||
|
||||
context.Draw.PutText("Aaah! the cat turned into a cat!", new QuikVec2(25,30));
|
||||
|
||||
QuikCommand command;
|
||||
while (context.Draw.Commands.TryDequeue(out command))
|
||||
{
|
||||
@ -210,6 +239,7 @@ void main()
|
||||
|
||||
foreach (QuikDrawCall call in gen.DrawCalls)
|
||||
{
|
||||
GL.BindTexture(TextureTarget.Texture2D, call.Texture == 0 ? whiteTexture : call.Texture);
|
||||
GL.DrawElements(BeginMode.Triangles, call.Count, DrawElementsType.UnsignedShort, call.Offset);
|
||||
}
|
||||
|
||||
|
@ -9,4 +9,11 @@
|
||||
<ProjectReference Include="..\Quik.OpenTK\Quik.OpenTK.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="font.dat" />
|
||||
<EmbeddedResource Include="font.dat" />
|
||||
<None Remove="font.xml" />
|
||||
<EmbeddedResource Include="font.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
98
QuikTestApplication/TestFont.cs
Normal file
98
QuikTestApplication/TestFont.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
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>();
|
||||
|
||||
public static byte[] Texture { get; private set; } = Array.Empty<byte>();
|
||||
public static QuikVec2 TextureSize { get; private set; }
|
||||
|
||||
public int TextureBase { get; set; } = 1;
|
||||
|
||||
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"))
|
||||
{
|
||||
Texture = new byte[(int)str.Length];
|
||||
str.Read(Texture, 0, (int)str.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasCharacter(int character)
|
||||
{
|
||||
return _characters.Contains((char) character);
|
||||
}
|
||||
|
||||
public override void GetCharacter(int character, out int texture, out QuikGlyph glyph)
|
||||
{
|
||||
if (!_glyphs.TryGetValue(character, out glyph))
|
||||
{
|
||||
glyph = _glyphs['?'];
|
||||
}
|
||||
|
||||
texture = TextureBase;
|
||||
}
|
||||
}
|
||||
}
|
BIN
QuikTestApplication/font.dat
Normal file
BIN
QuikTestApplication/font.dat
Normal file
Binary file not shown.
BIN
QuikTestApplication/font.png
Normal file
BIN
QuikTestApplication/font.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
98
QuikTestApplication/font.xml
Normal file
98
QuikTestApplication/font.xml
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<font name="monospace" bold="false" italic="false" width="512" height="128" size="32">
|
||||
<character text=" " x="69" y="84" width="3" height="3" origin-x="1" origin-y="1" advance="19"/>
|
||||
<character text="!" x="116" y="59" width="6" height="25" origin-x="-7" origin-y="24" advance="19"/>
|
||||
<character text=""" x="487" y="59" width="11" height="11" origin-x="-4" origin-y="24" advance="19"/>
|
||||
<character text="#" x="373" y="0" width="22" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="$" x="48" y="0" width="18" height="31" origin-x="-1" origin-y="25" advance="19"/>
|
||||
<character text="%" x="417" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="&" x="438" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="'" x="498" y="59" width="5" height="11" origin-x="-7" origin-y="24" advance="19"/>
|
||||
<character text="(" x="66" y="0" width="10" height="31" origin-x="-5" origin-y="25" advance="19"/>
|
||||
<character text=")" x="76" y="0" width="10" height="31" origin-x="-4" origin-y="25" advance="19"/>
|
||||
<character text="*" x="423" y="59" width="17" height="17" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="+" x="359" y="59" width="19" height="19" origin-x="0" origin-y="20" advance="19"/>
|
||||
<character text="," x="440" y="59" width="8" height="12" origin-x="-5" origin-y="7" advance="19"/>
|
||||
<character text="-" x="58" y="84" width="11" height="5" origin-x="-4" origin-y="12" advance="19"/>
|
||||
<character text="." x="29" y="84" width="7" height="7" origin-x="-6" origin-y="6" advance="19"/>
|
||||
<character text="/" x="145" y="0" width="18" height="29" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="0" x="198" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="1" x="360" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="2" x="377" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="3" x="394" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="4" x="103" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="5" x="411" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="6" x="216" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="7" x="428" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="8" x="234" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="9" x="252" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text=":" x="378" y="59" width="7" height="19" origin-x="-6" origin-y="18" advance="19"/>
|
||||
<character text=";" x="122" y="59" width="8" height="23" origin-x="-5" origin-y="18" advance="19"/>
|
||||
<character text="<" x="385" y="59" width="19" height="18" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="=" x="468" y="59" width="19" height="11" origin-x="0" origin-y="16" advance="19"/>
|
||||
<character text=">" x="404" y="59" width="19" height="18" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="?" x="68" y="59" width="16" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="@" x="105" y="0" width="21" height="29" origin-x="1" origin-y="23" advance="19"/>
|
||||
<character text="A" x="459" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="B" x="270" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="C" x="445" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="D" x="288" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="E" x="462" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="F" x="479" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="G" x="122" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="H" x="306" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="I" x="84" y="59" width="16" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="J" x="100" y="59" width="16" height="25" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="K" x="63" y="34" width="20" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="L" x="0" y="59" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="M" x="141" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="N" x="324" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="O" x="160" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="P" x="17" y="59" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
|
||||
<character text="Q" x="126" y="0" width="19" height="29" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="R" x="83" y="34" width="20" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="S" x="342" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="T" x="480" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="U" x="34" y="59" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="V" x="0" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="W" x="395" y="0" width="22" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="X" x="21" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="Y" x="42" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
|
||||
<character text="Z" x="179" y="34" width="19" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="[" x="96" y="0" width="9" height="31" origin-x="-6" origin-y="25" advance="19"/>
|
||||
<character text="\" x="163" y="0" width="18" height="29" origin-x="0" origin-y="24" advance="19"/>
|
||||
<character text="]" x="86" y="0" width="10" height="31" origin-x="-4" origin-y="25" advance="19"/>
|
||||
<character text="^" x="448" y="59" width="20" height="11" origin-x="0" origin-y="25" advance="19"/>
|
||||
<character text="_" x="36" y="84" width="22" height="5" origin-x="1" origin-y="-4" advance="19"/>
|
||||
<character text="`" x="0" y="84" width="10" height="8" origin-x="-3" origin-y="27" advance="19"/>
|
||||
<character text="a" x="246" y="59" width="17" height="20" origin-x="-1" origin-y="19" advance="19"/>
|
||||
<character text="b" x="307" y="0" width="17" height="26" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="c" x="263" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
|
||||
<character text="d" x="253" y="0" width="18" height="26" origin-x="0" origin-y="25" advance="19"/>
|
||||
<character text="e" x="152" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="f" x="341" y="0" width="16" height="26" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="g" x="200" y="0" width="18" height="27" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="h" x="357" y="0" width="16" height="26" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="i" x="271" y="0" width="18" height="26" origin-x="-1" origin-y="25" advance="19"/>
|
||||
<character text="j" x="5" y="0" width="13" height="33" origin-x="-1" origin-y="25" advance="19"/>
|
||||
<character text="k" x="289" y="0" width="18" height="26" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="l" x="324" y="0" width="17" height="26" origin-x="-1" origin-y="25" advance="19"/>
|
||||
<character text="m" x="171" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="n" x="279" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
|
||||
<character text="o" x="228" y="59" width="18" height="20" origin-x="-1" origin-y="19" advance="19"/>
|
||||
<character text="p" x="218" y="0" width="18" height="27" origin-x="-1" origin-y="19" advance="19"/>
|
||||
<character text="q" x="236" y="0" width="17" height="27" origin-x="-1" origin-y="19" advance="19"/>
|
||||
<character text="r" x="295" y="59" width="16" height="20" origin-x="-4" origin-y="19" advance="19"/>
|
||||
<character text="s" x="311" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
|
||||
<character text="t" x="51" y="59" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
|
||||
<character text="u" x="327" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
|
||||
<character text="v" x="190" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="w" x="130" y="59" width="22" height="20" origin-x="1" origin-y="19" advance="19"/>
|
||||
<character text="x" x="209" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="y" x="181" y="0" width="19" height="27" origin-x="0" origin-y="19" advance="19"/>
|
||||
<character text="z" x="343" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
|
||||
<character text="{" x="18" y="0" width="15" height="32" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="|" x="0" y="0" width="5" height="34" origin-x="-7" origin-y="25" advance="19"/>
|
||||
<character text="}" x="33" y="0" width="15" height="32" origin-x="-2" origin-y="25" advance="19"/>
|
||||
<character text="~" x="10" y="84" width="19" height="7" origin-x="0" origin-y="14" advance="19"/>
|
||||
</font>
|
Loading…
Reference in New Issue
Block a user