1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2016 SuperTuxKart-Team 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 3 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 #ifndef HEADER_FONT_MANAGER_HPP 20 #define HEADER_FONT_MANAGER_HPP 21 22 /** \defgroup font Font 23 * This module stores font files and tools used to draw characters in STK. 24 */ 25 26 #include "utils/leak_check.hpp" 27 #include "utils/log.hpp" 28 #include "utils/no_copy.hpp" 29 30 #include <string> 31 #include <map> 32 #include <typeindex> 33 #include <unordered_map> 34 #include <vector> 35 36 #ifndef SERVER_ONLY 37 #include <ft2build.h> 38 #include <harfbuzz/hb.h> 39 #include FT_FREETYPE_H 40 41 #include "irrString.h" 42 #include "GlyphLayout.h" 43 #endif 44 45 class FontWithFace; 46 47 /** This class stores all font files required in STK. 48 * \ingroup font 49 */ 50 class FontManager : public NoCopy 51 { 52 private: 53 /** Stores all \ref FontWithFace used in STK. */ 54 std::vector<FontWithFace*> m_fonts; 55 56 #ifndef SERVER_ONLY 57 /** A FreeType library, it holds the FT_Face internally inside freetype. */ 58 FT_Library m_ft_library; 59 60 /** List of TTF files for complex text shaping. */ 61 std::vector<FT_Face> m_faces; 62 63 /** TTF file for digit font in STK. */ 64 FT_Face m_digit_face; 65 66 /** DPI used when shaping, each face will apply an inverse of this and the 67 * dpi of itself when rendering, so all faces can share the same glyph 68 * layout cache. */ 69 unsigned m_shaping_dpi; 70 71 /** Map FT_Face to index for quicker layout. */ 72 std::map<FT_Face, uint16_t> m_ft_faces_to_index; 73 74 /** Text drawn to glyph layouts cache. */ 75 std::map<irr::core::stringw, 76 std::vector<irr::gui::GlyphLayout> > m_cached_gls; 77 78 bool m_has_color_emoji; 79 // ------------------------------------------------------------------------ 80 std::vector<FT_Face> loadTTF(const std::vector<std::string>& ttf_list); 81 82 hb_buffer_t* m_hb_buffer; 83 84 std::vector<hb_font_t*> m_hb_fonts; 85 #endif 86 87 /** Map type for each \ref FontWithFace with a index, save getting time in 88 * \ref getFont. */ 89 std::unordered_map<std::type_index, int> m_font_type_map; 90 public: 91 LEAK_CHECK() 92 // ------------------------------------------------------------------------ 93 FontManager(); 94 // ------------------------------------------------------------------------ 95 ~FontManager(); 96 // ------------------------------------------------------------------------ 97 /** Return a specfic type of \ref FontWithFace found in \ref m_fonts. */ getFont()98 template <typename T> T* getFont() 99 { 100 T* out = NULL; 101 const unsigned int n = m_font_type_map[std::type_index(typeid(T))]; 102 out = dynamic_cast<T*>(m_fonts[n]); 103 if (out != NULL) 104 { 105 return out; 106 } 107 Log::fatal("FontManager", "Can't get a font!"); 108 return out; 109 } 110 // ------------------------------------------------------------------------ 111 #ifndef SERVER_ONLY 112 /** Check for any error discovered in a freetype function that will return 113 * a FT_Error value, and log into the terminal. 114 * \param err The Freetype function. 115 * \param desc The description of what is the function doing. */ checkFTError(FT_Error err,const std::string & desc) const116 void checkFTError(FT_Error err, const std::string& desc) const 117 { 118 if (err > 0) 119 { 120 Log::error("FontManager", "Something wrong when %s! The error " 121 "code was %d.", desc.c_str(), err); 122 } 123 } 124 // ------------------------------------------------------------------------ hasColorEmoji() const125 bool hasColorEmoji() const { return m_has_color_emoji; } 126 // ------------------------------------------------------------------------ 127 /** Return the \ref m_ft_library. */ getFTLibrary() const128 FT_Library getFTLibrary() const { return m_ft_library; } 129 // ------------------------------------------------------------------------ 130 FT_Face loadColorEmoji(); 131 // ------------------------------------------------------------------------ getShapingDPI() const132 unsigned getShapingDPI() const { return m_shaping_dpi; } 133 // ------------------------------------------------------------------------ 134 void shape(const std::u32string& text, 135 std::vector<irr::gui::GlyphLayout>& gls, 136 std::vector<std::u32string>* line_data = NULL); 137 // ------------------------------------------------------------------------ 138 std::vector<irr::gui::GlyphLayout>& getCachedLayouts 139 (const irr::core::stringw& str); 140 // ------------------------------------------------------------------------ clearCachedLayouts()141 void clearCachedLayouts() { m_cached_gls.clear(); } 142 // ------------------------------------------------------------------------ 143 void initGlyphLayouts(const irr::core::stringw& text, 144 std::vector<irr::gui::GlyphLayout>& gls, 145 std::vector<std::u32string>* line_data = NULL); 146 #endif 147 // ------------------------------------------------------------------------ 148 void loadFonts(); 149 // ------------------------------------------------------------------------ 150 void unitTesting(); 151 152 }; // FontManager 153 154 extern FontManager *font_manager; 155 156 #endif 157 /* EOF */ 158