From 3e70fa27d9c4f90d29afde72a7443c38d719a064 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 22 Oct 2016 00:01:48 +0800 Subject: [PATCH] Add doxygen for Font modules Plus some coding-style cleanup --- src/font/bold_face.cpp | 14 +- src/font/bold_face.hpp | 12 +- src/font/digit_face.cpp | 5 +- src/font/digit_face.hpp | 5 +- src/font/face_ttf.cpp | 14 +- src/font/face_ttf.hpp | 19 ++- src/font/font_manager.cpp | 24 ++-- src/font/font_manager.hpp | 35 ++++- src/font/font_settings.hpp | 30 ++++- src/font/font_with_face.cpp | 107 ++++++++++++---- src/font/font_with_face.hpp | 121 +++++++++++++++--- src/font/regular_face.cpp | 5 +- src/font/regular_face.hpp | 7 +- src/guiengine/engine.cpp | 2 + src/guiengine/scalable_font.cpp | 1 + .../widgets/dynamic_ribbon_widget.cpp | 1 + src/karts/kart.cpp | 1 + src/main.cpp | 2 + src/scriptengine/script_track.cpp | 1 + src/states_screens/options_screen_ui.cpp | 1 + src/utils/debug.cpp | 1 + 21 files changed, 322 insertions(+), 86 deletions(-) diff --git a/src/font/bold_face.cpp b/src/font/bold_face.cpp index e9192de14..4f7ae33df 100644 --- a/src/font/bold_face.cpp +++ b/src/font/bold_face.cpp @@ -18,9 +18,10 @@ #include "font/bold_face.hpp" -#include "font/face_ttf.hpp" - // ---------------------------------------------------------------------------- +/** Constructor of BoldFace. + * \param ttf \ref FaceTTF for BoldFace to use. + */ BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf) { } // BoldFace @@ -53,3 +54,12 @@ void BoldFace::reset() insertCharacters(preload_chars.c_str()); updateCharactersList(); } // reset + +// ---------------------------------------------------------------------------- +/** Embolden the glyph to make bold font using FT_Outline_Embolden. + * \return A FT_Error value. + */ +int BoldFace::shapeOutline(FT_Outline* outline) const +{ + return FT_Outline_Embolden(outline, getDPI() * 2); +} // shapeOutline diff --git a/src/font/bold_face.hpp b/src/font/bold_face.hpp index 53ddce8f5..e9455395b 100644 --- a/src/font/bold_face.hpp +++ b/src/font/bold_face.hpp @@ -23,24 +23,28 @@ class FaceTTF; +/** A font which uses regular TTFs to render title or important message in STK + * with a bold outline, it shares the same \ref FaceTTF with \ref RegularFace. + * \ingroup font + */ class BoldFace : public FontWithFace { private: - virtual bool supportLazyLoadChar() const OVERRIDE { return true; } - // ------------------------------------------------------------------------ virtual unsigned int getGlyphPageSize() const OVERRIDE { return 1024; } // ------------------------------------------------------------------------ virtual float getScalingFactorOne() const OVERRIDE { return 0.2f; } // ------------------------------------------------------------------------ virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 120; } + // ------------------------------------------------------------------------ + virtual bool isBold() const { return true; } + // ------------------------------------------------------------------------ + virtual int shapeOutline(FT_Outline* outline) const OVERRIDE; public: LEAK_CHECK() // ------------------------------------------------------------------------ BoldFace(FaceTTF* ttf); // ------------------------------------------------------------------------ - virtual ~BoldFace() {} - // ------------------------------------------------------------------------ virtual void init() OVERRIDE; // ------------------------------------------------------------------------ virtual void reset() OVERRIDE; diff --git a/src/font/digit_face.cpp b/src/font/digit_face.cpp index 2403c4d6d..24ca94ef0 100644 --- a/src/font/digit_face.cpp +++ b/src/font/digit_face.cpp @@ -18,9 +18,10 @@ #include "font/digit_face.hpp" -#include "font/face_ttf.hpp" - // ---------------------------------------------------------------------------- +/** Constructor of DigitFace. + * \param ttf \ref FaceTTF for DigitFace to use. + */ DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf) { } // DigitFace diff --git a/src/font/digit_face.hpp b/src/font/digit_face.hpp index 35bbdb248..a5aed4dab 100644 --- a/src/font/digit_face.hpp +++ b/src/font/digit_face.hpp @@ -23,6 +23,9 @@ class FaceTTF; +/** A font which uses a more cartonish style TTF to render big numbers in STK. + * \ingroup font + */ class DigitFace : public FontWithFace { private: @@ -39,8 +42,6 @@ public: // ------------------------------------------------------------------------ DigitFace(FaceTTF* ttf); // ------------------------------------------------------------------------ - virtual ~DigitFace() {} - // ------------------------------------------------------------------------ virtual void init() OVERRIDE; // ------------------------------------------------------------------------ virtual void reset() OVERRIDE; diff --git a/src/font/face_ttf.cpp b/src/font/face_ttf.cpp index fdb64d572..fb496f590 100644 --- a/src/font/face_ttf.cpp +++ b/src/font/face_ttf.cpp @@ -18,22 +18,29 @@ #include "font/face_ttf.hpp" +#include "font/font_manager.hpp" #include "io/file_manager.hpp" // ---------------------------------------------------------------------------- +/** Constructor. Load all TTFs from a list. + * \param ttf_list List of TTFs to be loaded. + */ FaceTTF::FaceTTF(const std::vector& ttf_list) { for (const std::string& font : ttf_list) { FT_Face face = NULL; + const std::string loc = file_manager + ->getAssetChecked(FileManager::TTF, font.c_str(), true); font_manager->checkFTError(FT_New_Face(font_manager->getFTLibrary(), - (file_manager->getAssetChecked(FileManager::TTF, - font.c_str(), true)).c_str(), 0, &face), "loading fonts"); + loc.c_str(), 0, &face), loc + " is loaded"); m_faces.push_back(face); } } // FaceTTF // ---------------------------------------------------------------------------- +/** Destructor. Clears all TTFs. + */ FaceTTF::~FaceTTF() { for (unsigned int i = 0; i < m_faces.size(); i++) @@ -42,6 +49,9 @@ FaceTTF::~FaceTTF() } } // ~FaceTTF // ---------------------------------------------------------------------------- +/** Return a TTF in \ref m_faces. + * \param i index of TTF file in \ref m_faces. + */ FT_Face FaceTTF::getFace(unsigned int i) const { assert(i < m_faces.size()); diff --git a/src/font/face_ttf.hpp b/src/font/face_ttf.hpp index 90663dab5..6fb1e8c44 100644 --- a/src/font/face_ttf.hpp +++ b/src/font/face_ttf.hpp @@ -19,15 +19,29 @@ #ifndef HEADER_FACE_TTF_HPP #define HEADER_FACE_TTF_HPP -#include "font/font_manager.hpp" +#include "utils/leak_check.hpp" +#include "utils/no_copy.hpp" +#include + +#include +#include FT_FREETYPE_H + +/** This class will load a list of TTF files from \ref STKConfig, and save + * them inside \ref m_faces for \ref FontWithFace to load glyph. + * Each FaceTTF can be used more than once in each instantiation of \ref + * FontWithFace, so it can render characters differently using the same TTF + * file to save memory, for example different outline size. + * \ingroup font + */ class FaceTTF : public NoCopy { private: + /** Contains all TTF files loaded. */ std::vector m_faces; public: - LEAK_CHECK(); + LEAK_CHECK() // ------------------------------------------------------------------------ FaceTTF(const std::vector& ttf_list); // ------------------------------------------------------------------------ @@ -35,6 +49,7 @@ public: // ------------------------------------------------------------------------ FT_Face getFace(unsigned int i) const; // ------------------------------------------------------------------------ + /** Return the total TTF files loaded. */ unsigned int getTotalFaces() const { return m_faces.size(); } }; // FaceTTF diff --git a/src/font/font_manager.cpp b/src/font/font_manager.cpp index 82de84b3c..52a893de3 100644 --- a/src/font/font_manager.cpp +++ b/src/font/font_manager.cpp @@ -28,15 +28,22 @@ FontManager *font_manager = NULL; // ---------------------------------------------------------------------------- +/** Constructor. It will initialize the \ref m_ft_library. + */ FontManager::FontManager() { checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library"); } // FontManager // ---------------------------------------------------------------------------- +/** Destructor. Clears all fonts and related stuff. + */ FontManager::~FontManager() { - m_fonts.clearAndDeleteAll(); + for (unsigned int i = 0; i < m_fonts.size(); i++) + delete m_fonts[i]; + m_fonts.clear(); + delete m_normal_ttf; m_normal_ttf = NULL; delete m_digit_ttf; @@ -47,6 +54,8 @@ FontManager::~FontManager() } // ~FontManager // ---------------------------------------------------------------------------- +/** Initialize all \ref FaceTTF and \ref FontWithFace members. + */ void FontManager::loadFonts() { // First load the TTF files required by each font @@ -72,15 +81,10 @@ void FontManager::loadFonts() } // loadFonts // ---------------------------------------------------------------------------- -void FontManager::checkFTError(FT_Error err, const std::string& desc) const -{ - if (err > 0) - { - Log::error("FontManager", "Something wrong when %s!", desc.c_str()); - } -} // checkFTError - -// ---------------------------------------------------------------------------- +/** Unit testing that will try to load all translations in STK, and discover if + * there is any characters required by it are not supported in \ref + * m_normal_ttf. + */ void FontManager::unitTesting() { std::vector list = *(translations->getLanguageList()); diff --git a/src/font/font_manager.hpp b/src/font/font_manager.hpp index f46249944..156cd771c 100644 --- a/src/font/font_manager.hpp +++ b/src/font/font_manager.hpp @@ -19,14 +19,18 @@ #ifndef HEADER_FONT_MANAGER_HPP #define HEADER_FONT_MANAGER_HPP +/** \defgroup font Font + * This module stores font files and tools used to draw characters in STK. + */ + #include "utils/leak_check.hpp" #include "utils/log.hpp" #include "utils/no_copy.hpp" -#include "utils/ptr_vector.hpp" #include #include #include +#include #include #include FT_FREETYPE_H @@ -34,17 +38,26 @@ class FaceTTF; class FontWithFace; +/** This class stores all font files required in STK. + * \ingroup font + */ class FontManager : public NoCopy { private: - PtrVector m_fonts; + /** Stores all \ref FontWithFace used in STK. */ + std::vector m_fonts; + /** A FreeType library, it holds the FT_Face internally inside freetype. */ FT_Library m_ft_library; + /** TTF files used in \ref BoldFace and \ref RegularFace. */ FaceTTF* m_normal_ttf; + /** TTF files used in \ref DigitFace. */ FaceTTF* m_digit_ttf; + /** Map type for each \ref FontWithFace with a index, save getting time in + * \ref getFont. */ std::unordered_map m_font_type_map; public: @@ -54,11 +67,12 @@ public: // ------------------------------------------------------------------------ ~FontManager(); // ------------------------------------------------------------------------ + /** Return a specfic type of \ref FontWithFace found in \ref m_fonts. */ template T* getFont() { T* out = NULL; const unsigned int n = m_font_type_map[std::type_index(typeid(T))]; - out = dynamic_cast(m_fonts.get(n)); + out = dynamic_cast(m_fonts[n]); if (out != NULL) { return out; @@ -68,16 +82,23 @@ public: } // ------------------------------------------------------------------------ /** Check for any error discovered in a freetype function that will return - * a FT_Error value. + * a FT_Error value, and log into the terminal. * \param err The Freetype function. - * \param desc The description of what is the function doing. - */ - void checkFTError(FT_Error err, const std::string& desc) const; + * \param desc The description of what is the function doing. */ + void checkFTError(FT_Error err, const std::string& desc) const + { + if (err > 0) + { + Log::error("FontManager", "Something wrong when %s! The error " + "code was %d.", desc.c_str(), err); + } + } // ------------------------------------------------------------------------ void loadFonts(); // ------------------------------------------------------------------------ void unitTesting(); // ------------------------------------------------------------------------ + /** Return the \ref m_ft_library. */ FT_Library getFTLibrary() const { return m_ft_library; } }; // FontManager diff --git a/src/font/font_settings.hpp b/src/font/font_settings.hpp index a833b8c9f..3dc183584 100644 --- a/src/font/font_settings.hpp +++ b/src/font/font_settings.hpp @@ -25,21 +25,34 @@ using namespace irr; +/** This class stores settings when rendering fonts, used when instantiating + * \ref irr::gui::ScalableFont. + * \ingroup font + */ class FontSettings { private: + /** True if black border will be drawn when rendering. */ bool m_black_border; + /** If true, characters will have right alignment when rendering, for RTL + * language. */ bool m_rtl; + /** Scaling when rendering. */ float m_scale; + /** True if shadow will be drawn when rendering. */ bool m_shadow; + /** Save the color of shadow when rendering. */ video::SColor m_shadow_color; + public: LEAK_CHECK() // ------------------------------------------------------------------------ + /** Constructor. It will initialize all members with default values if no + * parameter is given. */ FontSettings(bool black_border = false, bool rtl = false, float scale = 1.0f, bool shadow = false, const video::SColor& color = video::SColor(0, 0, 0, 0)) @@ -51,26 +64,39 @@ public: m_shadow_color = color; } // ------------------------------------------------------------------------ - ~FontSettings() {} - // ------------------------------------------------------------------------ + /** Set the scaling. + * \param scale Scaling to be set. */ void setScale(float scale) { m_scale = scale; } // ------------------------------------------------------------------------ + /** Return the scaling. */ float getScale() const { return m_scale; } // ------------------------------------------------------------------------ + /** Set the color of shadow. + * \param col The color of shadow to be set. */ void setShadowColor(const video::SColor &col) { m_shadow_color = col; } // ------------------------------------------------------------------------ + /** Return the color of shadow. */ const video::SColor& getShadowColor() const { return m_shadow_color; } // ------------------------------------------------------------------------ + /** Return if shadow is enabled. */ bool useShadow() const { return m_shadow; } // ------------------------------------------------------------------------ + /** Set whether shadow is enabled. + * \param shadow If it's enabled. */ void setShadow(bool shadow) { m_shadow = shadow; } // ------------------------------------------------------------------------ + /** Set whether black border is enabled. + * \param border If it's enabled. */ void setBlackBorder(bool border) { m_black_border = border; } // ------------------------------------------------------------------------ + /** Return if black border is enabled. */ bool useBlackBorder() const { return m_black_border; } // ------------------------------------------------------------------------ + /** Set right text alignment for RTL language. + * \param rtl If it's enabled. */ void setRTL(bool rtl) { m_rtl = rtl; } // ------------------------------------------------------------------------ + /** Return if right text alignment for RTL language is enabled. */ bool isRTL() const { return m_rtl; } }; // FontSettings diff --git a/src/font/font_with_face.cpp b/src/font/font_with_face.cpp index 7dedffbef..08128fe5d 100644 --- a/src/font/font_with_face.cpp +++ b/src/font/font_with_face.cpp @@ -18,17 +18,20 @@ #include "font/font_with_face.hpp" -#include "font/bold_face.hpp" #include "font/face_ttf.hpp" +#include "font/font_manager.hpp" +#include "font/font_settings.hpp" #include "graphics/2dutils.hpp" #include "graphics/irr_driver.hpp" #include "guiengine/engine.hpp" #include "guiengine/skin.hpp" #include "utils/string_utils.hpp" -#include FT_OUTLINE_H - // ---------------------------------------------------------------------------- +/** Constructor. It will initialize the \ref m_spritebank and TTF files to use. + * \param name The name of face, used by irrlicht to distinguish spritebank. + * \param ttf \ref FaceTTF for this face to use. + */ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf) { m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str()); @@ -43,6 +46,8 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf) } // FontWithFace // ---------------------------------------------------------------------------- +/** Destructor. Clears the glyph page and sprite bank. + */ FontWithFace::~FontWithFace() { m_page->drop(); @@ -56,6 +61,8 @@ FontWithFace::~FontWithFace() } // ~FontWithFace // ---------------------------------------------------------------------------- +/** Initialize the font structure, but don't load glyph here. + */ void FontWithFace::init() { setDPI(); @@ -83,7 +90,11 @@ void FontWithFace::init() reset(); } // init + // ---------------------------------------------------------------------------- +/** Clear all the loaded characters, sub-class can do pre-loading of characters + * after this. + */ void FontWithFace::reset() { m_new_char_holder.clear(); @@ -94,6 +105,12 @@ void FontWithFace::reset() } // reset // ---------------------------------------------------------------------------- +/** Convert a character to a glyph index in one of the font in \ref m_face_ttf, + * it will find the first TTF that supports this character, if the final + * glyph_index is 0, this means such character is not supported by all TTFs in + * \ref m_face_ttf. + * \param c The character to be loaded. + */ void FontWithFace::loadGlyphInfo(wchar_t c) { unsigned int font_number = 0; @@ -108,11 +125,12 @@ void FontWithFace::loadGlyphInfo(wchar_t c) } // loadGlyphInfo // ---------------------------------------------------------------------------- +/** Create a new glyph page by filling it with transparent content. + */ void FontWithFace::createNewGlyphPage() { - // Clean the current glyph page by filling it with transparent content m_page->fill(video::SColor(0, 255, 255, 255)); - m_temp_height = 0; + m_current_height = 0; m_used_width = 0; m_used_height = 0; @@ -140,6 +158,10 @@ void FontWithFace::createNewGlyphPage() } // createNewGlyphPage // ---------------------------------------------------------------------------- +/** Render a glyph for a character into bitmap and save it into the glyph page. + * \param c The character to be loaded. + * \param c \ref GlyphInfo for the character. + */ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) { assert(gi.glyph_index > 0); @@ -147,7 +169,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) FT_Face cur_face = m_face_ttf->getFace(gi.font_number); FT_GlyphSlot slot = cur_face->glyph; - // Faces may be shared across regular and bold, + // Same face may be shared across the different FontWithFace, // so reset dpi each time font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()), "setting DPI"); @@ -155,15 +177,11 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index, FT_LOAD_DEFAULT), "loading a glyph"); - if (dynamic_cast(this) != NULL) - { - // Embolden the outline of the glyph - font_manager->checkFTError(FT_Outline_Embolden(&(slot->outline), - getDPI() * 2), "embolden a glyph"); - } + font_manager->checkFTError(shapeOutline(&(slot->outline)), + "shaping outline"); font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL), - "render a glyph to bitmap"); + "rendering a glyph to bitmap"); // Convert to an anti-aliased bitmap FT_Bitmap bits = slot->bitmap; @@ -176,7 +194,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) true, 0); if ((m_used_width + texture_size.Width > getGlyphPageSize() && - m_used_height + m_temp_height + texture_size.Height > + m_used_height + m_current_height + texture_size.Height > getGlyphPageSize()) || m_used_height + texture_size.Height > getGlyphPageSize()) { @@ -244,8 +262,8 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) if (m_used_width + texture_size.Width > getGlyphPageSize()) { m_used_width = 0; - m_used_height += m_temp_height; - m_temp_height = 0; + m_used_height += m_current_height; + m_current_height = 0; } // Copy to the full glyph page @@ -283,11 +301,13 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi) // Store used area m_used_width += texture_size.Width; - if (m_temp_height < texture_size.Height) - m_temp_height = texture_size.Height; + if (m_current_height < texture_size.Height) + m_current_height = texture_size.Height; } // insertGlyph // ---------------------------------------------------------------------------- +/** Update the supported characters for this font if required. + */ void FontWithFace::updateCharactersList() { if (m_fallback_font != NULL) @@ -321,6 +341,10 @@ void FontWithFace::updateCharactersList() } // updateCharactersList // ---------------------------------------------------------------------------- +/** Write the current glyph page in png inside current running directory. + * Mainly for debug use. + * \param name The file name. + */ void FontWithFace::dumpGlyphPage(const std::string& name) { for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++) @@ -341,20 +365,23 @@ void FontWithFace::dumpGlyphPage(const std::string& name) } // dumpGlyphPage // ---------------------------------------------------------------------------- +/** Write the current glyph page in png inside current running directory. + * Useful in gdb without parameter. + */ void FontWithFace::dumpGlyphPage() { dumpGlyphPage("face"); } // dumpGlyphPage // ---------------------------------------------------------------------------- +/** Set the face dpi which is resolution-dependent. + * Normal text will range from 0.8, in 640x* resolutions (won't scale below + * that) to 1.0, in 1024x* resolutions, and linearly up. + * Bold text will range from 0.2, in 640x* resolutions (won't scale below + * that) to 0.4, in 1024x* resolutions, and linearly up. + */ void FontWithFace::setDPI() { - // Set face dpi: - // Font size is resolution-dependent. - // Normal text will range from 0.8, in 640x* resolutions (won't scale - // below that) to 1.0, in 1024x* resolutions, and linearly up - // Bold text will range from 0.2, in 640x* resolutions (won't scale - // below that) to 0.4, in 1024x* resolutions, and linearly up const int screen_width = irr_driver->getFrameSize().Width; const int screen_height = irr_driver->getFrameSize().Height; float scale = std::max(0, screen_width - 640) / 564.0f; @@ -371,6 +398,10 @@ void FontWithFace::setDPI() } // setDPI // ---------------------------------------------------------------------------- +/** Return the \ref FontArea about a character. + * \param c The character to get. + * \param[out] fallback_font Whether fallback font is used. + */ const FontWithFace::FontArea& FontWithFace::getAreaFromCharacter(const wchar_t c, bool* fallback_font) const @@ -397,6 +428,12 @@ const FontWithFace::FontArea& } // getAreaFromCharacter // ---------------------------------------------------------------------------- +/** Get the dimension of text with support to different \ref FontSettings, + * it will also do checking for missing characters in font and lazy load them. + * \param text The text to be calculated. + * \param font_settings \ref FontSettings to use. + * \return The dimension of text + */ core::dimension2d FontWithFace::getDimension(const wchar_t* text, FontSettings* font_settings) { @@ -441,6 +478,12 @@ core::dimension2d FontWithFace::getDimension(const wchar_t* text, } // getDimension // ---------------------------------------------------------------------------- +/** Calculate the index of the character in the text on a specific position. + * \param text The text to be calculated. + * \param pixel_x The specific position. + * \param font_settings \ref FontSettings to use. + * \return The index of the character, -1 means no character in such position. + */ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x, FontSettings* font_settings) const { @@ -466,6 +509,17 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x, } // getCharacterFromPos // ---------------------------------------------------------------------------- +/** Render text and clip it to the specified rectangle if wanted, it will also + * do checking for missing characters in font and lazy load them. + * \param text The text to be rendering. + * \param position The position to be rendering. + * \param color The color used when rendering. + * \param hcenter If rendered horizontally center. + * \param vcenter If rendered vertically center. + * \param clip If clipping is needed. + * \param font_settings \ref FontSettings to use. + * \param char_collector \ref FontCharCollector to render billboard text. + */ void FontWithFace::render(const core::stringw& text, const core::rect& position, const video::SColor& color, bool hcenter, @@ -473,7 +527,6 @@ void FontWithFace::render(const core::stringw& text, FontSettings* font_settings, FontCharCollector* char_collector) { - const bool is_bold_face = (dynamic_cast(this) != NULL); const bool black_border = font_settings ? font_settings->useBlackBorder() : false; const bool rtl = font_settings ? font_settings->isRTL() : false; @@ -621,7 +674,7 @@ void FontWithFace::render(const core::stringw& text, const int sprite_amount = sprites.size(); - if ((black_border || is_bold_face) && char_collector == NULL) + if ((black_border || isBold()) && char_collector == NULL) { // Draw black border first, to make it behind the real character // which make script language display better @@ -693,7 +746,7 @@ void FontWithFace::render(const core::stringw& text, m_fallback_font->m_spritebank->getTexture(tex_id) : m_spritebank->getTexture(tex_id)); - if (fallback[n] || is_bold_face) + if (fallback[n] || isBold()) { video::SColor top = GUIEngine::getSkin()->getColor("font::top"); video::SColor bottom = GUIEngine::getSkin() diff --git a/src/font/font_with_face.hpp b/src/font/font_with_face.hpp index 52417a03c..5e2ecfbcb 100644 --- a/src/font/font_with_face.hpp +++ b/src/font/font_with_face.hpp @@ -19,47 +19,83 @@ #ifndef HEADER_FONT_WITH_FACE_HPP #define HEADER_FONT_WITH_FACE_HPP -#include "font/font_manager.hpp" -#include "font/font_settings.hpp" #include "utils/cpp2011.hpp" +#include "utils/leak_check.hpp" +#include "utils/no_copy.hpp" #include #include #include +#include +#include FT_FREETYPE_H +#include FT_OUTLINE_H + +#include + +using namespace irr; + const int BEARING = 64; class FaceTTF; +class FontSettings; +/** An abstract class which contains functions which convert vector fonts into + * bitmap and render them in STK. To make STK draw characters with different + * render option (like scaling, shadow) using a same FontWithFace, you need + * to wrap this with \ref irr::gui::ScalableFont and configure the + * \ref FontSettings for it. + * \ingroup font + */ class FontWithFace : public NoCopy { public: + /** A class for \ref STKTextBillboard to get font info to render billboard + * text. */ class FontCharCollector { public: + /** Collect the character info for billboard text. + * \param texture The texture of the character. + * \param destRect The destination rectangle + * \param sourceRect The source rectangle in the glyph page + * \param colors The color to render it. */ virtual void collectChar(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const video::SColor* const colors) = 0; }; + /** Glyph metrics for each glyph loaded. */ struct FontArea { FontArea() : advance_x(0), bearing_x(0) ,offset_y(0), offset_y_bt(0), spriteno(0) {} + /** Advance width for horizontal layout. */ int advance_x; + /** Left side bearing for horizontal layout. */ int bearing_x; + /** Top side bearing for horizontal layout. */ int offset_y; + /** Top side bearing for horizontal layout used in billboard text. */ int offset_y_bt; + /** Index number in sprite bank. */ int spriteno; }; protected: - int m_font_max_height; + /** Used in vertical dimension calculation. */ + int m_font_max_height; - int m_glyph_max_height; + /** Used in top side bearing calculation. */ + int m_glyph_max_height; // ------------------------------------------------------------------------ + /** Check characters to see if they are loaded in font, if not load them. + * For font that doesn't need lazy loading, nothing will be done. + * \param in_ptr Characters to check. + * \param first_load If true, it will ignore \ref supportLazyLoadChar, + * which is called in \ref reset. */ void insertCharacters(const wchar_t* in_ptr, bool first_load = false) { if (!supportLazyLoadChar() && !first_load) return; @@ -88,44 +124,69 @@ protected: // ------------------------------------------------------------------------ void updateCharactersList(); // ------------------------------------------------------------------------ + /** Set the fallback font for this font, so if some character is missing in + * this font, it will use that fallback font to try rendering it. + * \param face A \ref FontWithFace font. */ void setFallbackFont(FontWithFace* face) { m_fallback_font = face; } // ------------------------------------------------------------------------ + /** Set the scaling of fallback font. + * \param scale The scaling to set. */ void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; } private: + /** Mapping of glyph index to a TTF in \ref FaceTTF. */ struct GlyphInfo { + GlyphInfo(unsigned int font_num = 0, unsigned int glyph_idx = 0) : + font_number(font_num), glyph_index(glyph_idx) {} + /** Index to a TTF in \ref FaceTTF. */ unsigned int font_number; + /** Glyph index in the TTF, 0 means no such glyph. */ unsigned int glyph_index; - GlyphInfo(unsigned int first = 0, unsigned int second = 0) - { - font_number = first; - glyph_index = second; - } }; + /** \ref FaceTTF to load glyph from. */ FaceTTF* m_face_ttf; + /** Fallback font to use if some character isn't supported by this font. */ FontWithFace* m_fallback_font; + + /** Scaling for fallback font. */ float m_fallback_font_scale; - /** A temporary holder stored new char to be inserted. */ + /** A temporary holder to store new characters to be inserted. */ std::set m_new_char_holder; + /** Sprite bank to store each glyph. */ gui::IGUISpriteBank* m_spritebank; /** A full glyph page for this font. */ video::IImage* m_page; - unsigned int m_temp_height; + /** The current max height at current drawing line in glyph page. */ + unsigned int m_current_height; + + /** The used width in glyph page. */ unsigned int m_used_width; + + /** The used height in glyph page. */ unsigned int m_used_height; + + /** The dpi of this font. */ unsigned int m_face_dpi; + /** Store a list of supported character to a \ref FontArea. */ std::map m_character_area_map; + + /** Store a list of loaded and tested character to a \ref GlyphInfo. */ std::map m_character_glyph_info_map; // ------------------------------------------------------------------------ + /** Return a character width. + * \param area \ref FontArea to get glyph metrics. + * \param fallback If fallback font is used. + * \param scale The scaling of the character. + * \return The calculated width with suitable scaling. */ float getCharWidth(const FontArea& area, bool fallback, float scale) const { if (fallback) @@ -134,6 +195,9 @@ private: return area.advance_x * scale; } // ------------------------------------------------------------------------ + /** Test if a character has already been tried to be loaded. + * \param c Character to test. + * \return True if tested. */ bool loadedChar(wchar_t c) const { std::map::const_iterator n = @@ -143,6 +207,10 @@ private: return false; } // ------------------------------------------------------------------------ + /** Get the \ref GlyphInfo from \ref m_character_glyph_info_map about a + * character. + * \param c Character to get. + * \return \ref GlyphInfo of this character. */ const GlyphInfo& getGlyphInfo(wchar_t c) const { std::map::const_iterator n = @@ -152,6 +220,10 @@ private: return n->second; } // ------------------------------------------------------------------------ + /** Tells whether a character is supported by all TTFs in \ref m_face_ttf + * which is determined by \ref GlyphInfo of this character. + * \param c Character to test. + * \return True if it's supported. */ bool supportChar(wchar_t c) { std::map::const_iterator n = @@ -167,22 +239,36 @@ private: // ------------------------------------------------------------------------ void createNewGlyphPage(); // ------------------------------------------------------------------------ + /** Add a character into \ref m_new_char_holder for lazy loading later. */ void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); } // ------------------------------------------------------------------------ void insertGlyph(wchar_t c, const GlyphInfo& gi); // ------------------------------------------------------------------------ void setDPI(); // ------------------------------------------------------------------------ - virtual bool supportLazyLoadChar() const = 0; + /** Override it if sub-class should not do lazy loading characters. */ + virtual bool supportLazyLoadChar() const { return true; } // ------------------------------------------------------------------------ + /** Defined by sub-class about the texture size of glyph page, it should be + * a power of two. */ virtual unsigned int getGlyphPageSize() const = 0; // ------------------------------------------------------------------------ + /** Defined by sub-class about the scaling factor 1. */ virtual float getScalingFactorOne() const = 0; // ------------------------------------------------------------------------ + /** Defined by sub-class about the scaling factor 2. */ virtual unsigned int getScalingFactorTwo() const = 0; + // ------------------------------------------------------------------------ + /** Override it if sub-class has bold outline. */ + virtual bool isBold() const { return false; } + // ------------------------------------------------------------------------ + /** Override it if any outline shaping is needed to be done before + * rendering the glyph into bitmap. + * \return A FT_Error value if needed. */ + virtual int shapeOutline(FT_Outline* outline) const { return 0; } public: - LEAK_CHECK(); + LEAK_CHECK() // ------------------------------------------------------------------------ FontWithFace(const std::string& name, FaceTTF* ttf); // ------------------------------------------------------------------------ @@ -204,22 +290,17 @@ public: FontSettings* font_settings, FontCharCollector* char_collector = NULL); // ------------------------------------------------------------------------ - /** Write the current glyph page in png inside current running directory. - * Mainly for debug use. - * \param name The file name. - */ void dumpGlyphPage(const std::string& name); // ------------------------------------------------------------------------ - /** Write the current glyph page in png inside current running directory. - * Useful in gdb without parameter. - */ void dumpGlyphPage(); // ------------------------------------------------------------------------ + /** Return the sprite bank. */ gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; } // ------------------------------------------------------------------------ const FontArea& getAreaFromCharacter(const wchar_t c, bool* fallback_font) const; // ------------------------------------------------------------------------ + /** Return the dpi of this face. */ unsigned int getDPI() const { return m_face_dpi; } }; // FontWithFace diff --git a/src/font/regular_face.cpp b/src/font/regular_face.cpp index 0a5fc500a..78d098ce6 100644 --- a/src/font/regular_face.cpp +++ b/src/font/regular_face.cpp @@ -16,11 +16,12 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include "font/face_ttf.hpp" - #include "font/regular_face.hpp" // ---------------------------------------------------------------------------- +/** Constructor of RegularFace. + * \param ttf \ref FaceTTF for RegularFace to use. + */ RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf) { } // RegularFace diff --git a/src/font/regular_face.hpp b/src/font/regular_face.hpp index 54ac41d4a..c6bd22d14 100644 --- a/src/font/regular_face.hpp +++ b/src/font/regular_face.hpp @@ -23,11 +23,12 @@ class FaceTTF; +/** A font which uses regular TTFs to most text in STK. + * \ingroup font + */ class RegularFace : public FontWithFace { private: - virtual bool supportLazyLoadChar() const OVERRIDE { return true; } - // ------------------------------------------------------------------------ virtual unsigned int getGlyphPageSize() const OVERRIDE { return 512; } // ------------------------------------------------------------------------ virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; } @@ -39,8 +40,6 @@ public: // ------------------------------------------------------------------------ RegularFace(FaceTTF* ttf); // ------------------------------------------------------------------------ - virtual ~RegularFace() {} - // ------------------------------------------------------------------------ virtual void init() OVERRIDE; // ------------------------------------------------------------------------ virtual void reset() OVERRIDE; diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index 8cbc39ae7..92c22a1ee 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -659,6 +659,8 @@ namespace GUIEngine #include "config/user_config.hpp" #include "font/bold_face.hpp" #include "font/digit_face.hpp" +#include "font/font_manager.hpp" +#include "font/font_settings.hpp" #include "font/regular_face.hpp" #include "input/input_manager.hpp" #include "io/file_manager.hpp" diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index dfd035ba9..2b5966506 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -18,6 +18,7 @@ #include "guiengine/scalable_font.hpp" +#include "font/font_settings.hpp" #include "font/font_with_face.hpp" #include "utils/translation.hpp" diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index d55a6bf33..548a1ab14 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -15,6 +15,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include "font/font_manager.hpp" #include "font/regular_face.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 64c14f204..bc07b8561 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -26,6 +26,7 @@ #include "config/player_manager.hpp" #include "config/user_config.hpp" #include "font/bold_face.hpp" +#include "font/font_manager.hpp" #include "graphics/camera.hpp" #include "graphics/central_settings.hpp" #include "graphics/explosion.hpp" diff --git a/src/main.cpp b/src/main.cpp index 8ee16f0ad..44d57c84e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,6 +73,8 @@ This module handles the user configuration, the supertuxkart configuration file (which contains options usually not edited by the player) and the input configuration file. + \li \ref font : + This module stores font files and tools used to draw characters in STK. \li \ref graphics : This module contains the core graphics engine, that is mostly a thin layer on top of irrlicht providing some additional features we need for STK diff --git a/src/scriptengine/script_track.cpp b/src/scriptengine/script_track.cpp index d8cc4e465..16f00e914 100644 --- a/src/scriptengine/script_track.cpp +++ b/src/scriptengine/script_track.cpp @@ -20,6 +20,7 @@ #include "animations/three_d_animation.hpp" #include "font/digit_face.hpp" +#include "font/font_manager.hpp" #include "graphics/central_settings.hpp" #include "graphics/stk_text_billboard.hpp" #include "guiengine/scalable_font.hpp" diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index 4332e896d..3549c581b 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -24,6 +24,7 @@ #include "config/player_manager.hpp" #include "config/user_config.hpp" #include "font/bold_face.hpp" +#include "font/font_manager.hpp" #include "font/regular_face.hpp" #include "guiengine/scalable_font.hpp" #include "guiengine/screen.hpp" diff --git a/src/utils/debug.cpp b/src/utils/debug.cpp index a83fbb161..a8d4dd035 100644 --- a/src/utils/debug.cpp +++ b/src/utils/debug.cpp @@ -21,6 +21,7 @@ #include "config/user_config.hpp" #include "font/bold_face.hpp" #include "font/digit_face.hpp" +#include "font/font_manager.hpp" #include "font/regular_face.hpp" #include "graphics/camera_debug.hpp" #include "graphics/camera_fps.hpp"