diff --git a/ZenKit/Font.cs b/ZenKit/Font.cs
index c9977de..9049888 100644
--- a/ZenKit/Font.cs
+++ b/ZenKit/Font.cs
@@ -1,48 +1,132 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Numerics;
using System.Runtime.InteropServices;
using ZenKit.Util;
namespace ZenKit
{
+ ///
+ /// A single font glyph.
+ ///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct FontGlyph
{
+ ///
+ /// The width of the glyph in pixels.
+ ///
[MarshalAs(UnmanagedType.U1)] public byte width;
+
+ ///
+ /// The position of the top left corner of the glyph in the font texture.
+ /// This value is not stored as absolute pixels but rather in percent of the width and
+ /// height of the image. Thus to calculate the real pixel position of the top left corner,
+ /// one multiplies `topLeft.x` by the width of the font texture and `topLeft.y` by its height.
+ ///
+ ///
public Vector2 topLeft;
+
+ ///
+ /// The position of the bottom right corner of the glyph in the font texture.
+ /// This value is not stored as absolute pixels but rather in percent of the width and
+ /// height of the image. Thus to calculate the real pixel position of the bottom right corner,
+ /// one multiplies `bottomRight.x` by the width of the font texture and `bottomRight.y` by its height.
+ ///
+ ///
public Vector2 bottomRight;
}
+ ///
+ /// Represents a ZenGin font file.
+ /// Fonts in the ZenGin consist of a font definition file and a font texture. This class represents the former.
+ /// Font
+ /// definition files contain a set of glyphs which define the extents of a
+ /// Windows-1252 encoded character within the font texture
+ /// file. Font files can be identified most easily by their .FNT extension or alternatively through the
+ /// "1\n"
+ /// string at the beginning of the file.
+ ///
+ ///
public interface IFont : ICacheable
{
+ ///
+ /// The name of this font.
+ ///
public string Name { get; }
+
+ ///
+ /// The height of each glyph of this font in pixels.
+ ///
public int Height { get; }
+
+ ///
+ /// All glyphs of this font.
+ /// ZenGin fonts contain characters present in the
+ /// Windows-1252 character encoding
+ /// which is generally used by Gothic and Gothic II. The returned list contains these glyphs in order.
+ /// Some glyphs may not actually be present in the font texture. For those glyphs, the stored UV-coordinates will be
+ /// invalid in some way (ie. they may point to a pixel not actually in the texture or be negative).
+ ///
+ ///
+ /// Repeated access to this property will lead to poor performance if access to a native ZenKit object is
+ /// required. Either cache the value in a variable or use .
+ ///
+ ///
public List Glyphs { get; }
+
+ ///
+ /// The total number of glyphs stored in this font.
+ ///
public int GlyphCount { get; }
+ ///
+ /// Get a single glyph of this font.
+ ///
+ ///
+ /// The index of the glyph to get. Corresponds to a
+ /// Windows-1252 code point.
+ ///
+ /// The font glyph at the given
+ ///
+ ///
+ ///
public FontGlyph GetGlyph(int index);
}
+ ///
+ /// A ZenKit font object which has been fully loaded into C#. An object of this type is independent from any native
+ /// object and incurs none of its disadvantages.
+ ///
[Serializable]
public class CachedFont : IFont
{
+ ///
public string Name { get; set; }
+
+ ///
public int Height { get; set; }
+
+ ///
public List Glyphs { get; set; }
+
+ ///
public int GlyphCount => Glyphs.Count;
+ ///
public IFont Cache()
{
return this;
}
+ ///
public bool IsCached()
{
return true;
}
+ ///
public FontGlyph GetGlyph(int index)
{
return Glyphs[index];
@@ -53,36 +137,77 @@ public class Font : IFont
{
private readonly UIntPtr _handle;
+ ///
+ /// Loads a ZenGin font from the given file on disk using ZenKit.
+ ///
+ ///
+ /// For example:
+ ///
+ /// var font = new Font("FONT_OLD_20.FNT");
+ ///
+ ///
+ /// The path of the font file (usually ends in .FNT.
+ /// Thrown if loading the font fails for any reason.
public Font(string path)
{
_handle = Native.ZkFont_loadPath(path);
- if (_handle == UIntPtr.Zero) throw new Exception("Failed to load font");
+ if (_handle == UIntPtr.Zero) throw new IOException("Failed to load font");
}
+ ///
+ /// Loads a ZenGin font from the given stream.
+ ///
+ ///
+ /// For example:
+ ///
+ /// var rd = new Read("FONT_OLD_20.FNT");
+ /// var font = new Font(rd);
+ ///
+ ///
+ /// The stream to read from.
+ /// Thrown if loading the font fails for any reason.
public Font(Read r)
{
_handle = Native.ZkFont_load(r.Handle);
if (_handle == UIntPtr.Zero) throw new Exception("Failed to load font");
}
+ ///
+ /// Loads a ZenGin font from the given file on disk using ZenKit.
+ ///
+ ///
+ /// For example:
+ ///
+ /// var vfs = new Vfs();
+ /// vfs.MountDisk("Textures.vdf", VfsOverwriteBehavior.Older);
+ /// var font = new Font(vfs, "FONT_OLD_20.FNT");
+ ///
+ ///
+ ///
+ ///
+ /// Thrown if loading the font fails for any reason.
public Font(Vfs vfs, string name)
{
_handle = Native.ZkFont_loadVfs(vfs.Handle, name);
if (_handle == UIntPtr.Zero) throw new Exception("Failed to load font");
}
+ ///
public string Name => Native.ZkFont_getName(_handle).MarshalAsString() ??
throw new Exception("Failed to load font name");
+ ///
public int Height => (int)Native.ZkFont_getHeight(_handle);
+ ///
public int GlyphCount => (int)Native.ZkFont_getGlyphCount(_handle);
+ ///
public List Glyphs
{
get
{
- var glyphs = new List(256);
+ var glyphs = new List(GlyphCount);
Native.ZkFont_enumerateGlyphs(_handle, (_, glyph) =>
{
@@ -94,6 +219,7 @@ public List Glyphs
}
}
+ ///
public IFont Cache()
{
return new CachedFont
@@ -104,11 +230,13 @@ public IFont Cache()
};
}
+ ///
public bool IsCached()
{
return false;
}
+ ///
public FontGlyph GetGlyph(int index)
{
return Native.ZkFont_getGlyph(_handle, (ulong)index);