SuperTuxKart
font_with_face.hpp
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_WITH_FACE_HPP
20 #define HEADER_FONT_WITH_FACE_HPP
21 
22 #include "utils/cpp2011.hpp"
23 #include "utils/leak_check.hpp"
24 #include "utils/no_copy.hpp"
25 
26 #include <algorithm>
27 #include <cassert>
28 #include <map>
29 #include <set>
30 #include <string>
31 
32 #ifndef SERVER_ONLY
33 #include <ft2build.h>
34 #include FT_FREETYPE_H
35 #include FT_OUTLINE_H
36 #endif
37 
38 #include <GlyphLayout.h>
39 #include <dimension2d.h>
40 #include <irrString.h>
41 #include <rect.h>
42 
43 using namespace irr;
44 
45 const int BEARING = 64;
46 
47 class FaceTTF;
48 class FontSettings;
49 struct FontArea;
50 
51 namespace irr
52 {
53  namespace video
54  {
55  class ITexture;
56  class SColor;
57  }
58  namespace gui
59  {
60  class IGUISpriteBank;
61  }
62 }
63 
71 class FontWithFace : public NoCopy
72 {
73 public:
77  {
78  public:
84  virtual void collectChar(video::ITexture* texture,
85  const core::rect<float>& destRect,
86  const core::rect<s32>& sourceRect,
87  const video::SColor* const colors) = 0;
88  };
89 
90 protected:
93 
96 
97  // ------------------------------------------------------------------------
103  void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
104  {
105  if (!supportLazyLoadChar() && !first_load) return;
106 
107  for (const wchar_t* p = in_ptr; *p; ++p)
108  {
109  if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
110  continue;
111  if (!loadedChar(*p))
112  {
113  loadGlyphInfo(*p);
114  if (supportChar(*p))
115  addLazyLoadChar(*p);
116  else if (m_fallback_font != NULL)
117  {
118  if (!m_fallback_font->loadedChar(*p))
119  {
120  m_fallback_font->loadGlyphInfo(*p);
121  if (m_fallback_font->supportChar(*p))
122  m_fallback_font->addLazyLoadChar(*p);
123  }
124  }
125  }
126  }
127  }
128  // ------------------------------------------------------------------------
129  void updateCharactersList();
130  // ------------------------------------------------------------------------
134  void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
135  // ------------------------------------------------------------------------
138  void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
139 
140 private:
142  struct GlyphInfo
143  {
144  GlyphInfo(unsigned int font_num = 0, unsigned int glyph_idx = 0) :
145  font_number(font_num), glyph_index(glyph_idx) {}
147  unsigned int font_number;
149  unsigned int glyph_index;
150  };
151 
154 
157 
160 
162  std::set<wchar_t> m_new_char_holder;
163 
165  gui::IGUISpriteBank* m_spritebank;
166 
168  unsigned int m_current_height;
169 
171  unsigned int m_used_width;
172 
174  unsigned int m_used_height;
175 
177  unsigned int m_face_dpi;
178 
183  std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
184 
185  // ------------------------------------------------------------------------
186  float getCharWidth(const FontArea& area, bool fallback, float scale) const;
187  // ------------------------------------------------------------------------
191  bool loadedChar(wchar_t c) const
192  {
193  std::map<wchar_t, GlyphInfo>::const_iterator n =
194  m_character_glyph_info_map.find(c);
195  if (n != m_character_glyph_info_map.end())
196  return true;
197  return false;
198  }
199  // ------------------------------------------------------------------------
204  const GlyphInfo& getGlyphInfo(wchar_t c) const
205  {
206  std::map<wchar_t, GlyphInfo>::const_iterator n =
207  m_character_glyph_info_map.find(c);
208  // Make sure we always find GlyphInfo
209  assert(n != m_character_glyph_info_map.end());
210  return n->second;
211  }
212  // ------------------------------------------------------------------------
217  bool supportChar(wchar_t c)
218  {
219  std::map<wchar_t, GlyphInfo>::const_iterator n =
220  m_character_glyph_info_map.find(c);
221  if (n != m_character_glyph_info_map.end())
222  {
223  return n->second.glyph_index > 0;
224  }
225  return false;
226  }
227  // ------------------------------------------------------------------------
228  void loadGlyphInfo(wchar_t c);
229  // ------------------------------------------------------------------------
230  void createNewGlyphPage();
231  // ------------------------------------------------------------------------
233  void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
234  // ------------------------------------------------------------------------
236  virtual bool supportLazyLoadChar() const { return true; }
237  // ------------------------------------------------------------------------
240  virtual unsigned int getGlyphPageSize() const = 0;
241  // ------------------------------------------------------------------------
243  virtual float getScalingFactorOne() const = 0;
244  // ------------------------------------------------------------------------
246  virtual unsigned int getScalingFactorTwo() const = 0;
247  // ------------------------------------------------------------------------
249  virtual bool isBold() const { return false; }
250  // ------------------------------------------------------------------------
251  const FontArea* getUnknownFontArea() const;
252  // ------------------------------------------------------------------------
253  std::vector<gui::GlyphLayout> text2GlyphsWithoutShaping(
254  const core::stringw& t);
255  // ------------------------------------------------------------------------
256 #ifndef SERVER_ONLY
260  virtual int shapeOutline(FT_Outline* outline) const { return 0; }
261 #endif
262 
263 public:
264  LEAK_CHECK()
265  // ------------------------------------------------------------------------
266  FontWithFace(const std::string& name);
267  // ------------------------------------------------------------------------
268  virtual ~FontWithFace();
269  // ------------------------------------------------------------------------
270  virtual void init();
271  // ------------------------------------------------------------------------
272  virtual void reset();
273  // ------------------------------------------------------------------------
274  virtual core::dimension2d<u32> getDimension(const core::stringw& text,
275  FontSettings* font_settings = NULL);
276  // ------------------------------------------------------------------------
277  int getCharacterFromPos(const wchar_t* text, int pixel_x,
278  FontSettings* font_settings = NULL) const;
279  // ------------------------------------------------------------------------
280  void render(const std::vector<gui::GlyphLayout>& gl,
281  const core::rect<s32>& position, const video::SColor& color,
282  bool hcenter, bool vcenter, const core::rect<s32>* clip,
283  FontSettings* font_settings,
284  FontCharCollector* char_collector = NULL);
285  // ------------------------------------------------------------------------
286  virtual void drawText(const core::stringw& text,
287  const core::rect<s32>& position,
288  const video::SColor& color, bool hcenter,
289  bool vcenter, const core::rect<s32>* clip,
290  FontSettings* font_settings,
291  FontCharCollector* char_collector = NULL);
292  // ------------------------------------------------------------------------
293  void drawTextQuick(const core::stringw& text,
294  const core::rect<s32>& position,
295  const video::SColor& color, bool hcenter, bool vcenter,
296  const core::rect<s32>* clip,
297  FontSettings* font_settings,
298  FontCharCollector* char_collector = NULL);
299  // ------------------------------------------------------------------------
300  void dumpGlyphPage(const std::string& name);
301  // ------------------------------------------------------------------------
302  void dumpGlyphPage();
303  // ------------------------------------------------------------------------
305  gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
306  // ------------------------------------------------------------------------
307  const FontArea& getAreaFromCharacter(const wchar_t c,
308  bool* fallback_font) const;
309  // ------------------------------------------------------------------------
311  unsigned int getDPI() const { return m_face_dpi; }
312  // ------------------------------------------------------------------------
313  FaceTTF* getFaceTTF() const { return m_face_ttf; }
314  // ------------------------------------------------------------------------
315  void insertGlyph(unsigned font_number, unsigned glyph_index);
316  // ------------------------------------------------------------------------
317  int getFontMaxHeight() const { return m_font_max_height; }
318  // ------------------------------------------------------------------------
319  int getGlyphMaxHeight() const { return m_glyph_max_height; }
320  // ------------------------------------------------------------------------
321  virtual bool disableTextShaping() const { return false; }
322  // ------------------------------------------------------------------------
323  float getInverseShaping() const { return m_inverse_shaping; }
324  // ------------------------------------------------------------------------
325  virtual bool useColorGlyphPage() const { return false; }
326  // ------------------------------------------------------------------------
329  virtual float getNativeScalingFactor() const { return 1.0f; }
330  // ------------------------------------------------------------------------
331  void setDPI();
332 }; // FontWithFace
333 
334 #endif
335 /* EOF */
This class will load a list of TTF files from FontManager, and save them inside m_ft_faces for FontWi...
Definition: face_ttf.hpp:57
This class stores settings when rendering fonts, used when instantiating irr::gui::ScalableFont.
Definition: font_settings.hpp:33
A class for STKTextBillboard to get font info to render billboard text.
Definition: font_with_face.hpp:77
virtual void collectChar(video::ITexture *texture, const core::rect< float > &destRect, const core::rect< s32 > &sourceRect, const video::SColor *const colors)=0
Collect the character info for billboard text.
An abstract class which contains functions which convert vector fonts into bitmap and render them in ...
Definition: font_with_face.hpp:72
int m_font_max_height
Used in vertical dimension calculation.
Definition: font_with_face.hpp:92
void setFallbackFontScale(float scale)
Set the scaling of fallback font.
Definition: font_with_face.hpp:138
virtual bool supportLazyLoadChar() const
Override it if sub-class should not do lazy loading characters.
Definition: font_with_face.hpp:236
float m_inverse_shaping
Used to undo the scale on text shaping, only need to take care of width.
Definition: font_with_face.hpp:181
float m_fallback_font_scale
Scaling for fallback font.
Definition: font_with_face.hpp:159
virtual unsigned int getScalingFactorTwo() const =0
Defined by sub-class about the scaling factor 2.
unsigned int m_used_width
The used width in glyph page.
Definition: font_with_face.hpp:171
int m_glyph_max_height
Used in top side bearing calculation.
Definition: font_with_face.hpp:95
std::set< wchar_t > m_new_char_holder
A temporary holder to store new characters to be inserted.
Definition: font_with_face.hpp:162
virtual bool isBold() const
Override it if sub-class has bold outline.
Definition: font_with_face.hpp:249
virtual int shapeOutline(FT_Outline *outline) const
Override it if any outline shaping is needed to be done before rendering the glyph into bitmap.
Definition: font_with_face.hpp:260
void addLazyLoadChar(wchar_t c)
Add a character into m_new_char_holder for lazy loading later.
Definition: font_with_face.hpp:233
void setFallbackFont(FontWithFace *face)
Set the fallback font for this font, so if some character is missing in this font,...
Definition: font_with_face.hpp:134
virtual float getScalingFactorOne() const =0
Defined by sub-class about the scaling factor 1.
void insertCharacters(const wchar_t *in_ptr, bool first_load=false)
Check characters to see if they are loaded in font, if not load them.
Definition: font_with_face.hpp:103
unsigned int m_face_dpi
The dpi of this font.
Definition: font_with_face.hpp:177
const GlyphInfo & getGlyphInfo(wchar_t c) const
Get the GlyphInfo from m_character_glyph_info_map about a character.
Definition: font_with_face.hpp:204
unsigned int m_current_height
The current max height at current drawing line in glyph page.
Definition: font_with_face.hpp:168
bool loadedChar(wchar_t c) const
Test if a character has already been tried to be loaded.
Definition: font_with_face.hpp:191
unsigned int m_used_height
The used height in glyph page.
Definition: font_with_face.hpp:174
unsigned int getDPI() const
Return the dpi of this face.
Definition: font_with_face.hpp:311
virtual unsigned int getGlyphPageSize() const =0
Defined by sub-class about the texture size of glyph page, it should be a power of two.
bool supportChar(wchar_t c)
Tells whether a character is supported by all TTFs in m_face_ttf which is determined by GlyphInfo of ...
Definition: font_with_face.hpp:217
FontWithFace * m_fallback_font
Fallback font to use if some character isn't supported by this font.
Definition: font_with_face.hpp:156
virtual float getNativeScalingFactor() const
Defined by sub-class about the native scaling factor, to provide.
Definition: font_with_face.hpp:329
gui::IGUISpriteBank * m_spritebank
Sprite bank to store each glyph.
Definition: font_with_face.hpp:165
std::map< wchar_t, GlyphInfo > m_character_glyph_info_map
Store a list of loaded and tested character to a GlyphInfo.
Definition: font_with_face.hpp:183
FaceTTF * m_face_ttf
FaceTTF to load glyph from.
Definition: font_with_face.hpp:153
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:26
Glyph metrics for each glyph loaded.
Definition: face_ttf.hpp:37
Mapping of glyph index to a TTF in FaceTTF.
Definition: font_with_face.hpp:143
unsigned int glyph_index
Glyph index in the TTF, 0 means no such glyph.
Definition: font_with_face.hpp:149
unsigned int font_number
Index to a TTF in FaceTTF.
Definition: font_with_face.hpp:147