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");
}
////////////////////////////////////////////////////////////
///
/// Construct the font from another font
///
/// Font to copy
////////////////////////////////////////////////////////////
public Font(Font copy) :
base(sfFont_Copy(copy.This))
{
}
////////////////////////////////////////////////////////////
///
/// 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;
}
}
////////////////////////////////////////////////////////////
///
/// Provide a string describing the object
///
/// String description of the object
////////////////////////////////////////////////////////////
public override string ToString()
{
return "[Font]";
}
////////////////////////////////////////////////////////////
///
/// 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-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfFont_CreateFromFile(string Filename);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
unsafe static extern IntPtr sfFont_CreateFromMemory(char* Data, uint SizeInBytes);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfFont_Copy(IntPtr Font);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern void sfFont_Destroy(IntPtr This);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern Glyph sfFont_GetGlyph(IntPtr This, uint codePoint, uint characterSize, bool bold);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern int sfFont_GetKerning(IntPtr This, uint first, uint second, uint characterSize);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern int sfFont_GetLineSpacing(IntPtr This, uint characterSize);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfFont_GetImage(IntPtr This, uint characterSize);
[DllImport("csfml-graphics-2", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
static extern IntPtr sfFont_GetDefaultFont();
#endregion
}
}
}