1 // Copyright 2015-2017 the openage authors. See copying.md for legal info. 2 3 #pragma once 4 5 #include <memory> 6 #include <string> 7 #include <typeindex> 8 #include <vector> 9 10 #include "../../util/hash.h" 11 #include "font_manager.h" 12 13 // Forward Declarations of HarfBuzz stuff! 14 struct hb_font_t; 15 16 namespace openage { 17 namespace renderer { 18 19 constexpr int FREETYPE_UNIT = 64; 20 21 using codepoint_t = unsigned int; 22 23 /** 24 * Holds info about a single glyph. 25 */ 26 class Glyph { 27 public: 28 codepoint_t codepoint; //!< Glyph's codepoint. 29 int x_offset; //!< Horizontal distance from origin (current pen position) to glyph's leftmost boundary. 30 int y_offset; //!< Vertical distance from the baseline to glyph's topmost boundary. 31 unsigned int width; //!< Width of the glyph. 32 unsigned int height; //!< Height of the glyph. 33 float x_advance; //!< Advance width of the glyph. 34 float y_advance; //!< Advance height of the glyph. 35 }; 36 37 /** 38 * Enumeration of the possible font directions. 39 */ 40 enum class font_direction { 41 left_to_right, 42 right_to_left, 43 top_to_bottom, 44 bottom_to_top 45 }; 46 47 /** 48 * Description for a font. 49 * 50 * An instance of font_description is capable of uniquely distinguishing a font. 51 */ 52 struct font_description { 53 std::string font_file; //!< Path to the font's file. 54 unsigned int size; //!< Points size of the font. 55 font_direction direction; //!< The direction of the font. 56 std::string language; //!< Language of the font. 57 std::string script; //!< The font's script. 58 59 /** 60 * Constructs a font_description instance. 61 * 62 * @param font_file: The path to fon't font. 63 * @param size: The size of the font in points. 64 * @param direction: The direction of font. 65 * @param language: The font's language. 66 * @param script: The font's script. 67 */ 68 font_description(const std::string &font_file, 69 unsigned int size, 70 font_direction direction = font_direction::left_to_right, 71 const std::string &language = "en", 72 const std::string &script = "Latn"); 73 74 /** 75 * Constructs a font_description instance. 76 * 77 * This constructor uses fontconfig to determine a font file for the specified font family and style. 78 * 79 * @param family: The font family. 80 * @param style: The font style. 81 * @param size: The size of the font in points. 82 */ 83 font_description(const char *family, const char *style, unsigned int size); 84 85 font_description(const font_description &other); 86 87 font_description &operator=(const font_description &other); 88 89 bool operator==(const font_description &other) const; 90 91 bool operator!=(const font_description &other) const; 92 93 }; 94 95 class Font { 96 97 public: 98 /** 99 * Create a font instance from the description. 100 * 101 * @param description: the font description. 102 */ 103 Font(const font_description &description); 104 105 /** 106 * This constructor is used by the font manager to create a 107 * new font instance from the description. 108 * 109 * @param font_manager: The font manager. 110 * @param description: the font description. 111 */ 112 Font(FontManager *font_manager, const font_description &description); 113 114 virtual ~Font(); 115 116 /** 117 * Get the typographic ascender of font. 118 * 119 * @returns The ascender of font. 120 */ 121 float get_ascender() const; 122 123 /** 124 * Get the typographic descender of font. 125 * 126 * @returns The descender of font. 127 */ 128 float get_descender() const; 129 130 /** 131 * Get the line spacing of font. 132 * 133 * @returns The font's line height. 134 */ 135 float get_line_height() const; 136 137 /** 138 * Get the kerning adjustment between two glyphs. 139 * 140 * @param left_glyph: The first glyph. 141 * @param right_glyph: The next glyph. 142 * @returns The kerning adjustment. 143 */ 144 float get_horizontal_kerning(codepoint_t left_glyph, codepoint_t right_glyph) const; 145 146 /** 147 * Get the advance width of a particular string. 148 * 149 * @param text: The string for which the width is to be determined. 150 * @returns The advance width of the specified string. 151 */ 152 float get_advance_width(const std::string &text) const; 153 154 /** 155 * Get the list of glyphs for a particular string. 156 * 157 * @param text: the string for which the glyphs are to be retrieved. 158 * @returns The list of the glyphs. 159 */ 160 std::vector<codepoint_t> get_glyphs(const std::string &text) const; 161 162 /** 163 * Load a particular glyph's info and retrieves the glyph's bitmap data. 164 * 165 * @param codepoint: The glyph. 166 * @param glyph: The glyph's info is loaded in to this object. 167 * @returns The glyph's bitmap data. 168 */ 169 std::unique_ptr<unsigned char[]> load_glyph(codepoint_t codepoint, Glyph &glyph) const; 170 171 private: 172 /** 173 * Initializes the font's face and creates a harfbuzz font instance. 174 * 175 * @param ft_library: The freetype library that should be used to load the font's face. 176 */ 177 void initialize(FT_Library ft_library); 178 179 public: 180 /** 181 * The description of the font. 182 * @see font_description 183 */ 184 font_description description; 185 186 private: 187 // Font's created without the use of FontManager are standalone and have their own FreeTypeLibrary instance 188 std::unique_ptr<FreeTypeLibrary> freetype_library; 189 190 // The HarfBuzz font instance that drives the operations of this font 191 hb_font_t *hb_font; 192 193 }; 194 195 }} // openage::renderer 196 197 namespace std { 198 199 template<> 200 struct hash<openage::renderer::font_description> { 201 size_t operator()(const openage::renderer::font_description &fd) const { 202 size_t hash = std::hash<std::type_index>()(std::type_index(typeid(openage::renderer::font_description))); 203 hash = openage::util::hash_combine(hash, std::hash<std::string>()(fd.font_file)); 204 hash = openage::util::hash_combine(hash, std::hash<unsigned int>()(fd.size)); 205 return hash; 206 } 207 }; 208 209 } 210