/
font.h
221 lines (192 loc) · 6.63 KB
/
font.h
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/** @file font.h Font with metrics.
*
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/
#ifndef LIBGUI_FONT_H
#define LIBGUI_FONT_H
#include <de/libdeng2.h>
#include <de/Rule>
#include <de/Rectangle>
#include <de/String>
#include <de/Vector>
#include <de/Range>
#include <QFont>
#include <QImage>
#include <QList>
#include "libgui.h"
namespace de {
/**
* Font with metrics.
*/
class LIBGUI_PUBLIC Font
{
public:
/**
* Rich formatting instructions for a string of text.
*
* The formatting instructions are composed of a sequence of ranges that
* specify various modifications to the original font. It is important to
* note that a RichFormat instance always needs to be set up for a specific
* source text string. Also, RichFormat is out-of-band data: when operating
* on a piece of rich text (using the methods of Font), the formatting is
* always provided in parallel to the plain version of the text.
*
* Use RichFormat::fromPlainText() to set up a RichFormat for a string of
* plain text.
*
* Use RichFormat::initFromStyledText() to set up a RichFormat for a string
* of text that contains style information (as escape sequences that start
* with the Esc ASCII code 0x1b).
*/
class RichFormat
{
public:
RichFormat();
RichFormat(RichFormat const &other);
/**
* Constructs a RichFormat that specifies no formatting instructions.
*
* @param plainText Plain text.
*
* @return RichFormat instance with a single range that uses the
* default formatting.
*/
static RichFormat fromPlainText(String const &plainText);
/**
* Initializes this RichFormat instance with the styles found in the
* provided styled text (using escape sequences).
*
* @param styledText Text with style markup.
*
* @return Corresponding plain text for use with the methods of Font.
*/
String initFromStyledText(String const &styledText);
enum Weight {
OriginalWeight = -1,
Normal = 0,
Light = 1,
Bold = 2
};
enum Style {
OriginalStyle = -1,
Regular = 0,
Italic = 1
};
enum Color
{
OriginalColor = -1,
NormalColor = 0,
HighlightColor = 1,
DimmedColor = 2,
AccentColor = 3
};
/**
* Clips this RichFormat so that it covers only the specified range.
* The indices are translated to be relative to the provided range.
*
* @param range Target range for clipping.
*
* @return RichFormat with only those ranges covering @a range.
*/
RichFormat subRange(Rangei const &range) const;
/**
* Iterates the rich format ranges of a RichFormat.
*
* @note Iterator::next() must be called before at least once after
* constructing the instance to move the iterator onto the first range.
*/
struct Iterator
{
RichFormat const &format;
int index;
Iterator(RichFormat const &f);
bool hasNext() const;
void next();
bool isOriginal() const;
Rangei range() const;
float sizeFactor() const;
Weight weight() const;
Style style() const;
int color() const;
bool markIndent() const;
};
private:
struct FormatRange
{
Rangei range;
float sizeFactor;
Weight weight;
Style style;
int colorIndex;
bool markIndent;
FormatRange() : sizeFactor(1.f), weight(OriginalWeight),
style(OriginalStyle), colorIndex(-1), markIndent(false) {}
};
typedef QList<FormatRange> Ranges;
Ranges _ranges;
};
public:
Font();
Font(Font const &other);
Font(QFont const &font);
QFont toQFont() const;
/**
* Determines the size of the given line of text, i.e., how large an area
* is covered by the glyphs. (0,0) is at the baseline, left edge of the
* line. The rectangle may extend into negative coordinates.
*
* @param textLine Text to measure.
*
* @return Rectangle covered by the text.
*/
Rectanglei measure(String const &textLine) const;
Rectanglei measure(String const &textLine, RichFormat const &format) const;
/**
* Returns the advance width of a line of text. This is not the same as
* the width of the rectangle returned by measure().
*
* @param textLine Text to measure.
*
* @return Width of the line of text (including non-visible parts like
* whitespace).
*/
int advanceWidth(String const &textLine) const;
int advanceWidth(String const &textLine, RichFormat const &format) const;
/**
* Rasterizes a line of text onto a 32-bit RGBA image.
*
* @param textLine Text to rasterize.
* @param foreground Text foreground color.
* @param background Background color.
*
* @return Image containing the rasterized text.
*/
QImage rasterize(String const &textLine,
Vector4ub const &foreground = Vector4ub(255, 255, 255, 255),
Vector4ub const &background = Vector4ub(255, 255, 255, 0)) const;
QImage rasterize(String const &textLine,
RichFormat const &format,
Vector4ub const &foreground = Vector4ub(255, 255, 255, 255),
Vector4ub const &background = Vector4ub(255, 255, 255, 0)) const;
Rule const &height() const;
Rule const &ascent() const;
Rule const &descent() const;
Rule const &lineSpacing() const;
private:
DENG2_PRIVATE(d)
};
} // namespace de
#endif // LIBGUI_FONT_H