Skip to content

Commit e04c60e

Browse files
committed
Align special characters to the base line of the rendered string
1 parent 81d9ca8 commit e04c60e

File tree

6 files changed

+73
-25
lines changed

6 files changed

+73
-25
lines changed

code/graphics/opengl/gropengldraw.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,14 @@ void gr_opengl_string(float sx, float sy, const char *s, int resize_mode, int in
781781

782782
if (specialChar) {
783783
if (pass == 1) {
784+
// We compute the top offset of the special character by aligning it to the base line of the string
785+
// This is done by moving to the base line of the string by adding the ascender value and then
786+
// accounting for the height of the text with the height of the special font
787+
auto yOffset = nvgFont->getTopOffset() +
788+
(nvgFont->getAscender() - nvgFont->getSpecialCharacterFont()->h);
789+
784790
gr_opengl_string_old(sx + x * scaleX,
785-
sy + (y + nvgFont->getTopOffset()) * scaleY,
791+
sy + (y + yOffset) * scaleY,
786792
text,
787793
text + 1,
788794
nvgFont->getSpecialCharacterFont(),

code/graphics/software/FSFont.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,34 @@ namespace font
3737

3838
float FSFont::getHeight() const
3939
{
40-
return this->getTextHeight() + this->offsetTop + this->offsetBottom;
40+
return _height;
4141
}
4242

4343
const SCP_string &FSFont::getName() const
4444
{
4545
return this->name;
4646
}
4747

48-
void FSFont::checkHeight() {
49-
float height = this->getTextHeight() + this->offsetTop + this->offsetBottom;
48+
void FSFont::computeFontMetrics() {
49+
_height = this->getTextHeight() + this->offsetTop + this->offsetBottom;
5050

51-
if (height <= 1.0f)
51+
// By default the base line of the font is also the lowest point of the font
52+
_ascender = _height;
53+
_descender = 0.0f;
54+
55+
checkFontMetrics();
56+
}
57+
void FSFont::checkFontMetrics() {
58+
if (_height <= 1.0f)
5259
{
5360
Warning(LOCATION, "The height of font %s has an invalid height of %f, must be greater than one!",
54-
getName().c_str(), height);
61+
getName().c_str(), _height);
5562
}
5663
}
64+
float FSFont::getAscender() {
65+
return _ascender;
66+
}
67+
float FSFont::getDescender() {
68+
return _descender;
69+
}
5770
}

code/graphics/software/FSFont.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ namespace font
3737
float offsetTop; //!< The offset at the top of a line of text
3838
float offsetBottom; //!< The offset at the bottom of a line of text
3939

40+
float _height;
41+
float _ascender;
42+
float _descender;
43+
44+
void checkFontMetrics();
45+
4046
public:
4147

4248
/**
@@ -92,7 +98,7 @@ namespace font
9298
*
9399
* @return The height.
94100
*/
95-
virtual float getHeight() const;
101+
float getHeight() const;
96102

97103
/**
98104
* @brief Gets the height of this font in pixels without the top and bottom offsets.
@@ -155,6 +161,21 @@ namespace font
155161
*/
156162
void setBottomOffset(float newOffset);
157163

158-
void checkHeight();
164+
/**
165+
* @brief Recomputes the font metrics
166+
*/
167+
virtual void computeFontMetrics();
168+
169+
/**
170+
* @brief Gets the ascender value of this font
171+
* @return The ascender value
172+
*/
173+
float getAscender();
174+
175+
/**
176+
* @breif Gets the descender value of this font
177+
* @return The descender value
178+
*/
179+
float getDescender();
159180
};
160181
}

code/graphics/software/NVGFont.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,7 @@ namespace font
108108

109109
float NVGFont::getTextHeight() const
110110
{
111-
auto path = graphics::paths::PathRenderer::instance();
112-
113-
path->saveState();
114-
path->resetState();
115-
116-
path->fontFaceId(m_handle);
117-
path->fontSize(m_size);
118-
path->textLetterSpacing(m_letterSpacing);
119-
120-
float lineh;
121-
path->textMetrics(nullptr, nullptr, &lineh);
122-
123-
path->restoreState();
124-
125-
return lineh;
111+
return m_lineHeight;
126112
}
127113

128114
extern int get_char_width_old(font* fnt, ubyte c1, ubyte c2, int *width, int* spacing);
@@ -232,4 +218,22 @@ namespace font
232218

233219
path->restoreState();
234220
}
221+
void NVGFont::computeFontMetrics() {
222+
auto path = graphics::paths::PathRenderer::instance();
223+
224+
path->saveState();
225+
path->resetState();
226+
227+
path->fontFaceId(m_handle);
228+
path->fontSize(m_size);
229+
path->textLetterSpacing(m_letterSpacing);
230+
231+
path->textMetrics(&_ascender, &_descender, &m_lineHeight);
232+
233+
path->restoreState();
234+
235+
_height = m_lineHeight + this->offsetTop + this->offsetBottom;
236+
237+
checkFontMetrics();
238+
}
235239
}

code/graphics/software/NVGFont.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace font
1616

1717
font* m_specialCharacters;
1818

19+
float m_lineHeight = 0.0f;
20+
1921
public:
2022
NVGFont();
2123
virtual ~NVGFont();
@@ -39,6 +41,8 @@ namespace font
3941
virtual void getStringSize(const char *text, size_t textLen, int resize_mode,
4042
float *width, float *height) const SCP_OVERRIDE;
4143

44+
void computeFontMetrics() override;
45+
4246
static size_t getTokenLength(const char *string, size_t maxLength);
4347
};
4448
}

code/graphics/software/font.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ namespace
203203
nvgFont->setName(fontStr);
204204

205205
// Make sure that the height is not invalid
206-
nvgFont->checkHeight();
206+
nvgFont->computeFontMetrics();
207207
}
208208

209209
void parse_vfnt_font(const SCP_string& fontFilename)
@@ -300,7 +300,7 @@ namespace
300300
font->setBottomOffset(temp);
301301
}
302302
// Make sure that the height is not invalid
303-
font->checkHeight();
303+
font->computeFontMetrics();
304304
}
305305

306306
void font_parse_setup(const char *fileName)

0 commit comments

Comments
 (0)