File: glFont.h

package info (click to toggle)
spring 88.0%2Bdfsg1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 41,524 kB
  • sloc: cpp: 343,114; ansic: 38,414; python: 12,257; java: 12,203; awk: 5,748; sh: 1,204; xml: 997; perl: 405; objc: 192; makefile: 181; php: 134; sed: 2
file content (202 lines) | stat: -rwxr-xr-x 7,856 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _GLFONT_H
#define _GLFONT_H

#include <string>
#include <list>
#include <limits.h> // for INT_MAX

#include "System/float4.h"

#undef GetCharWidth // winapi.h


static const int FONT_LEFT     = 1 << 0;
static const int FONT_RIGHT    = 1 << 1;
static const int FONT_CENTER   = 1 << 2;
static const int FONT_BASELINE = 1 << 3; //! align to face baseline
static const int FONT_VCENTER  = 1 << 4;
static const int FONT_TOP      = 1 << 5; //! align to text ascender
static const int FONT_BOTTOM   = 1 << 6; //! align to text descender
static const int FONT_ASCENDER = 1 << 7; //! align to face ascender
static const int FONT_DESCENDER= 1 << 8; //! align to face descender

static const int FONT_OUTLINE     = 1 << 9;
static const int FONT_SHADOW      = 1 << 10;
static const int FONT_NORM        = 1 << 11; //! render in 0..1 space instead of 0..vsx|vsy
static const int FONT_SCALE       = 1 << 12; //! given size argument will be treated as scaling and not absolute fontsize

static const int FONT_NEAREST     = 1 << 13; //! round x,y render pos to nearest integer, so there is no interpolation blur for small fontsizes

class CVertexArray;
class CglFont
{
public:
	static CglFont* LoadFont(const std::string& fontFile, int size, int outlinewidth = 2, float outlineweight = 5.0f, int start = 32, int end = 254);
	CglFont(const std::string& fontfile, int size, int outlinewidth, float  outlineweight);
	~CglFont();

	//! The calling of Begin() .. End() is optional,
	//! but can increase the performance of drawing multiple strings a lot (upto 10x)
	void Begin(const bool immediate = false, const bool resetColors = true);
	void End();

	void glWorldPrint(const float3& p, const float size, const std::string& str);
	/**
	 * @param s  absolute font size, or relative scale, if option FONT_SCALE is set
	 * @param options  FONT_SCALE | FONT_NORM |
	 *                 (FONT_LEFT | FONT_CENTER | FONT_RIGHT) |
	 *                 (FONT_BASELINE | FONT_DESCENDER | FONT_VCENTER |
	 *                  FONT_TOP | FONT_ASCENDER | FONT_BOTTOM) |
	 *                 FONT_NEAREST | FONT_OUTLINE | FONT_SHADOW
	 */
	void glPrint(float x, float y, float s, const int& options, const std::string& str);
	void glPrintTable(float x, float y, float s, const int& options, const std::string& str);
	void glFormat(float x, float y, float s, const int& options, const std::string& fmt, ...);
	void glFormat(float x, float y, float s, const int& options, const char* fmt, ...);

	void SetAutoOutlineColor(bool enable); //! auto select outline color for in-text-colorcodes
	void SetTextColor(const float4* color = NULL);
	void SetOutlineColor(const float4* color = NULL);
	void SetColors(const float4* textColor = NULL, const float4* outlineColor = NULL);
	void SetTextColor(const float& r, const float& g, const float& b, const float& a) { const float4 f = float4(r,g,b,a); SetTextColor(&f); };
	void SetOutlineColor(const float& r, const float& g, const float& b, const float& a) { const float4 f = float4(r,g,b,a); SetOutlineColor(&f); };

	//! Adds \n's (and '...' if it would be too high) until the text fits into maxWidth/maxHeight
	int WrapInPlace(std::string& text, float fontSize, const float maxWidth, const float maxHeight = 1e9) const;
	std::list<std::string> Wrap(const std::string& text, float fontSize, const float maxWidth, const float maxHeight = 1e9) const;

	float GetKerning(const unsigned int& left_char, const unsigned int& right_char) const;
	float GetCharacterWidth(const unsigned char c) const;
	float GetTextWidth(const std::string& text) const;
	float GetTextHeight(const std::string& text, float* descender = NULL, int* numLines = NULL) const;
	int   GetTextNumLines(const std::string& text) const;
	static std::string StripColorCodes(const std::string& text);

