CUGL 1.3
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
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 MIT 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 
760  Rect getInternalBounds(const std::string& text, bool utf8=true) const;
761 
797  Rect getInternalBounds(const char* text, bool utf8=true) const {
798  return getInternalBounds(std::string(text), utf8);
799  }
800 
801 #pragma mark -
802 #pragma mark Atlas Support
803 
808  void clearAtlas();
809 
825  bool buildAtlas() {
826  bool result = buildAtlasAsync();
827  return result && (getAtlas() != nullptr);
828  }
829 
849  bool buildAtlas(const std::string& charset) {
850  bool result = buildAtlasAsync(charset);
851  return result && (getAtlas() != nullptr);
852  }
853 
873  bool buildAtlas(const char* charset) {
874  bool result = buildAtlasAsync(charset);
875  return result && (getAtlas() != nullptr);
876  }
877 
895  bool buildAtlasAsync();
896 
916  bool buildAtlasAsync(const std::string& charset);
917 
937  bool buildAtlasAsync(const char* charset) {
938  return buildAtlasAsync(std::string(charset));
939  }
940 
950  const std::shared_ptr<Texture>& getAtlas();
951 
960  bool hasAtlas() const { return _hasAtlas; }
961 
962 #pragma mark -
963 #pragma mark Rendering
964 
997  std::shared_ptr<Texture> getQuads(const std::string& text, const Vec2& origin,
998  std::vector<Vertex2>& vertices, bool utf8=true);
999 
1031  std::shared_ptr<Texture> getQuads(const char* text, const Vec2& origin,
1032  std::vector<Vertex2>& vertices, bool utf8=true) {
1033  return getQuads(std::string(text),origin,vertices,utf8);
1034  }
1035 
1072  std::shared_ptr<Texture> getQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1073  std::vector<Vertex2>& vertices, bool utf8=true);
1074 
1111  std::shared_ptr<Texture> getQuads(const char* text, const Vec2& origin, const Rect& rect,
1112  std::vector<Vertex2>& vertices, bool utf8=true) {
1113  return getQuads(std::string(text),origin,rect,vertices,utf8);
1114  }
1115 
1136  std::shared_ptr<Texture> getQuad(Uint32 thechar, Vec2& offset, std::vector<Vertex2>& vertices);
1137 
1162  std::shared_ptr<Texture> getQuad(Uint32 thechar, Vec2& offset, const Rect& rect,
1163  std::vector<Vertex2>& vertices);
1164 
1165 
1166 #pragma mark -
1167 #pragma mark Rendering Internals
1168 protected:
1199  void getAtlasQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1200  std::vector<Vertex2>& vertices, bool utf8);
1201 
1235  std::shared_ptr<Texture> getRenderedQuads(const std::string& text, const Vec2& origin, const Rect& rect,
1236  std::vector<Vertex2>& vertices, bool utf8);
1237 
1257  bool getAtlasQuad(Uint32 thechar, Vec2& offset, const Rect& rect, std::vector<Vertex2>& vertices);
1258 
1280  std::shared_ptr<Texture> getRenderedQuad(Uint32 thechar, Vec2& offset, const Rect& rect,
1281  std::vector<Vertex2>& vertices);
1282 
1300  Size getSizeASCII(const std::string& text) const;
1301 
1319  Size getSizeUTF8(const std::string& text) const;
1320 
1350  Rect getInternalBoundsASCII(const std::string& text) const;
1351 
1381  Rect getInternalBoundsUTF8(const std::string& text) const;
1382 
1383 #pragma mark -
1384 #pragma mark Atlas Preparation
1385 
1393  int prepareAtlas();
1394 
1405  int prepareAtlas(std::string charset);
1406 
1410  void prepareAtlasKerning();
1411 
1419  Metrics computeMetrics(Uint32 thechar) const;
1420 
1429  int computeKerning(Uint32 a, Uint32 b) const;
1430 
1446  void computeAtlasSize(int* width, int* height);
1447 
1459  std::vector< std::vector<Uint32> > planAtlas(int width, int height);
1460 
1466  void layoutAtlas(const std::vector< std::vector<Uint32> >& rectangle);
1467 
1478  bool generateSurface(int width, int height);
1479 
1488  SDL_Surface* allocSurface(int width, int height);
1489 };
1490 
1491 #pragma mark -
1492 #pragma mark Style Bit-Wise Operators
1493 
1499 inline int operator*(Font::Style value) {
1500  return static_cast<int>(value);
1501 }
1502 
1508 inline Font::Style operator|(Font::Style lhs, Font::Style rhs) {
1509  return static_cast<Font::Style>((*lhs) | (*rhs));
1510 }
1511 
1517 inline Font::Style operator&(Font::Style lhs, Font::Style rhs) {
1518  return static_cast<Font::Style>((*lhs) & (*rhs));
1519 }
1520 
1527 inline Font::Style operator^(Font::Style lhs, Font::Style rhs) {
1528  return static_cast<Font::Style>((*lhs) ^ (*rhs));
1529 }
1530 
1536 inline Font::Style operator~(Font::Style lhs) {
1537  return static_cast<Font::Style>(~(*lhs));
1538 }
1539 
1540 
1541 }
1542 
1543 #endif /* __CU_FONT_H__ */
cugl::Font::init
bool init(const std::string &file, int size)
cugl::Font::Hinting
Hinting
Definition: CUFont.h:154
cugl::Font::getAscent
int getAscent() const
Definition: CUFont.h:416
cugl::Font::computeAtlasSize
void computeAtlasSize(int *width, int *height)
cugl::Font::getInternalBoundsUTF8
Rect getInternalBoundsUTF8(const std::string &text) const
cugl::Font::_size
int _size
Definition: CUFont.h:229
cugl::Font::_hasAtlas
bool _hasAtlas
Definition: CUFont.h:258
cugl::Font::setKerning
void setKerning(bool kerning)
cugl::Font::buildAtlasAsync
bool buildAtlasAsync(const char *charset)
Definition: CUFont.h:937
cugl::Font::hasString
bool hasString(const char *text) const
Definition: CUFont.h:520
cugl::Font::getAtlasQuad
bool getAtlasQuad(Uint32 thechar, Vec2 &offset, const Rect &rect, std::vector< Vertex2 > &vertices)
cugl::Font::Style::BOLD
cugl::Font::_data
TTF_Font * _data
Definition: CUFont.h:232
cugl::Font::getQuad
std::shared_ptr< Texture > getQuad(Uint32 thechar, Vec2 &offset, std::vector< Vertex2 > &vertices)
cugl::Font::Metrics::minx
int minx
Definition: CUFont.h:112
cugl::Font::isFixedWidth
bool isFixedWidth() const
Definition: CUFont.h:439
cugl::Font::Hinting::NORMAL
cugl::Font::getAtlas
const std::shared_ptr< Texture > & getAtlas()
cugl::Font
Definition: CUFont.h:98
cugl::Font::_hints
Hinting _hints
Definition: CUFont.h:252
cugl::Font::_fontLineSkip
unsigned int _fontLineSkip
Definition: CUFont.h:242
cugl::Font::prepareAtlasKerning
void prepareAtlasKerning()
cugl::Font::getInternalBounds
Rect getInternalBounds(const char *text, bool utf8=true) const
Definition: CUFont.h:797
cugl::Font::alloc
static std::shared_ptr< Font > alloc(const char *file, int size)
Definition: CUFont.h:361
cugl::Font::buildAtlasAsync
bool buildAtlasAsync()
cugl::Font::setStyle
void setStyle(Style style)
cugl::Font::computeKerning
int computeKerning(Uint32 a, Uint32 b) const
cugl::Size
Definition: CUSize.h:57
cugl::Font::getSize
Size getSize(const char *text, bool utf8=true) const
Definition: CUFont.h:721
cugl::Font::getMetrics
const Metrics getMetrics(char thechar) const
Definition: CUFont.h:619
cugl::Font::_fixedWidth
bool _fixedWidth
Definition: CUFont.h:244
cugl::Font::getQuads
std::shared_ptr< Texture > getQuads(const char *text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8=true)
Definition: CUFont.h:1111
cugl::Font::getInternalBoundsASCII
Rect getInternalBoundsASCII(const std::string &text) const
cugl::Font::computeMetrics
Metrics computeMetrics(Uint32 thechar) const
cugl::Font::getQuads
std::shared_ptr< Texture > getQuads(const char *text, const Vec2 &origin, std::vector< Vertex2 > &vertices, bool utf8=true)
Definition: CUFont.h:1031
cugl::Font::Metrics::miny
int miny
Definition: CUFont.h:116
cugl::Font::getLineSkip
int getLineSkip() const
Definition: CUFont.h:426
cugl::Font::Hinting::LIGHT
cugl::Font::buildAtlas
bool buildAtlas()
Definition: CUFont.h:825
cugl::Font::buildAtlas
bool buildAtlas(const std::string &charset)
Definition: CUFont.h:849
cugl::Font::_glyphsize
std::unordered_map< Uint32, Metrics > _glyphsize
Definition: CUFont.h:264
cugl::Rect
Definition: CURect.h:45
cugl::Font::getDescent
int getDescent() const
Definition: CUFont.h:407
cugl::Font::~Font
~Font()
Definition: CUFont.h:287
cugl::Font::_surface
SDL_Surface * _surface
Definition: CUFont.h:270
cugl::Font::getHeight
int getHeight() const
Definition: CUFont.h:397
cugl::Font::getSizeUTF8
Size getSizeUTF8(const std::string &text) const
cugl::Font::_stylename
std::string _stylename
Definition: CUFont.h:227
cugl::Font::getRenderedQuad
std::shared_ptr< Texture > getRenderedQuad(Uint32 thechar, Vec2 &offset, const Rect &rect, std::vector< Vertex2 > &vertices)
cugl::Font::prepareAtlas
int prepareAtlas()
cugl::Font::getStyle
Style getStyle() const
Definition: CUFont.h:536
cugl::Font::Resolution
Resolution
Definition: CUFont.h:187
cugl::Font::getQuads
std::shared_ptr< Texture > getQuads(const std::string &text, const Vec2 &origin, std::vector< Vertex2 > &vertices, bool utf8=true)
cugl::Font::hasGlyph
bool hasGlyph(char a) const
Definition: CUFont.h:474
cugl::Font::_useKerning
bool _useKerning
Definition: CUFont.h:246
cugl::Font::Style::ITALIC
cugl::Font::Metrics::maxx
int maxx
Definition: CUFont.h:114
cugl::Font::buildAtlas
bool buildAtlas(const char *charset)
Definition: CUFont.h:873
cugl::Font::usesKerning
bool usesKerning() const
Definition: CUFont.h:450
cugl::Font::_render
Resolution _render
Definition: CUFont.h:254
cugl::Font::Style::UNDERLINE
cugl::Font::_fontAscent
unsigned int _fontAscent
Definition: CUFont.h:240
cugl::Font::hasAtlas
bool hasAtlas() const
Definition: CUFont.h:960
cugl::Font::Metrics::advance
int advance
Definition: CUFont.h:120
cugl::Font::getName
const std::string & getName() const
Definition: CUFont.h:376
cugl::Font::getHinting
Hinting getHinting() const
Definition: CUFont.h:562
cugl::Font::Metrics
Definition: CUFont.h:109
cugl::Font::_fontDescent
unsigned int _fontDescent
Definition: CUFont.h:238
cugl::Font::getStyleName
const std::string & getStyleName() const
Definition: CUFont.h:386
cugl::Vec2
Definition: CUVec2.h:61
cugl::Font::getRenderedQuads
std::shared_ptr< Texture > getRenderedQuads(const std::string &text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8)
cugl::Font::Resolution::SHADED
cugl::Font::allocSurface
SDL_Surface * allocSurface(int width, int height)
cugl::Font::Style::STRIKE
cugl::Font::_texture
std::shared_ptr< Texture > _texture
Definition: CUFont.h:268
cugl::Font::Resolution::SOLID
cugl::Font::alloc
static std::shared_ptr< Font > alloc(const std::string &file, int size)
Definition: CUFont.h:344
cugl::Font::getInternalBounds
Rect getInternalBounds(const std::string &text, bool utf8=true) const
cugl::Font::_fontHeight
unsigned int _fontHeight
Definition: CUFont.h:236
cugl::Font::Hinting::MONO
cugl::Font::clearAtlas
void clearAtlas()
cugl::Font::Metrics::maxy
int maxy
Definition: CUFont.h:118
cugl::Font::dispose
virtual void dispose()
cugl::Font::planAtlas
std::vector< std::vector< Uint32 > > planAtlas(int width, int height)
cugl::Font::getKerning
unsigned int getKerning(char a, char b) const
Definition: CUFont.h:651
cugl::Font::hasString
bool hasString(const std::string &text) const
cugl::Font::init
bool init(const char *file, int size)
Definition: CUFont.h:325
cugl::Font::Hinting::NONE
cugl::Font::setResolution
void setResolution(Resolution resolution)
Definition: CUFont.h:603
cugl::Font::getResolution
Resolution getResolution() const
Definition: CUFont.h:588
cugl::Font::_glyphset
std::vector< Uint32 > _glyphset
Definition: CUFont.h:260
cugl::Font::_kernmap
std::unordered_map< Uint32, std::unordered_map< Uint32, Uint32 > > _kernmap
Definition: CUFont.h:266
cugl::Font::_style
Style _style
Definition: CUFont.h:250
cugl::Font::Style
Style
Definition: CUFont.h:134
cugl::Font::Font
Font()
cugl::Font::_glyphmap
std::unordered_map< Uint32, Rect > _glyphmap
Definition: CUFont.h:262
cugl::Font::getAtlasQuads
void getAtlasQuads(const std::string &text, const Vec2 &origin, const Rect &rect, std::vector< Vertex2 > &vertices, bool utf8)
cugl::Font::generateSurface
bool generateSurface(int width, int height)
cugl::Font::Resolution::BLENDED
cugl::Font::setHinting
void setHinting(Hinting hinting)
cugl::Font::getSizeASCII
Size getSizeASCII(const std::string &text) const
cugl::Font::getSize
Size getSize(const std::string &text, bool utf8=true) const
cugl::Font::_name
std::string _name
Definition: CUFont.h:225
cugl::Font::Style::NORMAL
cugl::Font::layoutAtlas
void layoutAtlas(const std::vector< std::vector< Uint32 > > &rectangle)