From 6306c1e64743bb2d9d1428bac7e574504d3f6b7e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 17 Apr 2016 22:18:24 +0200 Subject: [PATCH] source/Graphics/Font/FontDriver.h: Add support for outlines. --- source/Graphics/Font/FontDriver.h | 2 +- source/Graphics/Font/FreeTypeDriver.cpp | 48 ++++++++++++++++++++----- source/Graphics/Font/FreeTypeDriver.h | 2 +- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/source/Graphics/Font/FontDriver.h b/source/Graphics/Font/FontDriver.h index 165c774..777a39d 100644 --- a/source/Graphics/Font/FontDriver.h +++ b/source/Graphics/Font/FontDriver.h @@ -18,7 +18,7 @@ public : virtual bool loadFromFile(const std::string& filename) = 0; - virtual Font::Glyph loadGlyph(unsigned int codepoint, Image& img) = 0; + virtual Font::Glyph loadGlyph(unsigned int codepoint, Image& img, unsigned int outlineSize = 0) = 0; virtual std::string getName() = 0; diff --git a/source/Graphics/Font/FreeTypeDriver.cpp b/source/Graphics/Font/FreeTypeDriver.cpp index 14dcf19..d910aac 100644 --- a/source/Graphics/Font/FreeTypeDriver.cpp +++ b/source/Graphics/Font/FreeTypeDriver.cpp @@ -3,6 +3,7 @@ #include FT_MODULE_H #include FT_LCD_FILTER_H +#include FT_STROKER_H #include #include "FreeTypeError.h" @@ -23,6 +24,8 @@ public : FT_Library handle; + FT_Stroker stroker; + private : LibWrapper(); @@ -34,14 +37,21 @@ LibWrapper::LibWrapper() FT_Error error = FT_Init_FreeType(&handle); if (error) { log("Could not initialize FreeType\n"); + return; } else { log("FreeType font driver was initialized.\n"); } + + error = FT_Stroker_New(handle, &stroker); } LibWrapper::~LibWrapper() { - FT_Error error = FT_Done_FreeType(handle); + FT_Error error; + + FT_Stroker_Done(stroker); + + error = FT_Done_FreeType(handle); if (error) { log("Could not close FreeType\n"); } @@ -92,10 +102,15 @@ bool FreeTypeDriver::loadFromFile(const std::string& filename) return true; } -Font::Glyph FreeTypeDriver::loadGlyph(unsigned int codepoint, Image& img) +Font::Glyph FreeTypeDriver::loadGlyph(unsigned int codepoint, Image& img, unsigned int outlineSize) { Font::Glyph glyph; - FT_Int32 flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; + FT_Glyph glyph_info; + FT_Int32 flags = FT_LOAD_TARGET_NORMAL; + + if (outlineSize > 0) { + flags |= FT_LOAD_NO_BITMAP; + } if (m_hinting) { flags |= FT_LOAD_FORCE_AUTOHINT; @@ -103,13 +118,30 @@ Font::Glyph FreeTypeDriver::loadGlyph(unsigned int codepoint, Image& img) flags |= FT_LOAD_NO_AUTOHINT; } - FT_Error error = FT_Load_Char(m_face, codepoint, flags); + if (FT_Load_Char(m_face, codepoint, flags) != 0) { + log("FreeType: failed to load glyph for character code '%c'\n", codepoint); + } + + FT_Error error = FT_Get_Glyph(m_face->glyph, &glyph_info); if (!error) { + FT_Glyph_Metrics& metrics = m_face->glyph->metrics; - + + if (outlineSize) { + FT_Stroker stroker = LibWrapper::getInstance().stroker; + + FT_Stroker_Set(stroker, outlineSize * 64, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINEJOIN_ROUND, + 0); + + FT_Glyph_Stroke(&glyph_info, stroker, false); + } + if (metrics.width > 0 && metrics.height > 0) { - FT_Bitmap& bmp = m_face->glyph->bitmap; + FT_Glyph_To_Bitmap(&glyph_info, FT_RENDER_MODE_NORMAL, 0, true); + FT_Bitmap& bmp = reinterpret_cast(glyph_info)->bitmap; img.create(PixelFormat::PF_Alpha, bmp.width, @@ -118,8 +150,8 @@ Font::Glyph FreeTypeDriver::loadGlyph(unsigned int codepoint, Image& img) glyph.offset.x = metrics.horiBearingX / (1 << 6); glyph.offset.y = metrics.horiBearingY / (1 << 6); - glyph.size.x = metrics.width / (1 << 6); - glyph.size.y = metrics.height / (1 << 6); + glyph.size.x = (metrics.width / (1 << 6)) + (outlineSize * 2); + glyph.size.y = (metrics.height / (1 << 6)) + (outlineSize * 2); } glyph.advance = static_cast(metrics.horiAdvance >> 6); diff --git a/source/Graphics/Font/FreeTypeDriver.h b/source/Graphics/Font/FreeTypeDriver.h index 3aa9743..d1204d6 100644 --- a/source/Graphics/Font/FreeTypeDriver.h +++ b/source/Graphics/Font/FreeTypeDriver.h @@ -17,7 +17,7 @@ public: virtual bool loadFromFile(const std::string& filename); - virtual Font::Glyph loadGlyph(unsigned int codepoint, Image& img); + virtual Font::Glyph loadGlyph(unsigned int codepoint, Image& img, unsigned int outlineSize = 0); virtual std::string getName();