WIP: load fonts with FreeType.

This commit is contained in:
2025-06-25 23:20:46 +02:00
parent 4b2aa31b63
commit 17196c9437
3 changed files with 92 additions and 3 deletions

View File

@@ -1,5 +1,18 @@
using System.Numerics;
namespace Voile;
public struct Glyph
{
public int TextureId { get; set; } = -1;
public float Width { get; set; }
public float Height { get; set; }
public Vector2 Bearing { get; set; }
public int Advance { get; set; }
public Glyph() { }
}
/// <summary>
/// Represents font data.
/// </summary>
@@ -18,4 +31,24 @@ public class Font : Resource
{
Buffer = buffer;
}
public void Measure(string text)
{
foreach (char c in text)
{
}
}
internal void AddGlyph(char c, Glyph glyph)
{
_glyphs.Add(c, glyph);
}
internal void GetGlyphBoundingBox(Glyph glyph)
{
}
private Dictionary<char, Glyph> _glyphs = new();
}

View File

@@ -1,6 +1,13 @@
using System.Numerics;
using System.Runtime.InteropServices;
using FreeTypeSharp;
using Voile.VFS;
using static FreeTypeSharp.FT;
using static FreeTypeSharp.FT_LOAD;
using static FreeTypeSharp.FT_Render_Mode_;
namespace Voile.Resources;
public class FontLoader : ResourceLoader<Font>
@@ -10,7 +17,6 @@ public class FontLoader : ResourceLoader<Font>
".ttf"
};
protected override Font LoadResource(string path)
{
using Stream stream = VirtualFileSystem.Read(path);
@@ -21,6 +27,57 @@ public class FontLoader : ResourceLoader<Font>
result.BufferSize = bytesRead;
LoadFaceData(result);
return result;
}
private unsafe void LoadFaceData(Font font)
{
LoadFreeType();
fixed (FT_LibraryRec_** lib = &_lib)
{
fixed (FT_FaceRec_* face = &_face)
{
FT_Error error;
var buffer = new Memory<byte>(font.Buffer);
var handle = buffer.Pin();
error = FT_New_Memory_Face(*lib, (byte*)handle.Pointer, (nint)font.BufferSize, 0, &face);
error = FT_Set_Pixel_Sizes(face, 0, (uint)font.Size);
error = FT_Load_Char(face, 'F', FT_LOAD_NO_BITMAP);
var metrics = face->glyph->metrics;
font.AddGlyph('F', new Glyph()
{
Width = metrics.width >> 6,
Height = metrics.height >> 6,
Bearing = new Vector2(metrics.horiBearingX >> 6, metrics.horiBearingY >> 6),
Advance = (int)metrics.horiAdvance >> 6,
});
FT_Done_Face(face);
FT_Done_FreeType(*lib);
}
}
}
private unsafe void LoadFreeType()
{
fixed (FT_LibraryRec_** lib = &_lib)
{
FT_Error error;
if (_lib == null)
{
error = FT_Init_FreeType(lib);
}
}
}
private unsafe FT_LibraryRec_* _lib;
private unsafe FT_FaceRec_ _face;
}