Remove old test projects.
This commit is contained in:
parent
41b7bebba5
commit
8d2afd0955
@ -1,83 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public static class FT
|
|
||||||
{
|
|
||||||
private const string freetype2 = "freetype";
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Init_FreeType")]
|
|
||||||
public static extern FTError InitFreeType(out FTLibrary library);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Done_FreeType")]
|
|
||||||
public static extern FTError DoneFreeType(FTLibrary library);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_New_Face")]
|
|
||||||
public static extern FTError NewFace(
|
|
||||||
FTLibrary library,
|
|
||||||
[MarshalAs(UnmanagedType.LPStr)] string path,
|
|
||||||
long faceIndex,
|
|
||||||
out FTFace face);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
|
|
||||||
public static extern FTError NewMemoryFace(
|
|
||||||
FTLibrary library,
|
|
||||||
IntPtr buffer,
|
|
||||||
long size,
|
|
||||||
long faceIndex,
|
|
||||||
out FTFace face);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
|
|
||||||
public static extern FTError NewMemoryFace(
|
|
||||||
FTLibrary library,
|
|
||||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer,
|
|
||||||
long size,
|
|
||||||
long faceIndex,
|
|
||||||
out FTFace face);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
|
|
||||||
public static extern FTError NewMemoryFace(
|
|
||||||
FTLibrary library,
|
|
||||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Span<byte> buffer,
|
|
||||||
long size,
|
|
||||||
long faceIndex,
|
|
||||||
out FTFace face);
|
|
||||||
|
|
||||||
// public static extern FTError OpenFace(FTLibrary library, in FTOpenArgs args, long faceIndex, out FTFace face);
|
|
||||||
|
|
||||||
// [DllImport(freetype2, EntryPoint = "FT_Attach_File")]
|
|
||||||
// public static extern FTError AttachFile(FTFace face, [MarshalAs(UnmanagedType.LPStr)] string filePathName);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Set_Char_Size")]
|
|
||||||
public static extern FTError SetCharSize(
|
|
||||||
FTFace library,
|
|
||||||
long charWidth,
|
|
||||||
long charHeight,
|
|
||||||
uint horizontalResolution,
|
|
||||||
uint verticalResolution);
|
|
||||||
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Get_Char_Index")]
|
|
||||||
public static extern uint GetCharIndex(FTFace face, ulong charCode);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Load_Glyph")]
|
|
||||||
public static extern FTError LoadGlyph(FTFace face, uint charIndex, FTLoadFlags flags);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Render_Glyph")]
|
|
||||||
public static extern FTError RenderGlyph(FTGlyphSlot slot, FTRenderMode mode);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Done_Face")]
|
|
||||||
public static extern FTError DoneFace(FTFace face);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Bitmap_Init")]
|
|
||||||
public static extern void BitmapInit(ref FTBitmap bitmap);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Bitmap_Convert")]
|
|
||||||
public static extern void BitmapConvert(FTLibrary library, in FTBitmap source, ref FTBitmap target,
|
|
||||||
int alignment);
|
|
||||||
|
|
||||||
[DllImport(freetype2, EntryPoint = "FT_Bitmap_Done")]
|
|
||||||
public static extern void BitmapDone(FTLibrary library, ref FTBitmap bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public enum FTError : int
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum FTLoadFlags
|
|
||||||
{
|
|
||||||
Default = 0,
|
|
||||||
NoScale = 1 << 0,
|
|
||||||
NoHinting = 1 << 1,
|
|
||||||
Render = 1 << 2,
|
|
||||||
NoBitmap = 1 << 3,
|
|
||||||
VerticalLayout = 1 << 4,
|
|
||||||
ForceAutoHint = 1 << 5,
|
|
||||||
CropBitmap = 1 << 6,
|
|
||||||
Pedantic = 1 << 7,
|
|
||||||
IgnoreGlobalAdvanceWidth = 1 << 9,
|
|
||||||
NoRecurse = 1 << 10,
|
|
||||||
IgnoreTransform = 1 << 11,
|
|
||||||
Monochrome= 1 << 12,
|
|
||||||
LinearDesign = 1 << 13,
|
|
||||||
SbitsOnly = 1 << 14,
|
|
||||||
NoAutoHint = 1 << 15,
|
|
||||||
Color = 1 << 20,
|
|
||||||
ComputeMetrics = 1 << 21,
|
|
||||||
BitmapMetricsOnly = 1 << 22
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public enum FTRenderMode
|
|
||||||
{
|
|
||||||
Normal = 0,
|
|
||||||
Light,
|
|
||||||
Mono,
|
|
||||||
Lcd,
|
|
||||||
LcdVertical,
|
|
||||||
Sdf
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum FaceFlag : int
|
|
||||||
{
|
|
||||||
Scalable = 1 << 0,
|
|
||||||
FixedSizes = 1 << 1,
|
|
||||||
FixedWidth = 1 << 2,
|
|
||||||
Sfnt = 1 << 3,
|
|
||||||
Horizontal = 1 << 4,
|
|
||||||
Vertical = 1 << 5,
|
|
||||||
Kerning = 1 << 6,
|
|
||||||
FastGlyphs = 1 << 7,
|
|
||||||
MultipleMasters = 1 << 8,
|
|
||||||
GlyphNames = 1 << 9,
|
|
||||||
ExternalStream = 1 << 10,
|
|
||||||
Hinter = 1 << 11,
|
|
||||||
CidKeyed = 1 << 12,
|
|
||||||
Tricky = 1 << 13,
|
|
||||||
Color = 1 << 14,
|
|
||||||
Variation = 1 << 15,
|
|
||||||
Svg = 1 << 16,
|
|
||||||
Sbix = 1 << 17,
|
|
||||||
SbixOverlay = 1 << 18
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,181 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Quik.Typography;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public class FreeTypeFont : QuikFont, IDisposable
|
|
||||||
{
|
|
||||||
|
|
||||||
private FreeTypeFontManager _owner;
|
|
||||||
private FTLibrary _library;
|
|
||||||
private FTFace _face;
|
|
||||||
private List<Atlas> _textures = new List<Atlas>();
|
|
||||||
private Dictionary<int, GlyphEntry> _entries = new Dictionary<int, GlyphEntry>();
|
|
||||||
|
|
||||||
public override float Ascender => _face.ScaledSize.Ascender / 64f;
|
|
||||||
public override float Descender => _face.ScaledSize.Descender / 64f;
|
|
||||||
|
|
||||||
internal FreeTypeFont(FreeTypeFontManager owner, FileInfo file, QuikFontStyle style)
|
|
||||||
{
|
|
||||||
Style = style;
|
|
||||||
_owner = owner;
|
|
||||||
_library = owner._library;
|
|
||||||
|
|
||||||
if (FT.NewFace(_library, file.FullName, 0, out _face) != FTError.None)
|
|
||||||
{
|
|
||||||
throw new Exception("Could not load font file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
FT.SetCharSize(_face, 0, (long)(style.Size * 64), 96, 96);
|
|
||||||
|
|
||||||
_textures.Add(new Atlas(owner.Context.TextureManager, _library));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override QuikFontStyle Style { get; }
|
|
||||||
|
|
||||||
public override bool HasCharacter(int character)
|
|
||||||
{
|
|
||||||
return FT.GetCharIndex(_face, (ulong)character) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetCharacter(int character, out QuikTexture texture, out QuikGlyph glyph)
|
|
||||||
{
|
|
||||||
GlyphEntry entry;
|
|
||||||
|
|
||||||
if (_entries.TryGetValue(character, out entry))
|
|
||||||
{
|
|
||||||
texture = entry.Atlas.Texture;
|
|
||||||
glyph = entry.Metrics;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = new GlyphEntry();
|
|
||||||
entry.Character = character;
|
|
||||||
|
|
||||||
uint index = FT.GetCharIndex(_face, (ulong) character);
|
|
||||||
FT.LoadGlyph(_face, index, FTLoadFlags.Default);
|
|
||||||
FT.RenderGlyph(_face.Glyph, FTRenderMode.Normal);
|
|
||||||
|
|
||||||
entry.Atlas = _textures[_textures.Count - 1];
|
|
||||||
if (!entry.Atlas.CanFit(_face.Glyph))
|
|
||||||
{
|
|
||||||
entry.Atlas = new Atlas(_owner.Context.TextureManager, _library);
|
|
||||||
_textures.Add(entry.Atlas);
|
|
||||||
}
|
|
||||||
entry.Atlas.AttachGlyph(_face.Glyph, out QRectangle uvs);
|
|
||||||
|
|
||||||
entry.Metrics = new QuikGlyph(
|
|
||||||
character,
|
|
||||||
uvs,
|
|
||||||
new QVec2(_face.Glyph.Metrics.Width / 64f, _face.Glyph.Metrics.Height / 64f),
|
|
||||||
new QVec2(_face.Glyph.Metrics.HorizontalBearingX / 64f, _face.Glyph.Metrics.HorizontalBearingY / 64f),
|
|
||||||
new QVec2(_face.Glyph.Metrics.VerticalBearingX / 64f , _face.Glyph.Metrics.VerticalBearingY / 64f),
|
|
||||||
new QVec2(_face.Glyph.Metrics.HorizontalAdvance / 64f, _face.Glyph.Metrics.VerticalAdvance / 64f));
|
|
||||||
|
|
||||||
_entries[character] = entry;
|
|
||||||
|
|
||||||
texture = entry.Atlas.Texture;
|
|
||||||
glyph = entry.Metrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDisposed { get; private set; } = false;
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (IsDisposed) return;
|
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
foreach (Atlas atlas in _textures)
|
|
||||||
{
|
|
||||||
atlas.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FT.DoneFace(_face);
|
|
||||||
IsDisposed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => Dispose(true);
|
|
||||||
|
|
||||||
private class Atlas : IDisposable
|
|
||||||
{
|
|
||||||
public QuikTexture Texture;
|
|
||||||
|
|
||||||
private QVec2 _pointer = new QVec2();
|
|
||||||
private float _verticalAdvance = 0;
|
|
||||||
private FTLibrary _ft;
|
|
||||||
private FTBitmap _bitmap;
|
|
||||||
|
|
||||||
public Atlas(IQuikTextureManager textureManager, FTLibrary ft)
|
|
||||||
{
|
|
||||||
Texture = textureManager.CreateTexture(
|
|
||||||
new QVec2(4096, 4096),
|
|
||||||
false,
|
|
||||||
QuikImageFormat.RgbaU8);
|
|
||||||
|
|
||||||
FT.BitmapInit(ref _bitmap);
|
|
||||||
_ft = ft;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanFit(in FTGlyphSlot slot)
|
|
||||||
{
|
|
||||||
// FIXME: the atlas will overflow.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AttachGlyph(in FTGlyphSlot slot, out QRectangle UVs)
|
|
||||||
{
|
|
||||||
FT.BitmapConvert(_ft, slot.Bitmap, ref _bitmap, 1);
|
|
||||||
|
|
||||||
QRectangle position =
|
|
||||||
new QRectangle(
|
|
||||||
_pointer + new QVec2(_bitmap.Width + 1, _bitmap.Rows + 1),
|
|
||||||
_pointer + new QVec2(1, 1));
|
|
||||||
|
|
||||||
Texture.SubImage(
|
|
||||||
_bitmap.Buffer,
|
|
||||||
QuikImageFormat.AlphaU8,
|
|
||||||
position,
|
|
||||||
0,
|
|
||||||
1);
|
|
||||||
|
|
||||||
_pointer.X += _bitmap.Width + 2;
|
|
||||||
_verticalAdvance = Math.Max(_verticalAdvance, slot.Bitmap.Rows + 2);
|
|
||||||
|
|
||||||
UVs = new QRectangle(
|
|
||||||
position.Right / 4096,
|
|
||||||
position.Bottom / 4096,
|
|
||||||
position.Left / 4096,
|
|
||||||
position.Top / 4096
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _isDisposed = false;
|
|
||||||
|
|
||||||
public void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (_isDisposed) return;
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
Texture.Dispose();
|
|
||||||
}
|
|
||||||
FT.BitmapDone(_ft, ref _bitmap);
|
|
||||||
_isDisposed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class GlyphEntry
|
|
||||||
{
|
|
||||||
public int Character;
|
|
||||||
public Atlas Atlas;
|
|
||||||
public QuikGlyph Metrics;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,177 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Quik.Typography;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public class FreeTypeFontManager : IQuikFontManager, IDisposable
|
|
||||||
{
|
|
||||||
public QuikContext Context { get; set; }
|
|
||||||
|
|
||||||
internal FTLibrary _library;
|
|
||||||
private Dictionary<string, FontCacheEntry> _cache = new Dictionary<string, FontCacheEntry>();
|
|
||||||
private Dictionary<QuikFontStyle, FreeTypeFont> _fonts= new Dictionary<QuikFontStyle, FreeTypeFont>();
|
|
||||||
|
|
||||||
public event FreeTypeFontManagerFontFinder FontNotFound;
|
|
||||||
|
|
||||||
public FreeTypeFontManager()
|
|
||||||
{
|
|
||||||
FT.InitFreeType(out _library);
|
|
||||||
|
|
||||||
// FIXME: There are operating system specific ways to achieve this. This is
|
|
||||||
// definitely not the best way to do this.
|
|
||||||
|
|
||||||
// Scan the fonts folder and build up a font cache.
|
|
||||||
string path = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
|
|
||||||
if (string.IsNullOrEmpty(path))
|
|
||||||
{
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
path = "/usr/share/fonts";
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
path = Path.Combine(
|
|
||||||
Environment.GetFolderPath(Environment.SpecialFolder.Windows),
|
|
||||||
"Fonts");
|
|
||||||
}
|
|
||||||
// For macOS I don't know. Too bad.
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectoryInfo directory = new DirectoryInfo(path);
|
|
||||||
ScanDirectoryForFonts(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ScanDirectoryForFonts(DirectoryInfo directory)
|
|
||||||
{
|
|
||||||
foreach (FileSystemInfo node in directory.GetFileSystemInfos())
|
|
||||||
{
|
|
||||||
if (node.Attributes.HasFlag(FileAttributes.Directory))
|
|
||||||
{
|
|
||||||
ScanDirectoryForFonts(node as DirectoryInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ScanFileForFonts(node as FileInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ScanFileForFonts(FileInfo file)
|
|
||||||
{
|
|
||||||
if (file is null) return;
|
|
||||||
|
|
||||||
if (FT.NewFace(_library, file.FullName, 0, out FTFace face) == FTError.None)
|
|
||||||
{
|
|
||||||
FontCacheEntry entry;
|
|
||||||
string name = face.FamilyName;
|
|
||||||
string style = face.StyleName;
|
|
||||||
|
|
||||||
if (name is null)
|
|
||||||
goto done_face;
|
|
||||||
|
|
||||||
if (_cache.ContainsKey(name))
|
|
||||||
{
|
|
||||||
entry = _cache[name];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry = new FontCacheEntry();
|
|
||||||
entry.Family = name;
|
|
||||||
_cache[name] = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (style.ToLowerInvariant())
|
|
||||||
{
|
|
||||||
case "regular":
|
|
||||||
entry.Regular = file;
|
|
||||||
break;
|
|
||||||
case "bold":
|
|
||||||
entry.Bold = file;
|
|
||||||
break;
|
|
||||||
case "italic":
|
|
||||||
entry.Italic = file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done_face:
|
|
||||||
FT.DoneFace(face);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
public QuikFont GetFont(QuikFontStyle fontStyle)
|
|
||||||
{
|
|
||||||
FreeTypeFont font;
|
|
||||||
|
|
||||||
if (_fonts.TryGetValue(fontStyle, out font))
|
|
||||||
return font;
|
|
||||||
|
|
||||||
FileInfo file = FindFont(fontStyle);
|
|
||||||
if (file == null)
|
|
||||||
{
|
|
||||||
FontNotFound?.Invoke(fontStyle, ref file);
|
|
||||||
if (file == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Could not find the font you are looking for.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
font = new FreeTypeFont(this, file, fontStyle);
|
|
||||||
_fonts.Add(fontStyle, font);
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
|
|
||||||
private FileInfo FindFont(QuikFontStyle fontStyle)
|
|
||||||
{
|
|
||||||
FontCacheEntry entry;
|
|
||||||
if (_cache.TryGetValue(fontStyle.Family, out entry))
|
|
||||||
{
|
|
||||||
switch (fontStyle.Type)
|
|
||||||
{
|
|
||||||
case QuikFontType.Normal:
|
|
||||||
return entry.Regular;
|
|
||||||
case QuikFontType.Bold:
|
|
||||||
return entry.Bold;
|
|
||||||
case QuikFontType.Italic:
|
|
||||||
return entry.Italic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// IDisposable
|
|
||||||
private void ReleaseUnmanagedResources()
|
|
||||||
{
|
|
||||||
FT.DoneFreeType(_library);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
ReleaseUnmanagedResources();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~FreeTypeFontManager()
|
|
||||||
{
|
|
||||||
ReleaseUnmanagedResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FontCacheEntry
|
|
||||||
{
|
|
||||||
public string Family;
|
|
||||||
public FileInfo Regular;
|
|
||||||
public FileInfo Bold;
|
|
||||||
public FileInfo Italic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void FreeTypeFontManagerFontFinder(QuikFontStyle style, ref FileInfo info);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<LangVersion>7.3</LangVersion>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Quik\Quik.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,180 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Quik.FreeType
|
|
||||||
{
|
|
||||||
public struct FTLibrary
|
|
||||||
{
|
|
||||||
private IntPtr _handle;
|
|
||||||
public IntPtr Handle => _handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe struct FTFace
|
|
||||||
{
|
|
||||||
private IntPtr _handle;
|
|
||||||
public IntPtr Handle => _handle;
|
|
||||||
private unsafe FTFaceInternal* Ptr => (FTFaceInternal*)_handle;
|
|
||||||
|
|
||||||
public long NumberOfGlyphs => Ptr->NumberOfGlyphs;
|
|
||||||
public long FaceIndex => Ptr->FaceIndex;
|
|
||||||
public FaceFlag FaceFlags => (FaceFlag)Ptr->FaceFlags;
|
|
||||||
public long StyleFlags => Ptr->StyleFlags;
|
|
||||||
public string FamilyName => Marshal.PtrToStringUTF8(Ptr->FamilyName);
|
|
||||||
public string StyleName => Marshal.PtrToStringUTF8(Ptr->StyleName);
|
|
||||||
public int NumberOfFixedSizes => Ptr->NumberOfFixedSizes;
|
|
||||||
public int NumberOfCharMaps => Ptr->NumberOfCharMaps;
|
|
||||||
public FTGlyphSlot Glyph => Ptr->Glyph;
|
|
||||||
public short Ascender => Ptr->Ascender;
|
|
||||||
public short Descender => Ptr->Descender;
|
|
||||||
public ref readonly FTSizeMetrics ScaledSize => ref ((FTSize*)Ptr->Size)->Metrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTBox
|
|
||||||
{
|
|
||||||
public long XMin;
|
|
||||||
public long YMin;
|
|
||||||
public long XMax;
|
|
||||||
public long YMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal struct FTFaceInternal
|
|
||||||
{
|
|
||||||
public long NumberOfFaces;
|
|
||||||
public long FaceIndex;
|
|
||||||
public long FaceFlags;
|
|
||||||
public long StyleFlags;
|
|
||||||
public long NumberOfGlyphs;
|
|
||||||
public IntPtr FamilyName;
|
|
||||||
public IntPtr StyleName;
|
|
||||||
public int NumberOfFixedSizes;
|
|
||||||
public IntPtr AvailableSizes;
|
|
||||||
public int NumberOfCharMaps;
|
|
||||||
public IntPtr Charmaps;
|
|
||||||
public FTGeneric Generic;
|
|
||||||
public FTBox BoundingBox;
|
|
||||||
public ushort UnitsPerEm;
|
|
||||||
public short Ascender;
|
|
||||||
public short Descender;
|
|
||||||
public short Height;
|
|
||||||
public short MaxAdvanceWidth;
|
|
||||||
public short MaxAdvanceHeight;
|
|
||||||
public short UnderlinePosition;
|
|
||||||
public short UnderlineThickness;
|
|
||||||
public FTGlyphSlot Glyph;
|
|
||||||
public IntPtr Size;
|
|
||||||
public IntPtr Charmap;
|
|
||||||
|
|
||||||
// Rest of the struct is private to implementation.
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTGeneric
|
|
||||||
{
|
|
||||||
public IntPtr Data;
|
|
||||||
public IntPtr Finalizer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTVector
|
|
||||||
{
|
|
||||||
public long X;
|
|
||||||
public long Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTBitmap
|
|
||||||
{
|
|
||||||
public uint Rows;
|
|
||||||
public uint Width;
|
|
||||||
public int Pitch;
|
|
||||||
public IntPtr Buffer;
|
|
||||||
public ushort NumberOfGrays;
|
|
||||||
public byte PixelMode;
|
|
||||||
public byte PaletteMode;
|
|
||||||
public IntPtr Palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTOutline
|
|
||||||
{
|
|
||||||
public short NumberOfContours;
|
|
||||||
public short NumberOfPoints;
|
|
||||||
public IntPtr Points;
|
|
||||||
public IntPtr Tags;
|
|
||||||
public IntPtr Contours;
|
|
||||||
public int Flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal struct FTGlyphSlotInternal
|
|
||||||
{
|
|
||||||
public FTLibrary Library;
|
|
||||||
public FTFace Face;
|
|
||||||
public FTGlyphSlot Next;
|
|
||||||
public uint GlyphIndex;
|
|
||||||
public FTGeneric Generic;
|
|
||||||
public FTGlyphMetrics Metrics;
|
|
||||||
public long LinearHorizontalAdvance;
|
|
||||||
public long LinearVerticalAdvance;
|
|
||||||
public FTVector Advance;
|
|
||||||
public int Format;
|
|
||||||
public FTBitmap Bitmap;
|
|
||||||
public int BitmapLeft;
|
|
||||||
public int BitmapTop;
|
|
||||||
public FTOutline Outline;
|
|
||||||
public uint NumberOfSubGlyphs;
|
|
||||||
public IntPtr SubGlyphs;
|
|
||||||
public IntPtr ControlData;
|
|
||||||
public long ControlLength;
|
|
||||||
public long LsbDelta;
|
|
||||||
public long RsbDelta;
|
|
||||||
public IntPtr Other;
|
|
||||||
public IntPtr Internal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe struct FTGlyphSlot
|
|
||||||
{
|
|
||||||
private IntPtr _handle;
|
|
||||||
public IntPtr Handle => _handle;
|
|
||||||
private FTGlyphSlotInternal* Ptr => (FTGlyphSlotInternal*) _handle;
|
|
||||||
|
|
||||||
public FTLibrary Library => Ptr->Library;
|
|
||||||
public FTFace Face => Ptr->Face;
|
|
||||||
public FTGlyphSlot Next => Ptr->Next;
|
|
||||||
public uint GlyphIndex => Ptr->GlyphIndex;
|
|
||||||
public ref readonly FTGlyphMetrics Metrics => ref Ptr->Metrics;
|
|
||||||
public long LinearHorizontalAdvance => Ptr->LinearHorizontalAdvance;
|
|
||||||
public long LinearVerticalAdvance => Ptr->LinearVerticalAdvance;
|
|
||||||
public FTVector Advance => Ptr->Advance;
|
|
||||||
public ref readonly FTBitmap Bitmap => ref Ptr->Bitmap;
|
|
||||||
public long BitmapLeft => Ptr->BitmapLeft;
|
|
||||||
public long BitmapTop => Ptr->BitmapTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTGlyphMetrics
|
|
||||||
{
|
|
||||||
public long Width;
|
|
||||||
public long Height;
|
|
||||||
public long HorizontalBearingX;
|
|
||||||
public long HorizontalBearingY;
|
|
||||||
public long HorizontalAdvance;
|
|
||||||
public long VerticalBearingX;
|
|
||||||
public long VerticalBearingY;
|
|
||||||
public long VerticalAdvance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTSizeMetrics
|
|
||||||
{
|
|
||||||
public short Xppem;
|
|
||||||
public short Yppem;
|
|
||||||
public long XScale;
|
|
||||||
public long YScale;
|
|
||||||
public long Ascender;
|
|
||||||
public long Descender;
|
|
||||||
public long Height;
|
|
||||||
public long MaxAdvance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct FTSize
|
|
||||||
{
|
|
||||||
public IntPtr Face;
|
|
||||||
public FTGeneric Generic;
|
|
||||||
public FTSizeMetrics Metrics;
|
|
||||||
private IntPtr Privates;
|
|
||||||
}
|
|
||||||
}
|
|
30
Quik.sln
30
Quik.sln
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
#
|
#
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuikTestApplication", "QuikTestApplication\QuikTestApplication.csproj", "{49AEF502-692A-48A4-8076-EF2228925280}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.FreeType", "Quik.FreeType\Quik.FreeType.csproj", "{53B95098-F304-47E6-A08C-DAFA589F5BCF}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -43,29 +39,5 @@ Global
|
|||||||
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
|
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
|
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
|
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{49AEF502-692A-48A4-8076-EF2228925280}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -1,183 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Quik;
|
|
||||||
using Quik.VertexGenerator;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
using OpenTK.Graphics.OpenGL4;
|
|
||||||
using OpenTK.Windowing.Common;
|
|
||||||
using OpenTK.Windowing.Desktop;
|
|
||||||
using OpenTK.Windowing.GraphicsLibraryFramework;
|
|
||||||
using Quik.FreeType;
|
|
||||||
using Quik.OpenTK;
|
|
||||||
using Quik.Typography;
|
|
||||||
using Quik.Controls;
|
|
||||||
using Quik.OpenGL;
|
|
||||||
using GL = Quik.OpenGL.GL;
|
|
||||||
using static Quik.OpenGL.GLEnum;
|
|
||||||
using Quik.CommandMachine;
|
|
||||||
|
|
||||||
namespace QuikTestApplication
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public const string vertex =
|
|
||||||
@"#version 140
|
|
||||||
uniform mat4 matrix;
|
|
||||||
in vec2 position;
|
|
||||||
in vec2 texcoord;
|
|
||||||
in vec4 color;
|
|
||||||
out vec2 ftexcoord;
|
|
||||||
out vec4 fcolor;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
fcolor = color;
|
|
||||||
ftexcoord = texcoord;
|
|
||||||
gl_Position = matrix * vec4(position.xy, 0, 1);
|
|
||||||
}
|
|
||||||
";
|
|
||||||
|
|
||||||
public const string fragment =
|
|
||||||
@"#version 140
|
|
||||||
in vec2 ftexcoord;
|
|
||||||
in vec4 fcolor;
|
|
||||||
out vec4 outcolor;
|
|
||||||
|
|
||||||
uniform sampler2D texture0;
|
|
||||||
uniform vec2 texture0offset;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
outcolor = fcolor * texture(texture0, ftexcoord + texture0offset);
|
|
||||||
}
|
|
||||||
";
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
NativeWindowSettings windowSettings = NativeWindowSettings.Default;
|
|
||||||
windowSettings.NumberOfSamples = 4;
|
|
||||||
NativeWindow window = new NativeWindow(windowSettings);
|
|
||||||
|
|
||||||
window.Context.MakeCurrent();
|
|
||||||
GL.LoadBindings(new GLFWBindingsContext().GetProcAddress);
|
|
||||||
|
|
||||||
FreeTypeFontManager fontManager = new FreeTypeFontManager();
|
|
||||||
QuikContext context = new QuikContext(new OpenGLTextureManager(), fontManager);
|
|
||||||
|
|
||||||
VertexGeneratorEngine engine = new VertexGeneratorEngine();
|
|
||||||
CommandQueue cmdQueue = new CommandQueue();
|
|
||||||
GL30Driver gldriver;
|
|
||||||
|
|
||||||
RootControl root = new RootControl(context);
|
|
||||||
Button button = new Button()
|
|
||||||
{
|
|
||||||
Bounds = new QRectangle(120, 60, 20, 20),
|
|
||||||
Text = "button",
|
|
||||||
Padding = 8,
|
|
||||||
NormalStroke = new QuikStrokeStyle(new QColor(0xccccccff), 4f),
|
|
||||||
HoverStroke = new QuikStrokeStyle(new QColor(0x1010ccff), 4f),
|
|
||||||
ActiveStroke = new QuikStrokeStyle(new QColor(0x999999ff), 4f),
|
|
||||||
};
|
|
||||||
button.Clicked += (sender, args) => {
|
|
||||||
if (!args.Buttons.HasFlag(Quik.MouseButton.Primary))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Button xbutton = (Button)sender;
|
|
||||||
|
|
||||||
if (xbutton.Text == "button")
|
|
||||||
{
|
|
||||||
xbutton.Text = "le button";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xbutton.Text = "button";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
root.MouseEnter += (_,_) => Console.WriteLine("enter");
|
|
||||||
root.MouseLeave += (_,_) => Console.WriteLine("leave");
|
|
||||||
root.MouseMove += (_,_) => Console.WriteLine("move");
|
|
||||||
root.MouseDown += (_,_) => Console.WriteLine("down");
|
|
||||||
root.MouseUp += (_,_) => Console.WriteLine("up");
|
|
||||||
root.Add(button);
|
|
||||||
|
|
||||||
GL.Enable(GL_MULTISAMPLE);
|
|
||||||
|
|
||||||
gldriver = new GL30Driver();
|
|
||||||
|
|
||||||
window.Context.SwapInterval = 0;
|
|
||||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
|
||||||
float lastMs = stopwatch.ElapsedMilliseconds;
|
|
||||||
int frames = 0;
|
|
||||||
for (;!window.IsExiting;)
|
|
||||||
{
|
|
||||||
NativeWindow.ProcessWindowEvents(false);
|
|
||||||
window.ProcessEvents(0.0f);
|
|
||||||
window.TryGetCurrentMonitorDpi(out float dpi, out _);
|
|
||||||
|
|
||||||
if (window.IsFocused)
|
|
||||||
{
|
|
||||||
var mouseState = window.MouseState;
|
|
||||||
QVec2 postion = new QVec2(mouseState.Position.X, window.ClientSize.Y - mouseState.Position.Y) * (dpi/72f);
|
|
||||||
Quik.MouseButton buttons =
|
|
||||||
(mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button1) ? Quik.MouseButton.Primary : 0) |
|
|
||||||
(mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button2) ? Quik.MouseButton.Secondary : 0) |
|
|
||||||
(mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button3) ? Quik.MouseButton.Tertiary : 0);
|
|
||||||
|
|
||||||
root.NotifyMouse(new Quik.MouseState(postion, buttons));
|
|
||||||
}
|
|
||||||
|
|
||||||
root.Bounds = new QRectangle(
|
|
||||||
window.ClientSize.X,
|
|
||||||
window.ClientSize.Y,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
root.NotifyUpdate();
|
|
||||||
|
|
||||||
cmdQueue.Clear();
|
|
||||||
root.NotifyPaint(cmdQueue);
|
|
||||||
|
|
||||||
engine.Reset();
|
|
||||||
engine.ProcessCommands(root.Bounds, cmdQueue);
|
|
||||||
|
|
||||||
DrawQueue drawQueue = engine.DrawQueue;
|
|
||||||
|
|
||||||
GL.Clear(GL_COLOR_BUFFER_BIT);
|
|
||||||
gldriver.Draw(drawQueue);
|
|
||||||
|
|
||||||
window.Context.SwapBuffers();
|
|
||||||
|
|
||||||
frames++;
|
|
||||||
float ms = stopwatch.ElapsedMilliseconds;
|
|
||||||
if (ms - lastMs > 1000)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Frames: {0}", frames*(ms - lastMs)/1000);
|
|
||||||
frames = 0;
|
|
||||||
lastMs = ms;
|
|
||||||
Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1} Calls: {2}", drawQueue.VertexCount, drawQueue.ElementCount, drawQueue.DrawCallCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TextFontManager : IQuikFontManager
|
|
||||||
{
|
|
||||||
public QuikContext Context { get; set; }
|
|
||||||
|
|
||||||
private TestFont _font;
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public QuikFont GetFont(QuikFontStyle fontStyle)
|
|
||||||
{
|
|
||||||
if (_font is null)
|
|
||||||
{
|
|
||||||
_font = new TestFont(Context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _font;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Quik.FreeType\Quik.FreeType.csproj" />
|
|
||||||
<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>
|
|
@ -1,126 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
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[] TextureData { get; private set; } = Array.Empty<byte>();
|
|
||||||
public static QVec2 TextureSize { get; private set; }
|
|
||||||
|
|
||||||
public QuikTexture Texture { get; }
|
|
||||||
|
|
||||||
public override float Ascender => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public override float Descender => throw new NotImplementedException();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
QVec2 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"))
|
|
||||||
{
|
|
||||||
QRectangle UVs;
|
|
||||||
QVec2 origin;
|
|
||||||
float advance;
|
|
||||||
int chr = element.Attributes["text"].Value[0];
|
|
||||||
|
|
||||||
QVec2 pos;
|
|
||||||
QVec2 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 QRectangle(
|
|
||||||
(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 QVec2(advance, 0));
|
|
||||||
_glyphs.Add(chr, glyph);
|
|
||||||
_characters.Add(chr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using (Stream str = typeof(TestFont).Assembly.GetManifestResourceStream("QuikTestApplication.font.dat"))
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HasCharacter(int character)
|
|
||||||
{
|
|
||||||
return _characters.Contains((char) character);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void GetCharacter(int character, out QuikTexture texture, out QuikGlyph glyph)
|
|
||||||
{
|
|
||||||
if (!_glyphs.TryGetValue(character, out glyph))
|
|
||||||
{
|
|
||||||
glyph = _glyphs['?'];
|
|
||||||
}
|
|
||||||
|
|
||||||
texture = Texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
@ -1,98 +0,0 @@
|
|||||||
<?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