CUGL
Cornell University Game Library
CUFont.h
1 //
2 // CUFont.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides a robust font asset with atlas support. Unlike other
6 // systems we decided to merge fonts and font atlases because it helps with
7 // asset management.
8 //
9 // This module makes heavy use of the cross-platform UTF8 utilities by
10 // Nemanja Trifunovic ( https://github.com/nemtrif/utfcpp ).
11 //
12 // This class uses our standard shared-pointer architecture.
13 //
14 // 1. The constructor does not perform any initialization; it just sets all
15 // attributes to their defaults.
16 //
17 // 2. All initialization takes place via init methods, which can fail if an
18 // object is initialized more than once.
19 //
20 // 3. All allocation takes place via static constructors which return a shared
21 // pointer.
22 //
23 //
24 // CUGL zlib License:
25 // This software is provided 'as-is', without any express or implied
26 // warranty. In no event will the authors be held liable for any damages
27 // arising from the use of this software.
28 //
29 // Permission is granted to anyone to use this software for any purpose,
30 // including commercial applications, and to alter it and redistribute it
31 // freely, subject to the following restrictions:
32 //
33 // 1. The origin of this software must not be misrepresented; you must not
34 // claim that you wrote the original software. If you use this software
35 // in a product, an acknowledgment in the product documentation would be
36 // appreciated but is not required.
37 //
38 // 2. Altered source versions must be plainly marked as such, and must not
39 // be misrepresented as being the original software.
40 //
41 // 3. This notice may not be removed or altered from any source distribution.
42 //
43 // Author: Walker White
44 // Version: 7/6/16
45 
46 #ifndef __CU_FONT_H__
47 #define __CU_FONT_H__
48 
49 #include <string>
50 #include <unordered_map>
51 #include <vector>
52 #include <cugl/math/CUSize.h>
53 #include <cugl/math/CURect.h>
54 #include <cugl/renderer/CUTexture.h>
55 #include <cugl/renderer/CUVertex.h>
56 #include <SDL/SDL_ttf.h>
57 
58 namespace cugl {
59 
98 class Font {
99 #pragma mark Inner Classes
100 public:
109  class Metrics {
110  public:
112  int minx;
114  int maxx;
116  int miny;
118  int maxy;
120  int advance;
121  };
122 
134  enum class Style : int {
136  NORMAL = TTF_STYLE_NORMAL,
138  BOLD = TTF_STYLE_BOLD,
140  ITALIC = TTF_STYLE_ITALIC,
142  UNDERLINE = TTF_STYLE_UNDERLINE,
144  STRIKE = TTF_STYLE_STRIKETHROUGH
145  };
146 
154  enum class Hinting : int {
159  NORMAL = TTF_HINTING_NORMAL,
165  LIGHT = TTF_HINTING_LIGHT,
171  MONO = TTF_HINTING_MONO,
176  NONE = TTF_HINTING_NONE
177  };
178 
187  enum class Resolution : int {
195  SOLID = 0,
207  SHADED = 1,
218  BLENDED = 2,
219  };
220 
221 #pragma mark -
222 #pragma mark Values
223 protected:
225  std::string _name;
227  std::string _stylename;
229  int _size;
230 
232  TTF_Font* _data;
233 
234  // Cached settings
236  unsigned int _fontHeight;
238  unsigned int _fontDescent;
240  unsigned int _fontAscent;
242  unsigned int _fontLineSkip;
247 
248  // Render settings
255 
256  // Altas support
258  bool _hasAtlas;
260  std::vector<Uint32> _glyphset;
262  std::unordered_map<Uint32, Rect> _glyphmap;
264  std::unordered_map<Uint32, Metrics> _glyphsize;
266  std::unordered_map<Uint32, std::unordered_map<Uint32, Uint32> > _kernmap;
268  std::shared_ptr<Texture> _texture;
270  SDL_Surface* _surface;
271 
272 
273 public:
274 #pragma mark -
275 #pragma mark Constructors
276 
282  Font();
283 
287  ~Font() { dispose(); }
288 
297  virtual void dispose();
298 
311  bool init(const std::string& file, int size);
312 
325  bool init(const char* file, int size) {
326  return init(std::string(file),size);
327  }
328 
329 
330 #pragma mark -
331 #pragma mark Static Constructors
332 
344  static std::shared_ptr<Font> alloc(const std::string& file, int size) {
345  std::shared_ptr<Font> result = std::make_shared<Font>();
346  return (result->init(file,size) ? result : nullptr);
347  }
348 
361  static std::shared_ptr<Font> alloc(const char* file, int size) {
362  std::shared_ptr<Font> result = std::make_shared<Font>();
363  return (result->init(file,size) ? result : nullptr);
364  }
365 
366 #pragma mark -
367 #pragma mark Attributes
368 
376  const std::string& getName() const { return _name; }
377 
386  const std::string& getStyleName() const { return _stylename; }
387 
397  int getHeight() const { return _fontHeight; }
398 
407  int getDescent() const { return _fontDescent; }
408 
416  int getAscent() const { return _fontAscent; }
417 
426  int getLineSkip() const { return _fontLineSkip; }
427 
439  bool isFixedWidth() const { return _fixedWidth; }
440 
450  bool usesKerning() const { return _useKerning; }
451 
461  void setKerning(bool kerning);
462 
474  bool hasGlyph(char a) const { return hasGlyph((Uint32)a); }
475 
491  bool hasGlyph(Uint32 a) const;
492 
507  bool hasString(const std::string& text) const;
508 
520  bool hasString(const char* text) const {
521  return hasString(std::string(text));
522  }
523 
524 #pragma mark -
525 #pragma mark Settings
526 
536  Style getStyle() const { return _style; }
537 
551  void setStyle(Style style);
552 
562  Hinting getHinting() const { return _hints; }
563 
576  void setHinting(Hinting hinting);
577 
588  Resolution getResolution() const { return _render; }
589 
603  void setResolution(Resolution resolution) { clearAtlas(); _render = resolution; }
604 
605 
606 
607 #pragma mark -
608 #pragma mark Measurements
609 
619  const Metrics getMetrics(char thechar) const {
620  return getMetrics((Uint32)thechar);
621  }
622 
637  const Metrics getMetrics(Uint32 thechar) const;
638 
651  unsigned int getKerning(char a, char b) const {
652  return getKerning((Uint32)a, (Uint32)b);
653  }
654 
671  unsigned int getKerning(Uint32 a, Uint32 b) const;
672 
696  Size getSize(const std::string& text, bool utf8=true) const;
697 
721  Size getSize(const char* text, bool utf8=true) const {
722  return getSize(std::string(text), utf8);
723  }
724 
761  Rect getInternalBounds(const std::string& text, bool utf8=true) const;
762 
799  Rect getInternalBounds(const char* text, bool utf8=true) const {
800  return getInternalBounds(std::string(text), utf8);
801  }
802 
803 #pragma mark -
804 #pragma mark Atlas Support
805 
810  void clearAtlas();
811 
827  bool buildAtlas() {
828  bool result = buildAtlasAsync();
829  return result && (getAtlas() != nullptr);
830  }
831 
851  bool buildAtlas(const std::string& charset) {
852  bool result = buildAtlasAsync(charset);
853  return result && (getAtlas() != nullptr);
854  }
855 
875  bool buildAtlas(const char* charset) {
876  bool result = buildAtlasAsync(charset);
877  return result && (getAtlas() != nullptr);
878  }
879 
897  bool buildAtlasAsync();
898 
918  bool buildAtlasAsync(const std::string& charset);
919 
939  bool buildAtlasAsync(const char* charset) {
940  return buildAtlasAsync(std::string(charset));
941  }
942 
952  const std::shared_ptr<Texture>& getAtlas();
953 
962  bool hasAtlas() const { return _hasAtlas; }
963 
964 #pragma mark -
965 #pragma mark Rendering
966 
999  std::shared_ptr<Texture> getQuads(const std::string& text, const Vec2& origin,
1000  std::vector<Vertex2>& vertices, bool utf8=true);
1001 
1033  std::shared_ptr<Texture> getQuads(const char* text, const Vec2& origin,
1034  std::vector<Vertex2>& vertices, bool utf8=true) {
1035  return getQuads(std::string(text),origin,vertices,utf8);
1036  }
1037 
1074  std::shared_ptr<Texture> getQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1075  std::vector<Vertex2>& vertices, bool utf8=true);
1076 
1113  std::shared_ptr<Texture> getQuads(const char* text, const Vec2& origin, const Rect& rect,
1114  std::vector<Vertex2>& vertices, bool utf8=true) {
1115  return getQuads(std::string(text),origin,rect,vertices,utf8);
1116  }
1117 
1138  std::shared_ptr<Texture> getQuad(Uint32 thechar, Vec2& offset, std::vector<Vertex2>& vertices);
1139 
1164  std::shared_ptr<Texture> getQuad(Uint32 thechar, Vec2& offset, const Rect& rect,
1165  std::vector<Vertex2>& vertices);
1166 
1167 
1168 #pragma mark -
1169 #pragma mark Rendering Internals
1170 protected:
1201  void getAtlasQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1202  std::vector<Vertex2>& vertices, bool utf8);
1203 
1237  std::shared_ptr<Texture> getRenderedQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1238  std::vector<Vertex2>& vertices, bool utf8);
1239 
1259  bool getAtlasQuad(Uint32 thechar, Vec2& offset, const Rect& rect, std::vector<Vertex2>& vertices);
1260 
1282  std::shared_ptr<Texture> getRenderedQuad(Uint32 thechar, Vec2& offset, const Rect& rect,
1283  std::vector<Vertex2>& vertices);
1284 
1302  Size getSizeASCII(const std::string& text) const;
1303 
1321  Size getSizeUTF8(const std::string& text) const;
1322 
1353  Rect getInternalBoundsASCII(const std::string& text) const;
1354 
1385  Rect getInternalBoundsUTF8(const std::string& text) const;
1386 
1387 #pragma mark -
1388 #pragma mark Atlas Preparation
1389 
1397  int prepareAtlas();
1398 
1409  int prepareAtlas(std::string charset);
1410 
1414  void prepareAtlasKerning();
1415 
1423  Metrics computeMetrics(Uint32 thechar) const;
1424 
1433  int computeKerning(Uint32 a, Uint32 b) const;
1434 
1450  void computeAtlasSize(int* width, int* height);
1451 
1463  std::vector< std::vector<Uint32> > planAtlas(int width, int height);
1464 
1470  void layoutAtlas(const std::vector< std::vector<Uint32> >& rectangle);
1471 
1482  bool generateSurface(int width, int height);
1483 
1492  SDL_Surface* allocSurface(int width, int height);
1493 };
1494 
1495 #pragma mark -
1496 #pragma mark Style Bit-Wise Operators
1497 
1503 inline int operator*(Font::Style value) {
1504  return static_cast<int>(value);
1505 }
1506 
1513  return static_cast<Font::Style>((*lhs) | (*rhs));
1514 }
1515 
1522  return static_cast<Font::Style>((*lhs) & (*rhs));
1523 }
1524 
1532  return static_cast<Font::Style>((*lhs) ^ (*rhs));
1533 }
1534 
1541  return static_cast<Font::Style>(~(*lhs));
1542 }
1543 
1544 
1545 }
1546 
1547 #endif /* __CU_FONT_H__ */
std::shared_ptr< Texture > getQuads(const char *text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8=true)
Definition: CUFont.h:1113
Definition: CUSize.h:57
void getAtlasQuads(const std::string &text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8)
Size getSizeASCII(const std::string &text) const
unsigned int _fontAscent
Definition: CUFont.h:240
Style _style
Definition: CUFont.h:250
Definition: CUFont.h:109
int prepareAtlas()
bool buildAtlasAsync(const char *charset)
Definition: CUFont.h:939
void setHinting(Hinting hinting)
bool hasString(const std::string &text) const
std::shared_ptr< Texture > getQuads(const char *text, const Vec2 &origin, std::vector< Vertex2 > &vertices, bool utf8=true)
Definition: CUFont.h:1033
Definition: CUVec2.h:61
Resolution getResolution() const
Definition: CUFont.h:588
Style getStyle() const
Definition: CUFont.h:536
SDL_Surface * allocSurface(int width, int height)
Font::Style operator^(Font::Style lhs, Font::Style rhs)
Definition: CUFont.h:1531
int advance
Definition: CUFont.h:120
void computeAtlasSize(int *width, int *height)
bool hasAtlas() const
Definition: CUFont.h:962
int getAscent() const
Definition: CUFont.h:416
std::shared_ptr< Texture > getRenderedQuads(const std::string &text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8)
const Metrics getMetrics(char thechar) const
Definition: CUFont.h:619
virtual void dispose()
Font::Style operator|(Font::Style lhs, Font::Style rhs)
Definition: CUFont.h:1512
Font::Style operator~(Font::Style lhs)
Definition: CUFont.h:1540
~Font()
Definition: CUFont.h:287
bool getAtlasQuad(Uint32 thechar, Vec2 &offset, const Rect &rect, std::vector< Vertex2 > &vertices)
int getHeight() const
Definition: CUFont.h:397
std::unordered_map< Uint32, std::unordered_map< Uint32, Uint32 > > _kernmap
Definition: CUFont.h:266
std::shared_ptr< Texture > getQuads(const std::string &text, const Vec2 &origin, std::vector< Vertex2 > &vertices, bool utf8=true)
static std::shared_ptr< Font > alloc(const std::string &file, int size)
Definition: CUFont.h:344
void setResolution(Resolution resolution)
Definition: CUFont.h:603
void setKerning(bool kerning)
Rect getInternalBounds(const char *text, bool utf8=true) const
Definition: CUFont.h:799
bool usesKerning() const
Definition: CUFont.h:450
Hinting _hints
Definition: CUFont.h:252
Size getSize(const std::string &text, bool utf8=true) const
void prepareAtlasKerning()
int maxx
Definition: CUFont.h:114
Rect getInternalBoundsUTF8(const std::string &text) const
bool buildAtlas(const std::string &charset)
Definition: CUFont.h:851
const std::shared_ptr< Texture > & getAtlas()
Rect getInternalBounds(const std::string &text, bool utf8=true) const
unsigned int _fontLineSkip
Definition: CUFont.h:242
std::shared_ptr< Texture > getQuad(Uint32 thechar, Vec2 &offset, std::vector< Vertex2 > &vertices)
Definition: CUFont.h:98
int getDescent() const
Definition: CUFont.h:407
void setStyle(Style style)
int miny
Definition: CUFont.h:116
int computeKerning(Uint32 a, Uint32 b) const
int _size
Definition: CUFont.h:229
int getLineSkip() const
Definition: CUFont.h:426
unsigned int _fontDescent
Definition: CUFont.h:238
bool buildAtlas(const char *charset)
Definition: CUFont.h:875
const std::string & getStyleName() const
Definition: CUFont.h:386
std::vector< Uint32 > _glyphset
Definition: CUFont.h:260
static std::shared_ptr< Font > alloc(const char *file, int size)
Definition: CUFont.h:361
TTF_Font * _data
Definition: CUFont.h:232
void layoutAtlas(const std::vector< std::vector< Uint32 > > &rectangle)
unsigned int _fontHeight
Definition: CUFont.h:236
bool hasString(const char *text) const
Definition: CUFont.h:520
Definition: CURect.h:45
bool generateSurface(int width, int height)
std::shared_ptr< Texture > getRenderedQuad(Uint32 thechar, Vec2 &offset, const Rect &rect, std::vector< Vertex2 > &vertices)
Font::Style operator&(Font::Style lhs, Font::Style rhs)
Definition: CUFont.h:1521
bool hasGlyph(char a) const
Definition: CUFont.h:474
SDL_Surface * _surface
Definition: CUFont.h:270
bool buildAtlasAsync()
bool _useKerning
Definition: CUFont.h:246
unsigned int getKerning(char a, char b) const
Definition: CUFont.h:651
bool isFixedWidth() const
Definition: CUFont.h:439
int maxy
Definition: CUFont.h:118
int minx
Definition: CUFont.h:112
bool init(const char *file, int size)
Definition: CUFont.h:325
const std::string & getName() const
Definition: CUFont.h:376
std::string _name
Definition: CUFont.h:225
int operator*(Font::Style value)
Definition: CUFont.h:1503
Size getSize(const char *text, bool utf8=true) const
Definition: CUFont.h:721
bool buildAtlas()
Definition: CUFont.h:827
Rect getInternalBoundsASCII(const std::string &text) const
Style
Definition: CUFont.h:134
Hinting getHinting() const
Definition: CUFont.h:562
std::vector< std::vector< Uint32 > > planAtlas(int width, int height)
std::string _stylename
Definition: CUFont.h:227
Resolution _render
Definition: CUFont.h:254
Size getSizeUTF8(const std::string &text) const
bool _hasAtlas
Definition: CUFont.h:258
Definition: CUAnimationNode.h:52
Hinting
Definition: CUFont.h:154
std::unordered_map< Uint32, Rect > _glyphmap
Definition: CUFont.h:262
bool _fixedWidth
Definition: CUFont.h:244
Resolution
Definition: CUFont.h:187
Metrics computeMetrics(Uint32 thechar) const
bool init(const std::string &file, int size)
void clearAtlas()
std::shared_ptr< Texture > _texture
Definition: CUFont.h:268
std::unordered_map< Uint32, Metrics > _glyphsize
Definition: CUFont.h:264