Reorganize and add comments

This commit is contained in:
Josh Holtrop 2023-02-02 20:05:51 -05:00
parent e910eb6004
commit bc0a80dc20
3 changed files with 246 additions and 106 deletions

View File

@ -8,6 +8,9 @@
#define round_up_26_6(val) (((val) + 63) >> 6u) #define round_up_26_6(val) (((val) + 63) >> 6u)
/**
* DFT font structure.
*/
typedef struct typedef struct
{ {
int32_t line_height; int32_t line_height;
@ -15,6 +18,9 @@ typedef struct
FT_Face ft_face; FT_Face ft_face;
} dft_font_t; } dft_font_t;
/**
* DFT glyph structure.
*/
typedef struct typedef struct
{ {
uint8_t * bitmap; uint8_t * bitmap;
@ -26,10 +32,16 @@ typedef struct
FT_Glyph ft_glyph; FT_Glyph ft_glyph;
} dft_glyph_t; } dft_glyph_t;
/** FreeType library handle. */
static FT_Library ft_library_handle; static FT_Library ft_library_handle;
/** Flag for whether we've already initialized FreeType. */
static bool ft_initialized; static bool ft_initialized;
static bool initialize_freetype() /**
* Initialize the FreeType library.
*/
static bool initialize_freetype(void)
{ {
if (ft_initialized) if (ft_initialized)
{ {
@ -45,7 +57,15 @@ static bool initialize_freetype()
return true; return true;
} }
/* outline_size is in 64ths of a pixel. */ /**
* Create a new DFT glyph structure.
*
* @param dft_font Pointer to DFT font structure.
* @param char_code Character code to load.
* @param outline_size Thickness of outline in 1/64 pixels.
*
* @return Pointer to new DFT glyph structure.
*/
dft_glyph_t * dft_glyph_new(dft_font_t * dft_font, uint32_t char_code, int32_t outline_size) dft_glyph_t * dft_glyph_new(dft_font_t * dft_font, uint32_t char_code, int32_t outline_size)
{ {
FT_Glyph glyph; FT_Glyph glyph;
@ -83,6 +103,11 @@ dft_glyph_t * dft_glyph_new(dft_font_t * dft_font, uint32_t char_code, int32_t o
return dft_glyph; return dft_glyph;
} }
/**
* Free a DFT glyph structure.
*
* @param dft_glyph Pointer to DFT glyph structure.
*/
void dft_glyph_free(dft_glyph_t * dft_glyph) void dft_glyph_free(dft_glyph_t * dft_glyph)
{ {
FT_Done_Glyph(dft_glyph->ft_glyph); FT_Done_Glyph(dft_glyph->ft_glyph);
@ -90,6 +115,13 @@ void dft_glyph_free(dft_glyph_t * dft_glyph)
free(dft_glyph); free(dft_glyph);
} }
/**
* Build font metrics.
*
* This function determines vertical font extents from a few particular glyphs.
*
* @param dft_font Pointer to DFT font structure.
*/
static inline void build_font_metrics(dft_font_t * dft_font) static inline void build_font_metrics(dft_font_t * dft_font)
{ {
static const char load_chars[] = "Mg_^"; static const char load_chars[] = "Mg_^";
@ -115,6 +147,15 @@ static inline void build_font_metrics(dft_font_t * dft_font)
dft_font->baseline_offset = (dft_font->line_height - (max_top - min_bottom)) / 2 - min_bottom; dft_font->baseline_offset = (dft_font->line_height - (max_top - min_bottom)) / 2 - min_bottom;
} }
/**
* Create a new DFT font structure.
*
* @param file_data Pointer to font file data.
* @param file_size Length of font file data.
* @param font_size Font size to render.
*
* @return Pointer to new DFT font structure or NULL on error.
*/
dft_font_t * dft_font_new(const uint8_t * file_data, uint32_t file_size, int font_size) dft_font_t * dft_font_new(const uint8_t * file_data, uint32_t file_size, int font_size)
{ {
if (!initialize_freetype()) if (!initialize_freetype())
@ -139,6 +180,11 @@ dft_font_t * dft_font_new(const uint8_t * file_data, uint32_t file_size, int fon
return dft_font; return dft_font;
} }
/**
* Free a DFT font structure.
*
* @param dft_font DFT font structure to free.
*/
void dft_font_free(dft_font_t * dft_font) void dft_font_free(dft_font_t * dft_font)
{ {
FT_Done_Face(dft_font->ft_face); FT_Done_Face(dft_font->ft_face);

197
src/dft/dft.d Normal file
View File

@ -0,0 +1,197 @@
module dft.dft;
import std.file;
/**
* DFT font structure.
*/
private struct dft_font_t
{
int line_height;
int baseline_offset;
};
/**
* DFT glyph structure.
*/
private struct dft_glyph_t
{
ubyte * bitmap;
int width;
int height;
int left;
int top;
int advance;
};
/** DFT C functions. @{ */
private extern(C) dft_glyph_t * dft_glyph_new(dft_font_t * dft_font, uint char_code, int outline_size);
private extern(C) void dft_glyph_free(dft_glyph_t * dft_glyph);
private extern(C) dft_font_t * dft_font_new(const ubyte * file_data, uint file_size, int font_size);
private extern(C) void dft_font_free(dft_font_t * dft_font);
/** @} */
/**
* DFT Font object.
*
* A Font represents a single loaded font file.
*/
class Font
{
/**
* DFT Glyph object.
*/
class Glyph
{
/** Pointer to C DFT glyph structure. */
dft_glyph_t * m_dft_glyph;
/**
* Construct a Glyph object.
*
* @param font DFT Font object.
* @param char_code Character code to load for this Glyph.
* @param outline_size Thickness of outline in 1/64 pixels.
*/
private this(Font font, uint char_code, int outline_size)
{
m_dft_glyph = dft_glyph_new(font.m_dft_font, char_code, outline_size);
}
/**
* Destructor for Glyph object.
*/
~this()
{
dft_glyph_free(m_dft_glyph);
}
/**
* Get the glyph's width in pixels.
*
* @return The glyph's width in pixels.
*/
@property int width()
{
return m_dft_glyph.width;
}
/**
* Get the glyph's height in pixels.
*
* @return The glyph's height in pixels.
*/
@property int height()
{
return m_dft_glyph.height;
}
/**
* Get the glyph's left offset in pixels.
*
* @return The glyph's left offset in pixels.
*/
@property int left()
{
return m_dft_glyph.left;
}
/**
* Get the glyph's top offset in pixels.
*
* @return The glyph's top offset in pixels.
*/
@property int top()
{
return m_dft_glyph.top;
}
/**
* Get the glyph's advance in pixels.
*
* @return The glyph's advance in pixels.
*/
@property int advance()
{
return m_dft_glyph.advance;
}
/**
* Get the glyph's bitmap image.
*
* @return The glyph's bitmap image.
*/
@property const(ubyte)[] bitmap()
{
int n_bytes = width * height;
return m_dft_glyph.bitmap[0..n_bytes];
}
}
/** Pointer to C DFT font structure. */
dft_font_t * m_dft_font;
/**
* Construct a DFT Font object from font file data in memory.
*
* @param file_data Font file data.
* @param font_size Font size to render.
*/
this(const(ubyte)[] file_data, int font_size)
{
m_dft_font = dft_font_new(file_data.ptr, cast(uint)file_data.length, font_size);
}
/**
* Construct a DFT Font object from a font file in the file system.
*
* @param file_name Font file name.
* @param font_size Font size to render.
*/
this(string file_name, int font_size)
{
const(ubyte)[] file_data = cast(const(ubyte)[])std.file.read(file_name);
this(file_data, font_size);
}
/**
* Destructor for DFT Font object.
*/
~this()
{
dft_font_free(m_dft_font);
}
/**
* Get the font's line height in pixels.
*
* @return The font's line height in pixels.
*/
@property int line_height()
{
return m_dft_font.line_height;
}
/**
* Get the font's baseline offset in pixels.
*
* @return The font's baseline offset in pixels.
*/
@property int baseline_offset()
{
return m_dft_font.baseline_offset;
}
/**
* Load a glyph for the given character code and outline size.
*
* @param char_code Character code to render.
* @param outline_size Thickness of outline in 1/64 pixels.
*
* @return The Glyph object.
*/
Glyph get_glyph(uint char_code, int outline_size)
{
return new Glyph(this, char_code, outline_size);
}
}

View File

@ -1,106 +1,3 @@
module dft; module dft;
import std.file; public import dft.dft;
private struct dft_font_t
{
int line_height;
int baseline_offset;
};
private struct dft_glyph_t
{
ubyte * bitmap;
int width;
int height;
int left;
int top;
int advance;
};
private extern(C) dft_glyph_t * dft_glyph_new(dft_font_t * dft_font, uint char_code, int outline_size);
private extern(C) void dft_glyph_free(dft_glyph_t * dft_glyph);
private extern(C) dft_font_t * dft_font_new(const ubyte * file_data, uint file_size, int font_size);
private extern(C) void dft_font_free(dft_font_t * dft_font);
class Font
{
class Glyph
{
dft_glyph_t * m_dft_glyph;
private this(Font font, uint char_code, int outline_size)
{
m_dft_glyph = dft_glyph_new(font.m_dft_font, char_code, outline_size);
}
~this()
{
dft_glyph_free(m_dft_glyph);
}
@property int width()
{
return m_dft_glyph.width;
}
@property int height()
{
return m_dft_glyph.height;
}
@property int left()
{
return m_dft_glyph.left;
}
@property int top()
{
return m_dft_glyph.top;
}
@property int advance()
{
return m_dft_glyph.advance;
}
@property const(ubyte)[] bitmap()
{
int n_bytes = width * height;
return m_dft_glyph.bitmap[0..n_bytes];
}
}
dft_font_t * m_dft_font;
this(const(ubyte)[] file_data, int font_size)
{
m_dft_font = dft_font_new(file_data.ptr, cast(uint)file_data.length, font_size);
}
this(string file_name, int font_size)
{
const(ubyte)[] file_data = cast(const(ubyte)[])std.file.read(file_name);
this(file_data, font_size);
}
~this()
{
dft_font_free(m_dft_font);
}
@property int line_height()
{
return m_dft_font.line_height;
}
@property int baseline_offset()
{
return m_dft_font.baseline_offset;
}
Glyph get_glyph(uint char_code, int outline_size)
{
return new Glyph(this, char_code, outline_size);
}
}