using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Security; using System.IO; namespace SFML { namespace Graphics { //////////////////////////////////////////////////////////// /// /// Structure describing a glyph (a visual character) /// //////////////////////////////////////////////////////////// [StructLayout(LayoutKind.Sequential)] public struct Glyph { /// Offset to move horizontically to the next character public int Advance; /// Bounding rectangle of the glyph, in coordinates relative to the baseline public IntRect Rectangle; /// Texture coordinates of the glyph inside the font's image public FloatRect TexCoords; } //////////////////////////////////////////////////////////// /// /// Font is the low-level class for loading and /// manipulating character fonts. This class is meant to /// be used by String2D /// //////////////////////////////////////////////////////////// public class Font : ObjectBase { //////////////////////////////////////////////////////////// /// /// Construct the font from a file /// /// Font file to load /// //////////////////////////////////////////////////////////// public Font(string filename) : base(sfFont_CreateFromFile(filename)) { if (This == IntPtr.Zero) throw new LoadingFailedException("font", filename); } //////////////////////////////////////////////////////////// /// /// Construct the font from a file in a stream /// /// Stream containing the file contents /// //////////////////////////////////////////////////////////// public Font(Stream stream) : base(IntPtr.Zero) { unsafe { stream.Position = 0; byte[] StreamData = new byte[stream.Length]; uint Read = (uint)stream.Read(StreamData, 0, StreamData.Length); fixed (byte* dataPtr = StreamData) { SetThis(sfFont_CreateFromMemory((char*)dataPtr, Read)); } } if (This == IntPtr.Zero) throw new LoadingFailedException("font"); } //////////////////////////////////////////////////////////// /// /// Get a glyph in the font /// /// Unicode code point of the character to get /// Character size /// Retrieve the bold version or the regular one? /// The glyph corresponding to the character //////////////////////////////////////////////////////////// public Glyph GetGlyph(uint codePoint, uint characterSize, bool bold) { return sfFont_GetGlyph(This, codePoint, characterSize, bold); } //////////////////////////////////////////////////////////// /// /// Get the kerning offset between two glyphs /// /// Unicode code point of the first character /// Unicode code point of the second character /// Character size /// Kerning offset, in pixels //////////////////////////////////////////////////////////// public int GetKerning(uint first, uint second, uint characterSize) { return sfFont_GetKerning(This, first, second, characterSize); } //////////////////////////////////////////////////////////// /// /// Get spacing between two consecutive lines /// /// Character size /// Line spacing, in pixels //////////////////////////////////////////////////////////// public int GetLineSpacing(uint characterSize) { return sfFont_GetLineSpacing(This, characterSize); } //////////////////////////////////////////////////////////// /// /// Get the image containing the glyphs of a given size /// /// Character size /// Image storing the glyphs for the given size //////////////////////////////////////////////////////////// public Image GetImage(uint characterSize) { myImages[characterSize] = new Image(sfFont_GetImage(This, characterSize)); return myImages[characterSize]; } //////////////////////////////////////////////////////////// /// /// Default built-in font /// //////////////////////////////////////////////////////////// public static Font DefaultFont { get { if (ourDefaultFont == null) ourDefaultFont = new Font(sfFont_GetDefaultFont()); return ourDefaultFont; } } //////////////////////////////////////////////////////////// /// /// Handle the destruction of the object /// /// Is the GC disposing the object, or is it an explicit call ? //////////////////////////////////////////////////////////// protected override void Destroy(bool disposing) { if (this != ourDefaultFont) { if (!disposing) Context.Global.SetActive(true); sfFont_Destroy(This); if (disposing) { foreach (Image image in myImages.Values) image.Dispose(); } if (!disposing) Context.Global.SetActive(false); } } //////////////////////////////////////////////////////////// /// /// Internal constructor /// /// Pointer to the object in C library //////////////////////////////////////////////////////////// private Font(IntPtr thisPtr) : base(thisPtr) { } private Dictionary myImages = new Dictionary(); private static Font ourDefaultFont = null; #region Imports [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern IntPtr sfFont_CreateFromFile(string Filename); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] unsafe static extern IntPtr sfFont_CreateFromMemory(char* Data, uint SizeInBytes); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern void sfFont_Destroy(IntPtr This); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern Glyph sfFont_GetGlyph(IntPtr This, uint codePoint, uint characterSize, bool bold); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern int sfFont_GetKerning(IntPtr This, uint first, uint second, uint characterSize); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern int sfFont_GetLineSpacing(IntPtr This, uint characterSize); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern IntPtr sfFont_GetImage(IntPtr This, uint characterSize); [DllImport("csfml-graphics"), SuppressUnmanagedCodeSecurity] static extern IntPtr sfFont_GetDefaultFont(); #endregion } } }