	inline float GetLineHeight()     const { return lineHeight; }
	inline float GetSize()           const { return fontSize; }
	inline float GetDescender()      const { return fontDescender; }
	inline int   GetOutlineWidth()   const { return outlineWidth; }
	inline float GetOutlineWeight()  const { return outlineWeight; }
	inline std::string GetFilePath() const { return fontPath; }
	inline std::string GetFamily()   const { return fontFamily; }
	inline std::string GetStyle()    const { return fontStyle; }
	int GetCharStart() const { return charstart; }
	int GetCharEnd()   const { return charend; }

	inline unsigned int GetTexture()   const { return fontTexture; }
	inline unsigned int GetTexWidth()  const { return texWidth; }
	inline unsigned int GetTexHeight() const { return texHeight; }

	static const char ColorCodeIndicator = '\xFF'; //FIXME use a non-printable char? (<32)
	static const char ColorResetIndicator = '\x08'; //! =: '\\b'

public:
	typedef std::vector<float4> ColorMap;

	struct GlyphInfo
	{
		GlyphInfo()
		{
			u0  = v0  = u1  = v1  = 1.0f;
			x0  = y0  = x1  = y1  = 0.0f;
			us0 = vs0 = us1 = vs1 = 1.0f;
			advance = height = 1.0f;
			descender = 0.0f;

			for (int i = 0; i <= 255; i++) {
				kerning[i] = 1.0f;
			}
		};

		float u0, v0, u1, v1;
		float x0, y0, x1, y1;
		float us0, vs0, us1, vs1; //! shadow texcoords
		float advance, height, descender;
		float kerning[256];
	} glyphs[256];

private:
	static const float4* ChooseOutlineColor(const float4& textColor);

	void RenderString(float x, float y, const float& scaleX, const float& scaleY, const std::string& str);
	void RenderStringShadow(float x, float y, const float& scaleX, const float& scaleY, const std::string& str);
	void RenderStringOutlined(float x, float y, const float& scaleX, const float& scaleY, const std::string& str);

private:
	struct colorcode {
		colorcode() : resetColor(false),pos(0) {};
		bool resetColor;
		float4 color;
		unsigned int pos;
	};
	struct word {
		word() : width(0.0f), text(""), isSpace(false), isLineBreak(false), isColorCode(false), numSpaces(0), pos(0) {};

		float width;
		std::string text;
		bool isSpace;
		bool isLineBreak;
		bool isColorCode;
		unsigned int numSpaces;
		unsigned int pos; //! position in the original text (needed for remerging colorcodes after wrapping; in printable chars (linebreaks and space don't count))
	};
	struct line {
		line() : width(0.0f), cost(0.0f), forceLineBreak(false) {};

		std::list<word>::iterator start, end;
		float width;
		float cost;
		bool forceLineBreak;
	};

	word SplitWord(word& w, float wantedWidth, bool smart = true) const;

	void SplitTextInWords(const std::string& text, std::list<word>* words, std::list<colorcode>* colorcodes) const;
	void RemergeColorCodes(std::list<word>* words, std::list<colorcode>& colorcodes) const;

	void AddEllipsis(std::list<line>& lines, std::list<word>& words, float maxWidth) const;

	void WrapTextConsole(std::list<word>& words, float maxWidth, float maxHeight) const;
	void WrapTextKnuth(std::list<word>& words, float maxWidth, float maxHeight) const;

private:
	float fontSize;
	float fontDescender;
	float lineHeight;
	std::string fontPath;
	std::string fontFamily;
	std::string fontStyle;
	int outlineWidth;
	float outlineWeight;
	int chars;
	unsigned int charstart;
	unsigned int charend;

	unsigned int fontTexture;
	unsigned int texWidth,texHeight;

	ColorMap stripTextColors;
	ColorMap stripOutlineColors;

	bool inBeginEnd;
	CVertexArray* va;
	CVertexArray* va2;

	bool autoOutlineColor; //! auto select outline color for in-text-colorcodes

	bool setColor; //! used for backward compability (so you can call glPrint (w/o BeginEnd and no shadow/outline!) and set the color yourself via glColor)

	float4 textColor;
	float4 outlineColor;

	//! \::ColorResetIndicator will reset to those (they are the colors set when glPrint was called)
	float4 baseTextColor;
	float4 baseOutlineColor;
};

extern CglFont* font;
extern CglFont* smallFont;

#endif /* _GLFONT_H */