2014-05-12 22:05:28 +00:00
# pragma once
2017-10-31 17:12:50 +00:00
# ifndef ES_CORE_RESOURCES_FONT_H
# define ES_CORE_RESOURCES_FONT_H
2013-10-04 23:24:41 +00:00
2017-11-01 22:21:10 +00:00
# include "math/Vector2f.h"
# include "math/Vector2i.h"
2014-06-20 01:30:09 +00:00
# include "resources/ResourceManager.h"
2017-11-01 22:21:10 +00:00
# include "Renderer.h"
2014-06-20 01:30:09 +00:00
# include "ThemeData.h"
2017-11-01 22:21:10 +00:00
# include <ft2build.h>
# include FT_FREETYPE_H
# include <vector>
2013-10-04 23:24:41 +00:00
class TextCache ;
2017-07-28 03:05:46 +00:00
# define FONT_SIZE_MINI ((unsigned int)(0.030f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
# define FONT_SIZE_SMALL ((unsigned int)(0.035f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
# define FONT_SIZE_MEDIUM ((unsigned int)(0.045f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
# define FONT_SIZE_LARGE ((unsigned int)(0.085f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
2013-10-04 23:24:41 +00:00
2014-03-17 00:52:15 +00:00
# define FONT_PATH_LIGHT ": / opensans_hebrew_condensed_light.ttf"
# define FONT_PATH_REGULAR ": / opensans_hebrew_condensed_regular.ttf"
2014-05-01 19:47:33 +00:00
enum Alignment
{
ALIGN_LEFT ,
ALIGN_CENTER , // centers both horizontally and vertically
2017-08-15 02:34:34 +00:00
ALIGN_RIGHT ,
ALIGN_TOP ,
ALIGN_BOTTOM
2014-05-01 19:47:33 +00:00
} ;
2013-10-04 23:24:41 +00:00
//A TrueType Font renderer that uses FreeType and OpenGL.
//The library is automatically initialized when it's needed.
class Font : public IReloadable
{
public :
static void initLibrary ( ) ;
static std : : shared_ptr < Font > get ( int size , const std : : string & path = getDefaultPath ( ) ) ;
2014-05-12 22:05:28 +00:00
virtual ~ Font ( ) ;
2013-10-04 23:24:41 +00:00
2017-10-28 20:24:35 +00:00
Vector2f sizeText ( std : : string text , float lineSpacing = 1.5f ) ; // Returns the expected size of a string when rendered. Extra spacing is applied to the Y axis.
2013-10-04 23:24:41 +00:00
TextCache * buildTextCache ( const std : : string & text , float offsetX , float offsetY , unsigned int color ) ;
2017-10-28 20:24:35 +00:00
TextCache * buildTextCache ( const std : : string & text , Vector2f offset , unsigned int color , float xLen , Alignment alignment = ALIGN_LEFT , float lineSpacing = 1.5f ) ;
2013-10-04 23:24:41 +00:00
void renderTextCache ( TextCache * cache ) ;
2014-07-27 21:44:02 +00:00
std : : string wrapText ( std : : string text , float xLen ) ; // Inserts newlines into text to make it wrap properly.
2017-10-28 20:24:35 +00:00
Vector2f sizeWrappedText ( std : : string text , float xLen , float lineSpacing = 1.5f ) ; // Returns the expected size of a string after wrapping is applied.
Vector2f getWrappedTextCursorOffset ( std : : string text , float xLen , size_t cursor , float lineSpacing = 1.5f ) ; // Returns the position of of the cursor after moving "cursor" characters.
2013-10-04 23:24:41 +00:00
2014-05-12 22:05:28 +00:00
float getHeight ( float lineSpacing = 1.5f ) const ;
2014-07-27 21:44:02 +00:00
float getLetterHeight ( ) ;
2013-10-04 23:24:41 +00:00
void unload ( std : : shared_ptr < ResourceManager > & rm ) override ;
void reload ( std : : shared_ptr < ResourceManager > & rm ) override ;
int getSize ( ) const ;
2014-02-16 18:27:58 +00:00
inline const std : : string & getPath ( ) const { return mPath ; }
2013-10-04 23:24:41 +00:00
2014-03-17 00:52:15 +00:00
inline static const char * getDefaultPath ( ) { return FONT_PATH_REGULAR ; }
2014-01-01 05:39:22 +00:00
static std : : shared_ptr < Font > getFromTheme ( const ThemeData : : ThemeElement * elem , unsigned int properties , const std : : shared_ptr < Font > & orig ) ;
2014-03-27 21:47:25 +00:00
size_t getMemUsage ( ) const ; // returns an approximation of VRAM used by this font's texture (in bytes)
static size_t getTotalMemUsage ( ) ; // returns an approximation of total VRAM used by font textures (in bytes)
2013-10-04 23:24:41 +00:00
private :
static FT_Library sLibrary ;
static std : : map < std : : pair < std : : string , int > , std : : weak_ptr < Font > > sFontMap ;
Font ( int size , const std : : string & path ) ;
2014-07-27 21:44:02 +00:00
struct FontTexture
2014-05-12 22:05:28 +00:00
{
2014-07-27 21:44:02 +00:00
GLuint textureId ;
2017-10-28 20:24:35 +00:00
Vector2i textureSize ;
2014-05-12 22:05:28 +00:00
2017-10-28 20:24:35 +00:00
Vector2i writePos ;
2014-07-27 21:44:02 +00:00
int rowHeight ;
2014-05-12 22:05:28 +00:00
2014-08-11 23:05:18 +00:00
FontTexture ( ) ;
~ FontTexture ( ) ;
2017-10-28 20:24:35 +00:00
bool findEmpty ( const Vector2i & size , Vector2i & cursor_out ) ;
2014-08-11 23:05:18 +00:00
// you must call initTexture() after creating a FontTexture to get a textureId
void initTexture ( ) ; // initializes the OpenGL texture according to this FontTexture's settings, updating textureId
void deinitTexture ( ) ; // deinitializes the OpenGL texture if any exists, is automatically called in the destructor
2014-05-12 22:05:28 +00:00
} ;
2014-08-30 20:36:56 +00:00
struct FontFace
{
const ResourceData data ;
FT_Face face ;
FontFace ( ResourceData & & d , int size ) ;
virtual ~ FontFace ( ) ;
} ;
2014-08-11 23:05:18 +00:00
void rebuildTextures ( ) ;
void unloadTextures ( ) ;
2014-07-27 21:44:02 +00:00
std : : vector < FontTexture > mTextures ;
2014-05-12 22:05:28 +00:00
2017-10-28 20:24:35 +00:00
void getTextureForNewGlyph ( const Vector2i & glyphSize , FontTexture * & tex_out , Vector2i & cursor_out ) ;
2014-07-27 21:44:02 +00:00
2014-08-30 20:36:56 +00:00
std : : map < unsigned int , std : : unique_ptr < FontFace > > mFaceCache ;
2017-11-10 18:48:23 +00:00
FT_Face getFaceForChar ( unsigned int id ) ;
2014-08-30 20:36:56 +00:00
void clearFaceCache ( ) ;
2014-07-27 21:44:02 +00:00
struct Glyph
{
FontTexture * texture ;
2017-10-28 20:24:35 +00:00
Vector2f texPos ;
Vector2f texSize ; // in texels!
2014-07-27 21:44:02 +00:00
2017-10-28 20:24:35 +00:00
Vector2f advance ;
Vector2f bearing ;
2014-07-27 21:44:02 +00:00
} ;
2017-11-10 18:48:23 +00:00
std : : map < unsigned int , Glyph > mGlyphMap ;
2013-10-04 23:24:41 +00:00
2017-11-10 18:48:23 +00:00
Glyph * getGlyph ( unsigned int id ) ;
2014-07-27 21:44:02 +00:00
int mMaxGlyphHeight ;
const int mSize ;
2013-10-04 23:24:41 +00:00
const std : : string mPath ;
2014-05-12 22:05:28 +00:00
2014-05-13 01:03:02 +00:00
float getNewlineStartOffset ( const std : : string & text , const unsigned int & charStart , const float & xLen , const Alignment & alignment ) ;
2014-05-12 22:05:28 +00:00
friend TextCache ;
2013-10-04 23:24:41 +00:00
} ;
2014-01-24 22:21:10 +00:00
// Used to store a sort of "pre-rendered" string.
// When a TextCache is constructed (Font::buildTextCache()), the vertices and texture coordinates of the string are calculated and stored in the TextCache object.
2014-05-12 22:05:28 +00:00
// Rendering a previously constructed TextCache (Font::renderTextCache) every frame is MUCH faster than rebuilding one every frame.
2014-01-24 22:21:10 +00:00
// Keep in mind you still need the Font object to render a TextCache (as the Font holds the OpenGL texture), and if a Font changes your TextCache may become invalid.
2013-10-04 23:24:41 +00:00
class TextCache
{
2014-07-27 21:44:02 +00:00
protected :
2013-10-04 23:24:41 +00:00
struct Vertex
{
2017-10-28 20:24:35 +00:00
Vector2f pos ;
Vector2f tex ;
2013-10-04 23:24:41 +00:00
} ;
2014-07-27 21:44:02 +00:00
struct VertexList
{
2014-08-11 23:05:18 +00:00
GLuint * textureIdPtr ; // this is a pointer because the texture ID can change during deinit/reinit (when launching a game)
2014-07-27 21:44:02 +00:00
std : : vector < Vertex > verts ;
std : : vector < GLubyte > colors ;
} ;
std : : vector < VertexList > vertexLists ;
public :
2013-10-04 23:24:41 +00:00
struct CacheMetrics
{
2017-10-28 20:24:35 +00:00
Vector2f size ;
2013-10-04 23:24:41 +00:00
} metrics ;
void setColor ( unsigned int color ) ;
2014-07-27 21:44:02 +00:00
friend Font ;
2013-10-04 23:24:41 +00:00
} ;
2017-10-31 17:12:50 +00:00
# endif // ES_CORE_RESOURCES_FONT_H