mirror of https://github.com/minetest/minetest.git
Merge 177b52acb0
into d767ab0890
This commit is contained in:
commit
297d2342ff
|
@ -2681,6 +2681,8 @@ Version History
|
||||||
* Formspec version 7 (5.8.0):
|
* Formspec version 7 (5.8.0):
|
||||||
* style[]: Add focused state for buttons
|
* style[]: Add focused state for buttons
|
||||||
* Add field_enter_after_edit[] (experimental)
|
* Add field_enter_after_edit[] (experimental)
|
||||||
|
* Formspec version 8 (5.9.0):
|
||||||
|
* hypertext[]: Allow `em` as a length unit
|
||||||
|
|
||||||
Elements
|
Elements
|
||||||
--------
|
--------
|
||||||
|
@ -3535,6 +3537,10 @@ Some tags can enclose text, they open with `<tagname>` and close with `</tagname
|
||||||
Tags can have attributes, in that case, attributes are in the opening tag in
|
Tags can have attributes, in that case, attributes are in the opening tag in
|
||||||
form of a key/value separated with equal signs. Attribute values should not be quoted.
|
form of a key/value separated with equal signs. Attribute values should not be quoted.
|
||||||
|
|
||||||
|
Attributes that describe lengths (font size and image dimensions) can be a regular
|
||||||
|
number, which describes the size in pixels, or a number with the unit `em`, which
|
||||||
|
describes the size in relation to the font size of the enclosing element.
|
||||||
|
|
||||||
If you want to insert a literal greater-than sign or a backslash into the text,
|
If you want to insert a literal greater-than sign or a backslash into the text,
|
||||||
you must escape it by preceding it with a backslash.
|
you must escape it by preceding it with a backslash.
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,9 @@ This is a normal text.
|
||||||
|
|
||||||
<bigger><mono>style</mono> test</bigger>
|
<bigger><mono>style</mono> test</bigger>
|
||||||
<style color=#FFFF00>Yellow text.</style> <style color=#FF0000>Red text.</style>
|
<style color=#FFFF00>Yellow text.</style> <style color=#FF0000>Red text.</style>
|
||||||
<style size=24>Size 24.</style> <style size=16>Size 16</style>. <style size=12>Size 12.</style>
|
<style size=24>Size 24.</style> <style size=16>Size 16.</style> <style size=12>Size 12.</style>
|
||||||
|
<style size=2em>Size 2em.</style> <style size=1em>Size 1em.</style> <style size=0.5em>Size 0.5em.</style>
|
||||||
|
<style size=3em>Size 3em. <style size=0.5em>Half of 3em.</style></style>
|
||||||
<style font=normal>Normal font.</style> <style font=mono>Mono font.</style>
|
<style font=normal>Normal font.</style> <style font=mono>Mono font.</style>
|
||||||
|
|
||||||
<bigger>Tag test</bigger>
|
<bigger>Tag test</bigger>
|
||||||
|
@ -112,6 +114,10 @@ Normal:
|
||||||
<img name=testformspec_item.png float=left>
|
<img name=testformspec_item.png float=left>
|
||||||
<mono>float=right</mono>:
|
<mono>float=right</mono>:
|
||||||
<img name=testformspec_item.png float=right>
|
<img name=testformspec_item.png float=right>
|
||||||
|
<mono>width=1em height=2em</mono>:
|
||||||
|
<img name=testformspec_item.png width=1em height=2em>
|
||||||
|
<mono>width=2em</mono> inside <mono>width=2em</mono> (should render at <mono>width=4em</mono>):
|
||||||
|
<style size=2em><img name=testformspec_item.png width=2em></style>
|
||||||
|
|
||||||
<bigger><mono>item</mono> test</bigger>
|
<bigger><mono>item</mono> test</bigger>
|
||||||
Normal:
|
Normal:
|
||||||
|
|
|
@ -49,6 +49,49 @@ static bool check_integer(const std::string &str)
|
||||||
return *endptr == '\0';
|
return *endptr == '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_length(const std::string &str)
|
||||||
|
{
|
||||||
|
return ParsedText::LengthValue(str).isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// LengthValue - A data structure representing a (possibly relative) length
|
||||||
|
|
||||||
|
ParsedText::LengthValue::LengthValue(const std::string &str)
|
||||||
|
{
|
||||||
|
char *unitptr = nullptr;
|
||||||
|
this->size = std::strtod(str.c_str(), &unitptr);
|
||||||
|
|
||||||
|
if (this->size <= 0)
|
||||||
|
this->size = 0;
|
||||||
|
this->unit = unitptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParsedText::LengthValue::isValid()
|
||||||
|
{
|
||||||
|
return this->getAbsoluteValue(1) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ParsedText::LengthValue::getAbsoluteValue(const double &em_size)
|
||||||
|
{
|
||||||
|
if (this->unit.empty())
|
||||||
|
return this->size;
|
||||||
|
else if (this->unit == "em")
|
||||||
|
return this->size * em_size;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ParsedText::LengthValue::getAbsoluteValue()
|
||||||
|
{
|
||||||
|
return getAbsoluteValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParsedText::LengthValue::isAbsolute()
|
||||||
|
{
|
||||||
|
return getAbsoluteValue() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// ParsedText - A text parser
|
// ParsedText - A text parser
|
||||||
|
|
||||||
|
@ -63,7 +106,7 @@ void ParsedText::Element::setStyle(StyleList &style)
|
||||||
if (parseColorString(style["hovercolor"], color, false))
|
if (parseColorString(style["hovercolor"], color, false))
|
||||||
this->hovercolor = color;
|
this->hovercolor = color;
|
||||||
|
|
||||||
unsigned int font_size = std::atoi(style["fontsize"].c_str());
|
this->font_size = std::atoi(style["fontsize"].c_str());
|
||||||
|
|
||||||
FontMode font_mode = FM_Standard;
|
FontMode font_mode = FM_Standard;
|
||||||
if (style["fontstyle"] == "mono")
|
if (style["fontstyle"] == "mono")
|
||||||
|
@ -72,9 +115,9 @@ void ParsedText::Element::setStyle(StyleList &style)
|
||||||
// hypertext[] only accepts absolute font size values and has a hardcoded
|
// hypertext[] only accepts absolute font size values and has a hardcoded
|
||||||
// default font size of 16. This is the only way to make hypertext[]
|
// default font size of 16. This is the only way to make hypertext[]
|
||||||
// respect font size settings that I can think of.
|
// respect font size settings that I can think of.
|
||||||
font_size = myround(font_size / 16.0f * g_fontengine->getFontSize(font_mode));
|
this->font_size = myround(this->font_size / 16.0f * g_fontengine->getFontSize(font_mode));
|
||||||
|
|
||||||
FontSpec spec(font_size, font_mode,
|
FontSpec spec(this->font_size, font_mode,
|
||||||
is_yes(style["bold"]), is_yes(style["italic"]));
|
is_yes(style["bold"]), is_yes(style["italic"]));
|
||||||
|
|
||||||
// TODO: find a way to check font validity
|
// TODO: find a way to check font validity
|
||||||
|
@ -83,7 +126,7 @@ void ParsedText::Element::setStyle(StyleList &style)
|
||||||
|
|
||||||
if (!this->font)
|
if (!this->font)
|
||||||
printf("No font found ! Size=%d, mode=%d, bold=%s, italic=%s\n",
|
printf("No font found ! Size=%d, mode=%d, bold=%s, italic=%s\n",
|
||||||
font_size, font_mode, style["bold"].c_str(),
|
this->font_size, font_mode, style["bold"].c_str(),
|
||||||
style["italic"].c_str());
|
style["italic"].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,9 +384,8 @@ void ParsedText::parseGenericStyleAttr(
|
||||||
style[name] = is_yes(value);
|
style[name] = is_yes(value);
|
||||||
|
|
||||||
} else if (name == "size") {
|
} else if (name == "size") {
|
||||||
if (check_integer(value))
|
if (check_length(value))
|
||||||
style["fontsize"] = value;
|
style["fontsize"] = value;
|
||||||
|
|
||||||
} else if (name == "font") {
|
} else if (name == "font") {
|
||||||
if (value == "mono" || value == "normal")
|
if (value == "mono" || value == "normal")
|
||||||
style["fontstyle"] = value;
|
style["fontstyle"] = value;
|
||||||
|
@ -512,13 +554,13 @@ u32 ParsedText::parseTag(const wchar_t *text, u32 cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.count("width")) {
|
if (attrs.count("width")) {
|
||||||
int width = stoi(attrs["width"]);
|
int width = LengthValue(attrs["width"]).getAbsoluteValue(m_element->font_size);
|
||||||
if (width > 0)
|
if (width > 0)
|
||||||
m_element->dim.Width = width;
|
m_element->dim.Width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.count("height")) {
|
if (attrs.count("height")) {
|
||||||
int height = stoi(attrs["height"]);
|
int height = LengthValue(attrs["height"]).getAbsoluteValue(m_element->font_size);
|
||||||
if (height > 0)
|
if (height > 0)
|
||||||
m_element->dim.Height = height;
|
m_element->dim.Height = height;
|
||||||
}
|
}
|
||||||
|
@ -595,9 +637,18 @@ u32 ParsedText::parseTag(const wchar_t *text, u32 cursor)
|
||||||
|
|
||||||
// Update styles accordingly
|
// Update styles accordingly
|
||||||
m_style.clear();
|
m_style.clear();
|
||||||
for (auto tag = m_active_tags.crbegin(); tag != m_active_tags.crend(); ++tag)
|
unsigned int font_size = 0;
|
||||||
for (const auto &prop : (*tag)->style)
|
for (auto tag = m_active_tags.crbegin(); tag != m_active_tags.crend(); ++tag) {
|
||||||
m_style[prop.first] = prop.second;
|
for (const auto &prop : (*tag)->style) {
|
||||||
|
if (prop.first == "fontsize") {
|
||||||
|
// resolve font size
|
||||||
|
font_size = LengthValue(prop.second).getAbsoluteValue(font_size);
|
||||||
|
} else {
|
||||||
|
m_style[prop.first] = prop.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_style["fontsize"] = std::to_string(font_size);
|
||||||
|
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,17 @@ public:
|
||||||
typedef std::unordered_map<std::string, std::string> StyleList;
|
typedef std::unordered_map<std::string, std::string> StyleList;
|
||||||
typedef std::unordered_map<std::string, std::string> AttrsList;
|
typedef std::unordered_map<std::string, std::string> AttrsList;
|
||||||
|
|
||||||
|
struct LengthValue
|
||||||
|
{
|
||||||
|
double size;
|
||||||
|
std::string unit;
|
||||||
|
LengthValue(const std::string &str);
|
||||||
|
bool isValid();
|
||||||
|
bool isAbsolute();
|
||||||
|
double getAbsoluteValue();
|
||||||
|
double getAbsoluteValue(const double &em_size);
|
||||||
|
};
|
||||||
|
|
||||||
struct Tag
|
struct Tag
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -98,6 +109,7 @@ public:
|
||||||
ValignType valign;
|
ValignType valign;
|
||||||
|
|
||||||
gui::IGUIFont *font;
|
gui::IGUIFont *font;
|
||||||
|
unsigned int font_size;
|
||||||
|
|
||||||
irr::video::SColor color;
|
irr::video::SColor color;
|
||||||
irr::video::SColor hovercolor;
|
irr::video::SColor hovercolor;
|
||||||
|
|
|
@ -244,7 +244,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
// base64-encoded SHA-1 (27+\0).
|
// base64-encoded SHA-1 (27+\0).
|
||||||
|
|
||||||
// See also formspec [Version History] in doc/lua_api.md
|
// See also formspec [Version History] in doc/lua_api.md
|
||||||
#define FORMSPEC_API_VERSION 7
|
#define FORMSPEC_API_VERSION 8
|
||||||
|
|
||||||
#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
|
#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue