Skip to content

Commit 2bec83e

Browse files
authored
Add FormSpec font styling options (#9763)
* Add FormSpec font styling options * Change multiplication to stof * Remove extraneous check
1 parent 1dd6c8e commit 2bec83e

7 files changed

+105
-11
lines changed

doc/lua_api.txt

+18
Original file line numberDiff line numberDiff line change
@@ -2747,6 +2747,18 @@ Some types may inherit styles from parent types.
27472747
button's content when set.
27482748
* bgimg_pressed - background image when pressed. Defaults to bgimg when not provided.
27492749
* This is deprecated, use states instead.
2750+
* font - Sets font type. This is a comma separated list of options. Valid options:
2751+
* Main font type options. These cannot be combined with each other:
2752+
* `normal`: Default font
2753+
* `mono`: Monospaced font
2754+
* Font modification options. If used without a main font type, `normal` is used:
2755+
* `bold`: Makes font bold.
2756+
* `italic`: Makes font italic.
2757+
Default `normal`.
2758+
* font_size - Sets font size. Default is user-set. Can have multiple values:
2759+
* `<number>`: Sets absolute font size to `number`.
2760+
* `+<number>`/`-<number>`: Offsets default font size by `number` points.
2761+
* `*<number>`: Multiplies default font size by `number`, similar to CSS `em`.
27502762
* border - boolean, draw border. Set to false to hide the bevelled button pane. Default true.
27512763
* content_offset - 2d vector, shifts the position of the button's content without resizing it.
27522764
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
@@ -2758,11 +2770,15 @@ Some types may inherit styles from parent types.
27582770
* scrollbar
27592771
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
27602772
* table, textlist
2773+
* font - Sets font type. See button `font` property for more information.
2774+
* font_size - Sets font size. See button `font_size` property for more information.
27612775
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
27622776
* dropdown
27632777
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
27642778
* field, pwdfield, textarea
27652779
* border - set to false to hide the textbox background and border. Default true.
2780+
* font - Sets font type. See button `font` property for more information.
2781+
* font_size - Sets font size. See button `font_size` property for more information.
27662782
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
27672783
* textcolor - color. Default white.
27682784
* image
@@ -2771,6 +2787,8 @@ Some types may inherit styles from parent types.
27712787
* item_image
27722788
* noclip - boolean, set to true to allow the element to exceed formspec bounds. Default to false.
27732789
* label, vertlabel
2790+
* font - Sets font type. See button `font` property for more information.
2791+
* font_size - Sets font size. See button `font_size` property for more information.
27742792
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
27752793
* image_button (additional properties)
27762794
* fgimg - standard image. Defaults to none.

src/client/fontengine.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,21 @@ unsigned int FontEngine::getDefaultFontSize()
186186
return m_default_size[m_currentMode];
187187
}
188188

189+
unsigned int FontEngine::getFontSize(FontMode mode)
190+
{
191+
if (m_currentMode == FM_Simple) {
192+
if (mode == FM_Mono || mode == FM_SimpleMono)
193+
return m_default_size[FM_SimpleMono];
194+
else
195+
return m_default_size[FM_Simple];
196+
}
197+
198+
if (mode == FM_Unspecified)
199+
return m_default_size[FM_Standard];
200+
201+
return m_default_size[mode];
202+
}
203+
189204
/******************************************************************************/
190205
void FontEngine::readSettings()
191206
{

src/client/fontengine.h

+3
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ class FontEngine
124124
/** get default font size */
125125
unsigned int getDefaultFontSize();
126126

127+
/** get font size for a specific mode */
128+
unsigned int getFontSize(FontMode mode);
129+
127130
/** initialize font engine */
128131
void initialize(Settings* main_settings, gui::IGUIEnvironment* env);
129132

src/gui/StyleSpec.h

+49
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1818
*/
1919

2020
#include "client/tile.h" // ITextureSource
21+
#include "client/fontengine.h"
2122
#include "debug.h"
2223
#include "irrlichttypes_extrabloated.h"
2324
#include "util/string.h"
25+
#include <algorithm>
2426
#include <array>
2527

2628
#pragma once
@@ -46,6 +48,8 @@ class StyleSpec
4648
ALPHA,
4749
CONTENT_OFFSET,
4850
PADDING,
51+
FONT,
52+
FONT_SIZE,
4953
NUM_PROPERTIES,
5054
NONE
5155
};
@@ -98,6 +102,10 @@ class StyleSpec
98102
return CONTENT_OFFSET;
99103
} else if (name == "padding") {
100104
return PADDING;
105+
} else if (name == "font") {
106+
return FONT;
107+
} else if (name == "font_size") {
108+
return FONT_SIZE;
101109
} else {
102110
return NONE;
103111
}
@@ -225,6 +233,47 @@ class StyleSpec
225233
return vec;
226234
}
227235

236+
gui::IGUIFont *getFont() const
237+
{
238+
FontSpec spec(FONT_SIZE_UNSPECIFIED, FM_Standard, false, false);
239+
240+
const std::string &font = properties[FONT];
241+
const std::string &size = properties[FONT_SIZE];
242+
243+
if (font.empty() && size.empty())
244+
return nullptr;
245+
246+
std::vector<std::string> modes = split(font, ',');
247+
248+
for (size_t i = 0; i < modes.size(); i++) {
249+
if (modes[i] == "normal")
250+
spec.mode = FM_Standard;
251+
else if (modes[i] == "mono")
252+
spec.mode = FM_Mono;
253+
else if (modes[i] == "bold")
254+
spec.bold = true;
255+
else if (modes[i] == "italic")
256+
spec.italic = true;
257+
}
258+
259+
if (!size.empty()) {
260+
int calc_size = 1;
261+
262+
if (size[0] == '*') {
263+
std::string new_size = size.substr(1); // Remove '*' (invalid for stof)
264+
calc_size = stof(new_size) * g_fontengine->getFontSize(spec.mode);
265+
} else if (size[0] == '+' || size[0] == '-') {
266+
calc_size = stoi(size) + g_fontengine->getFontSize(spec.mode);
267+
} else {
268+
calc_size = stoi(size);
269+
}
270+
271+
spec.size = (unsigned)std::min(std::max(calc_size, 1), 999);
272+
}
273+
274+
return g_fontengine->getFont(spec);
275+
}
276+
228277
video::ITexture *getTexture(Property prop, ISimpleTextureSource *tsrc,
229278
video::ITexture *def) const
230279
{

src/gui/guiButton.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ void GUIButton::setFromStyle(const StyleSpec& style)
788788
setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
789789
setDrawBorder(style.getBool(StyleSpec::BORDER, true));
790790
setUseAlphaChannel(style.getBool(StyleSpec::ALPHA, true));
791+
setOverrideFont(style.getFont());
791792

792793
if (style.isNotDefault(StyleSpec::BGIMG)) {
793794
video::ITexture *texture = style.getTexture(StyleSpec::BGIMG,

src/gui/guiFormSpecMenu.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2424
#include <limits>
2525
#include <sstream>
2626
#include "guiFormSpecMenu.h"
27-
#include "guiScrollBar.h"
28-
#include "guiTable.h"
2927
#include "constants.h"
3028
#include "gamedef.h"
3129
#include "client/keycode.h"
@@ -64,9 +62,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
6462
#include "guiEditBoxWithScrollbar.h"
6563
#include "guiInventoryList.h"
6664
#include "guiItemImage.h"
67-
#include "guiScrollBar.h"
6865
#include "guiScrollContainer.h"
69-
#include "guiTable.h"
7066
#include "intlGUIEditBox.h"
7167
#include "guiHyperText.h"
7268

@@ -1482,6 +1478,7 @@ void GUIFormSpecMenu::parsePwdField(parserData* data, const std::string &element
14821478
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
14831479
e->setDrawBorder(style.getBool(StyleSpec::BORDER, true));
14841480
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
1481+
e->setOverrideFont(style.getFont());
14851482

14861483
irr::SEvent evt;
14871484
evt.EventType = EET_KEY_INPUT_EVENT;
@@ -1565,6 +1562,7 @@ void GUIFormSpecMenu::createTextField(parserData *data, FieldSpec &spec,
15651562
if (style.get(StyleSpec::BGCOLOR, "") == "transparent") {
15661563
e->setDrawBackground(false);
15671564
}
1565+
e->setOverrideFont(style.getFont());
15681566

15691567
e->drop();
15701568
}
@@ -1778,6 +1776,11 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
17781776

17791777
std::vector<std::string> lines = split(text, '\n');
17801778

1779+
auto style = getDefaultStyleForElement("label", "");
1780+
gui::IGUIFont *font = style.getFont();
1781+
if (!font)
1782+
font = m_font;
1783+
17811784
for (unsigned int i = 0; i != lines.size(); i++) {
17821785
std::wstring wlabel_colors = translate_string(
17831786
utf8_to_wide(unescape_string(lines[i])));
@@ -1799,7 +1802,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
17991802

18001803
rect = core::rect<s32>(
18011804
pos.X, pos.Y,
1802-
pos.X + m_font->getDimension(wlabel_plain.c_str()).Width,
1805+
pos.X + font->getDimension(wlabel_plain.c_str()).Width,
18031806
pos.Y + imgsize.Y);
18041807

18051808
} else {
@@ -1821,7 +1824,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
18211824

18221825
rect = core::rect<s32>(
18231826
pos.X, pos.Y - m_btn_height,
1824-
pos.X + m_font->getDimension(wlabel_plain.c_str()).Width,
1827+
pos.X + font->getDimension(wlabel_plain.c_str()).Width,
18251828
pos.Y + m_btn_height);
18261829
}
18271830

@@ -1837,9 +1840,9 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
18371840
spec.fid);
18381841
e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
18391842

1840-
auto style = getDefaultStyleForElement("label", spec.fname);
18411843
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
18421844
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
1845+
e->setOverrideFont(font);
18431846

18441847
m_fields.push_back(spec);
18451848

@@ -1867,6 +1870,11 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &elemen
18671870

18681871
MY_CHECKPOS("vertlabel",1);
18691872

1873+
auto style = getDefaultStyleForElement("vertlabel", "", "label");
1874+
gui::IGUIFont *font = style.getFont();
1875+
if (!font)
1876+
font = m_font;
1877+
18701878
v2s32 pos;
18711879
core::rect<s32> rect;
18721880

@@ -1880,7 +1888,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &elemen
18801888
// isn't quite tall enough and cuts off the text.
18811889
rect = core::rect<s32>(pos.X, pos.Y,
18821890
pos.X + imgsize.X,
1883-
pos.Y + font_line_height(m_font) *
1891+
pos.Y + font_line_height(font) *
18841892
(text.length() + 1));
18851893

18861894
} else {
@@ -1892,7 +1900,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &elemen
18921900
rect = core::rect<s32>(
18931901
pos.X, pos.Y+((imgsize.Y/2) - m_btn_height),
18941902
pos.X+15, pos.Y +
1895-
font_line_height(m_font) *
1903+
font_line_height(font) *
18961904
(text.length() + 1) +
18971905
((imgsize.Y/2) - m_btn_height));
18981906
}
@@ -1917,9 +1925,9 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &elemen
19171925
rect, false, false, data->current_parent, spec.fid);
19181926
e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
19191927

1920-
auto style = getDefaultStyleForElement("vertlabel", spec.fname, "label");
19211928
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false));
19221929
e->setOverrideColor(style.getColor(StyleSpec::TEXTCOLOR, video::SColor(0xFFFFFFFF)));
1930+
e->setOverrideFont(font);
19231931

19241932
m_fields.push_back(spec);
19251933

src/gui/guiFormSpecMenu.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2727
#include "inventorymanager.h"
2828
#include "modalMenu.h"
2929
#include "guiInventoryList.h"
30+
#include "guiScrollBar.h"
3031
#include "guiTable.h"
3132
#include "network/networkprotocol.h"
3233
#include "client/joystick_controller.h"
@@ -37,7 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3738
class InventoryManager;
3839
class ISimpleTextureSource;
3940
class Client;
40-
class GUIScrollBar;
4141
class TexturePool;
4242
class GUIScrollContainer;
4343

0 commit comments

Comments
 (0)