From bc0a80dc20a77aac46a796ffdff91af647c8b194 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 2 Feb 2023 20:05:51 -0500 Subject: [PATCH] Reorganize and add comments --- src/{dft => }/dft.c | 50 ++++++++++- src/dft/dft.d | 197 ++++++++++++++++++++++++++++++++++++++++++++ src/dft/package.d | 105 +---------------------- 3 files changed, 246 insertions(+), 106 deletions(-) rename src/{dft => }/dft.c (77%) create mode 100644 src/dft/dft.d diff --git a/src/dft/dft.c b/src/dft.c similarity index 77% rename from src/dft/dft.c rename to src/dft.c index 9302a38..8ce6750 100644 --- a/src/dft/dft.c +++ b/src/dft.c @@ -8,6 +8,9 @@ #define round_up_26_6(val) (((val) + 63) >> 6u) +/** + * DFT font structure. + */ typedef struct { int32_t line_height; @@ -15,6 +18,9 @@ typedef struct FT_Face ft_face; } dft_font_t; +/** + * DFT glyph structure. + */ typedef struct { uint8_t * bitmap; @@ -26,10 +32,16 @@ typedef struct FT_Glyph ft_glyph; } dft_glyph_t; +/** FreeType library handle. */ static FT_Library ft_library_handle; + +/** Flag for whether we've already initialized FreeType. */ static bool ft_initialized; -static bool initialize_freetype() +/** + * Initialize the FreeType library. + */ +static bool initialize_freetype(void) { if (ft_initialized) { @@ -45,7 +57,15 @@ static bool initialize_freetype() 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) { 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; } +/** + * Free a DFT glyph structure. + * + * @param dft_glyph Pointer to DFT glyph structure. + */ void dft_glyph_free(dft_glyph_t * dft_glyph) { FT_Done_Glyph(dft_glyph->ft_glyph); @@ -90,6 +115,13 @@ void dft_glyph_free(dft_glyph_t * 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 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; } +/** + * 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) { 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; } +/** + * Free a DFT font structure. + * + * @param dft_font DFT font structure to free. + */ void dft_font_free(dft_font_t * dft_font) { FT_Done_Face(dft_font->ft_face); diff --git a/src/dft/dft.d b/src/dft/dft.d new file mode 100644 index 0000000..b3d7090 --- /dev/null +++ b/src/dft/dft.d @@ -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); + } +} diff --git a/src/dft/package.d b/src/dft/package.d index 79b5963..a408634 100644 --- a/src/dft/package.d +++ b/src/dft/package.d @@ -1,106 +1,3 @@ module dft; -import std.file; - -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); - } -} +public import dft.dft;