diff --git a/code/nel/include/nel/gui/css_parser.h b/code/nel/include/nel/gui/css_parser.h
new file mode 100644
index 000000000..cb4cea62e
--- /dev/null
+++ b/code/nel/include/nel/gui/css_parser.h
@@ -0,0 +1,39 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef CL_CSS_PARSER_H
+#define CL_CSS_PARSER_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_style.h"
+
+namespace NLGUI
+{
+ /**
+ * \brief CSS style parsing
+ * \date 2019-03-15 10:50 GMT
+ * \author Meelis Mägi (Nimetu)
+ */
+ class CCssParser {
+ public:
+ // parse style declaration, eg "color: red; font-size: 10px;"
+ static TStyle parseDecls(const std::string &styleString);
+ };
+
+}//namespace
+
+#endif // CL_CSS_PARSER_H
+
diff --git a/code/nel/include/nel/gui/css_style.h b/code/nel/include/nel/gui/css_style.h
new file mode 100644
index 000000000..2a854a6d9
--- /dev/null
+++ b/code/nel/include/nel/gui/css_style.h
@@ -0,0 +1,141 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef CL_CSS_STYLE_H
+#define CL_CSS_STYLE_H
+
+#include "nel/misc/types_nl.h"
+#include "nel/misc/rgba.h"
+
+namespace NLGUI
+{
+ typedef std::map TStyle;
+
+ /**
+ * \brief CSS style rules
+ * \date 2019-03-15 10:50 GMT
+ * \author Meelis Mägi (Nimetu)
+ */
+ class CStyleParams
+ {
+ public:
+ struct STextShadow
+ {
+ public:
+ STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
+ : Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
+ { }
+
+ bool Enabled;
+ bool Outline;
+ sint32 X;
+ sint32 Y;
+ NLMISC::CRGBA Color;
+ };
+ public:
+ CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
+ {
+ FontSize=10;
+ FontWeight=400;
+ FontOblique=false;
+ Underlined=false;
+ StrikeThrough=false;
+ GlobalColor=false;
+ Width=-1;
+ Height=-1;
+ MaxWidth=-1;
+ MaxHeight=-1;
+ BorderWidth=1;
+ BackgroundColor=NLMISC::CRGBA::Black;
+ BackgroundColorOver=NLMISC::CRGBA::Black;
+ }
+ uint FontSize;
+ uint FontWeight;
+ bool FontOblique;
+ std::string FontFamily;
+ NLMISC::CRGBA TextColor;
+ STextShadow TextShadow;
+ bool GlobalColor;
+ bool Underlined;
+ bool StrikeThrough;
+ sint32 Width;
+ sint32 Height;
+ sint32 MaxWidth;
+ sint32 MaxHeight;
+ sint32 BorderWidth;
+ NLMISC::CRGBA BackgroundColor;
+ NLMISC::CRGBA BackgroundColorOver;
+ };
+
+ class CCssStyle {
+ public:
+
+
+ // 'browser' style, overwriten with ''
+ CStyleParams Root;
+
+ // current element style
+ CStyleParams Current;
+
+ private:
+ std::vector _StyleStack;
+
+ // test if str is one of "thin/medium/thick" and return its pixel value
+ bool scanCssLength(const std::string& str, uint32 &px) const;
+
+ // read style attribute
+ void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams ¤t) const;
+
+ public:
+ void reset();
+
+ inline uint getFontSizeSmaller() const
+ {
+ if (Current.FontSize < 5)
+ return 3;
+ return Current.FontSize-2;
+ }
+
+ inline void pushStyle()
+ {
+ _StyleStack.push_back(Current);
+ }
+
+ inline void popStyle()
+ {
+ if (_StyleStack.empty())
+ Current = Root;
+ else
+ {
+ Current = _StyleStack.back();
+ _StyleStack.pop_back();
+ }
+ }
+
+ // apply style string to this.Root
+ void applyRootStyle(const std::string &styleString);
+
+ // apply style string to this.Current
+ void applyStyle(const std::string &styleString);
+
+ void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0) const;
+
+ };
+
+}//namespace
+
+#endif // CL_CSS_STYLE_H
+
diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h
index b21841f8c..d8935f431 100644
--- a/code/nel/include/nel/gui/group_html.h
+++ b/code/nel/include/nel/gui/group_html.h
@@ -24,12 +24,11 @@
#include "nel/gui/ctrl_button.h"
#include "nel/gui/group_table.h"
#include "nel/gui/libwww_types.h"
+#include "nel/gui/css_style.h"
// forward declaration
typedef void CURLM;
-typedef std::map TStyle;
-
namespace NLGUI
{
class CCtrlButton;
@@ -76,58 +75,6 @@ namespace NLGUI
static SWebOptions options;
- // text-shadow
- struct STextShadow
- {
- public:
- STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
- : Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
- { }
-
- bool Enabled;
- bool Outline;
- sint32 X;
- sint32 Y;
- NLMISC::CRGBA Color;
- };
-
- class CStyleParams
- {
- public:
- CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
- {
- FontSize=10;
- FontWeight=400;
- FontOblique=false;
- Underlined=false;
- StrikeThrough=false;
- GlobalColor=false;
- Width=-1;
- Height=-1;
- MaxWidth=-1;
- MaxHeight=-1;
- BorderWidth=1;
- BackgroundColor=NLMISC::CRGBA::Black;
- BackgroundColorOver=NLMISC::CRGBA::Black;
- }
- uint FontSize;
- uint FontWeight;
- bool FontOblique;
- std::string FontFamily;
- NLMISC::CRGBA TextColor;
- STextShadow TextShadow;
- bool GlobalColor;
- bool Underlined;
- bool StrikeThrough;
- sint32 Width;
- sint32 Height;
- sint32 MaxWidth;
- sint32 MaxHeight;
- sint32 BorderWidth;
- NLMISC::CRGBA BackgroundColor;
- NLMISC::CRGBA BackgroundColorOver;
- };
-
// ImageDownload system
enum TDataType {ImgType= 0, BnpType};
enum TImageType {NormalImage=0, OverImage};
@@ -535,33 +482,8 @@ namespace NLGUI
// IL mode
bool _LI;
- // Current active style
- CStyleParams _Style;
- // Default style
- CStyleParams _StyleDefault;
- // Nested style stack
- std::vector _StyleParams;
- inline void pushStyle()
- {
- _StyleParams.push_back(_Style);
- }
- inline void popStyle()
- {
- if (_StyleParams.empty())
- _Style = _StyleDefault;
- else
- {
- _Style = _StyleParams.back();
- _StyleParams.pop_back();
- }
- }
-
- inline uint getFontSizeSmaller() const
- {
- if (_Style.FontSize < 5)
- return 3;
- return _Style.FontSize-2;
- }
+ // Keep track of current element style
+ CCssStyle _Style;
// Current link
std::vector _Link;
@@ -625,14 +547,6 @@ namespace NLGUI
return _TR.back();
}
- std::vector _TextShadow;
- inline STextShadow getTextShadow() const
- {
- if (_TextShadow.empty())
- return STextShadow();
- return _TextShadow.back();
- }
-
// Forms
class CForm
{
@@ -794,10 +708,6 @@ namespace NLGUI
typedef std::map > TGroupHtmlByUIDMap;
static TGroupHtmlByUIDMap _GroupHtmlByUID;
- // read style attribute
- void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams ¤t);
- void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0);
-
// load and render local html file (from bnp for example)
void doBrowseLocalFile(const std::string &filename);
diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h
index 84eeb01e9..d7fe1251c 100644
--- a/code/nel/include/nel/gui/libwww.h
+++ b/code/nel/include/nel/gui/libwww.h
@@ -276,9 +276,14 @@ namespace NLGUI
HTML_ATTR(H6,STYLE),
};
-
#undef HTML_ATTR
+ // ***************************************************************************
+ // Read HTML color value from src and set dest
+ // Can handle #rgb(a), #rrggbb(aa) or rgb()/rgba(), hsl(), hsla() formats
+ // or color name directly
+ bool scanHTMLColor(const char *src, NLMISC::CRGBA &dest);
+
// ***************************************************************************
// Read a CSS length value, return true if one of supported units '%, rem, em, px, pt'
// On failure: 'value' and 'unit' values are undefined
diff --git a/code/nel/src/gui/css_parser.cpp b/code/nel/src/gui/css_parser.cpp
new file mode 100644
index 000000000..c45121824
--- /dev/null
+++ b/code/nel/src/gui/css_parser.cpp
@@ -0,0 +1,58 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "stdpch.h"
+
+#include
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_parser.h"
+#include "nel/gui/css_style.h"
+
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+ // ***************************************************************************
+ // Parse style declarations style, eg. "color:red; font-size: 10px;"
+ //
+ // key is converted to lowercase
+ // value is left as is
+ TStyle CCssParser::parseDecls(const std::string &styleString)
+ {
+ TStyle styles;
+ std::vector elements;
+ NLMISC::splitString(styleString, ";", elements);
+
+ for(uint i = 0; i < elements.size(); ++i)
+ {
+ std::string::size_type pos;
+ pos = elements[i].find_first_of(':');
+ if (pos != std::string::npos)
+ {
+ std::string key = trim(toLower(elements[i].substr(0, pos)));
+ std::string value = trim(elements[i].substr(pos+1));
+ styles[key] = value;
+ }
+ }
+
+ return styles;
+ }
+} // namespace
+
diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp
new file mode 100644
index 000000000..9d4b665bb
--- /dev/null
+++ b/code/nel/src/gui/css_style.cpp
@@ -0,0 +1,496 @@
+// Ryzom - MMORPG Framework
+// Copyright (C) 2010 Winch Gate Property Limited
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "stdpch.h"
+
+#include
+#include "nel/misc/types_nl.h"
+#include "nel/gui/css_style.h"
+#include "nel/gui/css_parser.h"
+#include "nel/gui/libwww.h"
+
+using namespace NLMISC;
+
+#ifdef DEBUG_NEW
+#define new DEBUG_NEW
+#endif
+
+namespace NLGUI
+{
+ // ***************************************************************************
+ void CCssStyle::reset()
+ {
+ _StyleStack.clear();
+
+ Root = CStyleParams();
+ Current = CStyleParams();
+ }
+
+ // ***************************************************************************
+ void CCssStyle::applyRootStyle(const std::string &styleString)
+ {
+ getStyleParams(styleString, Root, Root);
+ }
+
+ // ***************************************************************************
+ void CCssStyle::applyStyle(const std::string &styleString)
+ {
+ if (_StyleStack.empty())
+ {
+ getStyleParams(styleString, Current, Root);
+ }
+ else
+ {
+ getStyleParams(styleString, Current, _StyleStack.back());
+ }
+ }
+
+ bool CCssStyle::scanCssLength(const std::string& str, uint32 &px) const
+ {
+ if (fromString(str, px))
+ return true;
+
+ if (str == "thin")
+ {
+ px = 1;
+ return true;
+ }
+ if (str == "medium")
+ {
+ px = 3;
+ return true;
+ }
+ if (str == "thick")
+ {
+ px = 5;
+ return true;
+ }
+
+ return false;
+ }
+
+ // ***************************************************************************
+ // CStyleParams style;
+ // style.FontSize; // font-size: 10px;
+ // style.TextColor; // color: #ABCDEF;
+ // style.Underlined; // text-decoration: underline; text-decoration-line: underline;
+ // style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through;
+ void CCssStyle::getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams ¤t) const
+ {
+ float tmpf;
+ TStyle styles = CCssParser::parseDecls(styleString);
+ TStyle::iterator it;
+
+ // first pass: get font-size for 'em' sizes
+ for (it=styles.begin(); it != styles.end(); ++it)
+ {
+ if (it->first == "font")
+ {
+ if (it->second == "inherit")
+ {
+ style.FontSize = current.FontSize;
+ style.FontFamily = current.FontFamily;
+ style.FontWeight = current.FontWeight;
+ style.FontOblique = current.FontOblique;
+ }
+ }
+ else
+ if (it->first == "font-size")
+ {
+ if (it->second == "inherit")
+ {
+ style.FontSize = current.FontSize;
+ }
+ else
+ {
+ std::string unit;
+ if (getCssLength(tmpf, unit, it->second.c_str()))
+ {
+ if (unit == "rem")
+ style.FontSize = Root.FontSize * tmpf;
+ else if (unit == "em")
+ style.FontSize = current.FontSize * tmpf;
+ else if (unit == "pt")
+ style.FontSize = tmpf / 0.75f;
+ else if (unit == "%")
+ style.FontSize = current.FontSize * tmpf / 100.f;
+ else
+ style.FontSize = tmpf;
+ }
+ }
+ }
+ }
+
+ // second pass: rest of style
+ for (it=styles.begin(); it != styles.end(); ++it)
+ {
+ if (it->first == "border")
+ {
+ sint32 b;
+ if (it->second == "none")
+ style.BorderWidth = 0;
+ else
+ if (fromString(it->second, b))
+ style.BorderWidth = b;
+ }
+ else
+ if (it->first == "font-style")
+ {
+ if (it->second == "inherit")
+ style.FontOblique = current.FontOblique;
+ else
+ if (it->second == "italic" || it->second == "oblique")
+ style.FontOblique = true;
+ }
+ else
+ if (it->first == "font-family")
+ {
+ if (it->second == "inherit")
+ style.FontFamily = current.FontFamily;
+ else
+ style.FontFamily = it->second;
+ }
+ else
+ if (it->first == "font-weight")
+ {
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
+ uint weight = 400;
+ if (it->second == "inherit")
+ weight = current.FontWeight;
+ else
+ if (it->second == "normal")
+ weight = 400;
+ else
+ if (it->second == "bold")
+ weight = 700;
+ else
+ if (it->second == "lighter")
+ {
+ const uint lighter[] = {100, 100, 100, 100, 100, 400, 400, 700, 700};
+ uint index = current.FontWeight / 100 - 1;
+ clamp(index, 1u, 9u);
+ weight = lighter[index-1];
+ }
+ else
+ if (it->second == "bolder")
+ {
+ const uint bolder[] = {400, 400, 400, 700, 700, 900, 900, 900, 900};
+ uint index = current.FontWeight / 100 + 1;
+ clamp(index, 1u, 9u);
+ weight = bolder[index-1];
+ }
+ else
+ if (fromString(it->second, weight))
+ {
+ weight = (weight / 100);
+ clamp(weight, 1u, 9u);
+ weight *= 100;
+ }
+ style.FontWeight = weight;
+ }
+ else
+ if (it->first == "color")
+ if (it->second == "inherit")
+ style.TextColor = current.TextColor;
+ else
+ scanHTMLColor(it->second.c_str(), style.TextColor);
+ else
+ if (it->first == "text-decoration" || it->first == "text-decoration-line")
+ {
+ std::string prop(toLower(it->second));
+ style.Underlined = (prop.find("underline") != std::string::npos);
+ style.StrikeThrough = (prop.find("line-through") != std::string::npos);
+ }
+ else
+ if (it->first == "text-stroke" || it->first == "-webkit-text-stroke")
+ {
+ // text-stroke: length || color
+ bool success = false;
+ uint px = 0;
+ CRGBA color;
+ std::vector parts;
+ NLMISC::splitString(it->second, " ", parts);
+ if (parts.size() == 1)
+ {
+ success = scanCssLength(parts[0], px);
+ if (!success)
+ success = scanHTMLColor(parts[0].c_str(), color);
+ }
+ else if (parts.size() == 2)
+ {
+ success = scanCssLength(parts[0], px);
+ if (success)
+ success = scanHTMLColor(parts[1].c_str(), color);
+ else
+ {
+ success = scanHTMLColor(parts[0].c_str(), color);
+ success = success && scanCssLength(parts[1], px);
+ }
+ }
+
+ // do not disable shadow if one is already set
+ if (success)
+ {
+ style.TextShadow.Enabled = (px > 0);
+ style.TextShadow.Color = color;
+ style.TextShadow.X = px;
+ style.TextShadow.Y = px;
+ style.TextShadow.Outline = true;
+ }
+ }
+ else
+ if (it->first == "text-shadow")
+ {
+ if (it->second == "none")
+ style.TextShadow = CStyleParams::STextShadow(false);
+ else
+ if (it->second == "inherit")
+ style.TextShadow = current.TextShadow;
+ else
+ {
+ // text-shadow: offset-x offset-y | blur | #color
+ // text-shadow: #color | offset-x offset-y
+ bool success = true;
+ std::string prop(it->second);
+ size_t pos;
+ pos = prop.find_first_of(",\n\r");
+ if (pos != std::string::npos)
+ prop = prop.substr(0, pos);
+
+ std::vector parts;
+ NLMISC::splitString(prop, " ", parts);
+ switch(parts.size())
+ {
+ case 1:
+ {
+ success = scanHTMLColor(it->second.c_str(), style.TextShadow.Color);
+ break;
+ }
+ // no case 2:
+ case 3:
+ {
+ if (!fromString(parts[0], style.TextShadow.X))
+ {
+ success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
+ success = success && fromString(parts[1], style.TextShadow.X);
+ success = success && fromString(parts[2], style.TextShadow.Y);
+ }
+ else
+ {
+ success = fromString(parts[1], style.TextShadow.Y);
+ success = success && scanHTMLColor(parts[2].c_str(), style.TextShadow.Color);
+ }
+ break;
+ }
+ case 4:
+ {
+ if (!fromString(parts[0], style.TextShadow.X))
+ {
+ success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
+ success = success && fromString(parts[1], style.TextShadow.X);
+ success = success && fromString(parts[2], style.TextShadow.Y);
+ // ignore blur [3]
+ }
+ else
+ {
+ success = fromString(parts[0], style.TextShadow.X);
+ success = success && fromString(parts[1], style.TextShadow.Y);
+ // ignore blur [2]
+ success = success && scanHTMLColor(parts[3].c_str(), style.TextShadow.Color);
+ }
+ break;
+ }
+ default:
+ {
+ // unsupported rule
+ break;
+ }
+ }
+
+ style.TextShadow.Enabled = success;
+ }
+ }
+ else
+ if (it->first == "width")
+ {
+ std::string unit;
+ if (getCssLength(tmpf, unit, it->second.c_str()))
+ {
+ if (unit == "rem")
+ style.Width = tmpf * Root.FontSize;
+ else if (unit == "em")
+ style.Width = tmpf * style.FontSize;
+ else if (unit == "pt")
+ style.FontSize = tmpf / 0.75f;
+ else
+ style.Width = tmpf;
+ }
+ }
+ else
+ if (it->first == "height")
+ {
+ std::string unit;
+ if (getCssLength(tmpf, unit, it->second.c_str()))
+ {
+ if (unit == "rem")
+ style.Height = tmpf * Root.FontSize;
+ else if (unit == "em")
+ style.Height = tmpf * style.FontSize;
+ else if (unit == "pt")
+ style.FontSize = tmpf / 0.75f;
+ else
+ style.Height = tmpf;
+ }
+ }
+ else
+ if (it->first == "max-width")
+ {
+ std::string unit;
+ if (getCssLength(tmpf, unit, it->second.c_str()))
+ {
+ if (unit == "rem")
+ style.MaxWidth = tmpf * Root.FontSize;
+ else if (unit == "em")
+ style.MaxWidth = tmpf * style.FontSize;
+ else if (unit == "pt")
+ style.FontSize = tmpf / 0.75f;
+ else
+ style.MaxWidth = tmpf;
+ }
+ }
+ else
+ if (it->first == "max-height")
+ {
+ std::string unit;
+ if (getCssLength(tmpf, unit, it->second.c_str()))
+ {
+ if (unit == "rem")
+ style.MaxHeight = tmpf * Root.FontSize;
+ else if (unit == "em")
+ style.MaxHeight = tmpf * style.FontSize;
+ else if (unit == "pt")
+ style.FontSize = tmpf / 0.75f;
+ else
+ style.MaxHeight = tmpf;
+ }
+ }
+ else
+ if (it->first == "-ryzom-modulate-color")
+ {
+ bool b;
+ if (it->second == "inherit")
+ style.GlobalColor = current.GlobalColor;
+ else
+ if (fromString(it->second, b))
+ style.GlobalColor = b;
+ }
+ else
+ if (it->first == "background-color")
+ {
+ if (it->second == "inherit")
+ style.BackgroundColor = current.BackgroundColor;
+ else
+ scanHTMLColor(it->second.c_str(), style.BackgroundColor);
+ }
+ else
+ if (it->first == "-ryzom-background-color-over")
+ {
+ if (it->second == "inherit")
+ style.BackgroundColorOver = current.BackgroundColorOver;
+ else
+ scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
+ }
+ }
+
+ // if outer element has underline set, then inner element cannot remove it
+ if (current.Underlined)
+ style.Underlined = current.Underlined;
+
+ // if outer element has line-through set, then inner element cannot remove it
+ if (current.StrikeThrough)
+ style.StrikeThrough = current.StrikeThrough;
+ }
+
+ // ***************************************************************************
+ void CCssStyle::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh) const
+ {
+ if (maxw <= 0) maxw = width;
+ if (maxh <= 0) maxh = height;
+
+ maxw = std::max(minw, maxw);
+ maxh = std::max(minh, maxh);
+
+ float ratio = (float) width / std::max(1, height);
+ if (width > maxw)
+ {
+ width = maxw;
+ height = std::max((sint32)(maxw /ratio), minh);
+ }
+ if (width < minw)
+ {
+ width = minw;
+ height = std::min((sint32)(minw / ratio), maxh);
+ }
+ if (height > maxh)
+ {
+ width = std::max((sint32)(maxh * ratio), minw);
+ height = maxh;
+ }
+ if (height < minh)
+ {
+ width = std::min((sint32)(minh * ratio), maxw);
+ height = minh;
+ }
+ if (width > maxw && height > maxh)
+ {
+ if (maxw/width <= maxh/height)
+ {
+ width = maxw;
+ height = std::max(minh, (sint32)(maxw / ratio));
+ }
+ else
+ {
+ width = std::max(minw, (sint32)(maxh * ratio));
+ height = maxh;
+ }
+ }
+ if (width < minw && height < minh)
+ {
+ if (minw / width <= minh / height)
+ {
+ width = std::min(maxw, (sint32)(minh * ratio));
+ height = minh;
+ }
+ else
+ {
+ width = minw;
+ height = std::min(maxh, (sint32)(minw / ratio));
+ }
+ }
+ if (width < minw && height > maxh)
+ {
+ width = minw;
+ height = maxh;
+ }
+ if (width > maxw && height < minh)
+ {
+ width = maxw;
+ height = minh;
+ }
+ }
+
+} // namespace
+
diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 36d0eab7f..ba21c6af1 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -357,7 +357,7 @@ namespace NLGUI
// apply max-width, max-height rules if asked
if (maxw > -1 || maxh > -1)
{
- applyCssMinMax(width, height, 0, 0, maxw, maxh);
+ _Style.applyCssMinMax(width, height, 0, 0, maxw, maxh);
changed = true;
}
@@ -386,29 +386,33 @@ namespace NLGUI
void CGroupHTML::setTextButtonStyle(CCtrlTextButton *ctrlButton, const CStyleParams &style)
{
// this will also set size for treating it like "display: inline-block;"
- if (style.Width > 0) ctrlButton->setWMin(_Style.Width);
- if (style.Height > 0) ctrlButton->setHMin(_Style.Height);
+ if (style.Width > 0) ctrlButton->setWMin(style.Width);
+ if (style.Height > 0) ctrlButton->setHMin(style.Height);
CViewText *pVT = ctrlButton->getViewText();
if (pVT)
{
- setTextStyle(pVT, _Style);
+ setTextStyle(pVT, style);
}
- if (_Style.BackgroundColor.A > 0)
+ if (style.BackgroundColor.A > 0)
{
- if (_Style.BackgroundColorOver.A == 0)
- _Style.BackgroundColorOver = _Style.BackgroundColor;
-
- ctrlButton->setColor(_Style.BackgroundColor);
- ctrlButton->setColorOver(_Style.BackgroundColorOver);
+ ctrlButton->setColor(style.BackgroundColor);
+ if (style.BackgroundColorOver.A == 0)
+ {
+ ctrlButton->setColorOver(style.BackgroundColor);
+ }
+ else
+ {
+ ctrlButton->setColorOver(style.BackgroundColorOver);
+ }
ctrlButton->setTexture("", "blank.tga", "", false);
ctrlButton->setTextureOver("", "blank.tga", "");
ctrlButton->setProperty("force_text_over", "true");
}
- else if (_Style.BackgroundColorOver.A > 0)
+ else if (style.BackgroundColorOver.A > 0)
{
- ctrlButton->setColorOver(_Style.BackgroundColorOver);
+ ctrlButton->setColorOver(style.BackgroundColorOver);
ctrlButton->setProperty("force_text_over", "true");
ctrlButton->setTextureOver("blank.tga", "blank.tga", "blank.tga");
}
@@ -1027,7 +1031,7 @@ namespace NLGUI
TStyle CGroupHTML::parseStyle (const string &str_styles)
{
- TStyle styles;
+ TStyle styles;
vector elements;
NLMISC::splitString(str_styles, ";", elements);
@@ -1149,392 +1153,6 @@ namespace NLGUI
_CellParams.push_back (cellParams); \
}
- static bool scanCssLength(const std::string& str, uint32 &px)
- {
- if (fromString(str, px))
- return true;
-
- if (str == "thin")
- {
- px = 1;
- return true;
- }
- if (str == "medium")
- {
- px = 3;
- return true;
- }
- if (str == "thick")
- {
- px = 5;
- return true;
- }
-
- return false;
- }
-
- static bool isHexa(char c)
- {
- return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
- }
-
- static uint8 convertHexa(char c)
- {
- return (uint8) (tolower(c) - (isdigit(c) ? '0' : ('a' - 10)));
- }
-
- // scan a color component, and return pointer to next position
- static const char *scanColorComponent(const char *src, uint8 &intensity)
- {
- if (!src) return NULL;
- if (!isHexa(*src)) return NULL;
- uint8 value = convertHexa(*src++) << 4;
- if (!isHexa(*src)) return NULL;
- value += convertHexa(*src++);
- intensity = value;
- return src;
- }
-
- static float hueToRgb(float m1, float m2, float h)
- {
- if (h < 0) h += 1.0f;
- if (h > 1) h -= 1.0f;
- if (h*6 < 1.0f) return m1 + (m2 - m1)*h*6;
- if (h*2 < 1.0f) return m2;
- if (h*3 < 2.0f) return m1 + (m2 - m1) * (2.0f/3.0f - h)*6;
- return m1;
- }
-
- static void hslToRgb(float h, float s, float l, CRGBA &result)
- {
- float m1, m2;
- if (l <= 0.5f)
- m2 = l * (s + 1.0f);
- else
- m2 = l + s - l * s;
- m1 = l*2 - m2;
-
- result.R = 255 * hueToRgb(m1, m2, h + 1.0f/3.0f);
- result.G = 255 * hueToRgb(m1, m2, h);
- result.B = 255 * hueToRgb(m1, m2, h - 1.0f/3.0f);
- result.A = 255;
- }
-
- class CNameToCol
- {
- public:
- const char *Name;
- CRGBA Color;
- CNameToCol(const char *name, CRGBA color) : Name(name), Color(color) {}
- };
-
- static CNameToCol htmlColorNameToRGBA[] =
- {
- CNameToCol("AliceBlue", CRGBA(0xF0, 0xF8, 0xFF)),
- CNameToCol("AntiqueWhite", CRGBA(0xFA, 0xEB, 0xD7)),
- CNameToCol("Aqua", CRGBA(0x00, 0xFF, 0xFF)),
- CNameToCol("Aquamarine", CRGBA(0x7F, 0xFF, 0xD4)),
- CNameToCol("Azure", CRGBA(0xF0, 0xFF, 0xFF)),
- CNameToCol("Beige", CRGBA(0xF5, 0xF5, 0xDC)),
- CNameToCol("Bisque", CRGBA(0xFF, 0xE4, 0xC4)),
- CNameToCol("Black", CRGBA(0x00, 0x00, 0x00)),
- CNameToCol("BlanchedAlmond", CRGBA(0xFF, 0xEB, 0xCD)),
- CNameToCol("Blue", CRGBA(0x00, 0x00, 0xFF)),
- CNameToCol("BlueViolet", CRGBA(0x8A, 0x2B, 0xE2)),
- CNameToCol("Brown", CRGBA(0xA5, 0x2A, 0x2A)),
- CNameToCol("BurlyWood", CRGBA(0xDE, 0xB8, 0x87)),
- CNameToCol("CadetBlue", CRGBA(0x5F, 0x9E, 0xA0)),
- CNameToCol("Chartreuse", CRGBA(0x7F, 0xFF, 0x00)),
- CNameToCol("Chocolate", CRGBA(0xD2, 0x69, 0x1E)),
- CNameToCol("Coral", CRGBA(0xFF, 0x7F, 0x50)),
- CNameToCol("CornflowerBlue", CRGBA(0x64, 0x95, 0xED)),
- CNameToCol("Cornsilk", CRGBA(0xFF, 0xF8, 0xDC)),
- CNameToCol("Crimson", CRGBA(0xDC, 0x14, 0x3C)),
- CNameToCol("Cyan", CRGBA(0x00, 0xFF, 0xFF)),
- CNameToCol("DarkBlue", CRGBA(0x00, 0x00, 0x8B)),
- CNameToCol("DarkCyan", CRGBA(0x00, 0x8B, 0x8B)),
- CNameToCol("DarkGoldenRod", CRGBA(0xB8, 0x86, 0x0B)),
- CNameToCol("DarkGray", CRGBA(0xA9, 0xA9, 0xA9)),
- CNameToCol("DarkGreen", CRGBA(0x00, 0x64, 0x00)),
- CNameToCol("DarkKhaki", CRGBA(0xBD, 0xB7, 0x6B)),
- CNameToCol("DarkMagenta", CRGBA(0x8B, 0x00, 0x8B)),
- CNameToCol("DarkOliveGreen", CRGBA(0x55, 0x6B, 0x2F)),
- CNameToCol("Darkorange", CRGBA(0xFF, 0x8C, 0x00)),
- CNameToCol("DarkOrchid", CRGBA(0x99, 0x32, 0xCC)),
- CNameToCol("DarkRed", CRGBA(0x8B, 0x00, 0x00)),
- CNameToCol("DarkSalmon", CRGBA(0xE9, 0x96, 0x7A)),
- CNameToCol("DarkSeaGreen", CRGBA(0x8F, 0xBC, 0x8F)),
- CNameToCol("DarkSlateBlue", CRGBA(0x48, 0x3D, 0x8B)),
- CNameToCol("DarkSlateGray", CRGBA(0x2F, 0x4F, 0x4F)),
- CNameToCol("DarkTurquoise", CRGBA(0x00, 0xCE, 0xD1)),
- CNameToCol("DarkViolet", CRGBA(0x94, 0x00, 0xD3)),
- CNameToCol("DeepPink", CRGBA(0xFF, 0x14, 0x93)),
- CNameToCol("DeepSkyBlue", CRGBA(0x00, 0xBF, 0xFF)),
- CNameToCol("DimGray", CRGBA(0x69, 0x69, 0x69)),
- CNameToCol("DodgerBlue", CRGBA(0x1E, 0x90, 0xFF)),
- CNameToCol("Feldspar", CRGBA(0xD1, 0x92, 0x75)),
- CNameToCol("FireBrick", CRGBA(0xB2, 0x22, 0x22)),
- CNameToCol("FloralWhite", CRGBA(0xFF, 0xFA, 0xF0)),
- CNameToCol("ForestGreen", CRGBA(0x22, 0x8B, 0x22)),
- CNameToCol("Fuchsia", CRGBA(0xFF, 0x00, 0xFF)),
- CNameToCol("Gainsboro", CRGBA(0xDC, 0xDC, 0xDC)),
- CNameToCol("GhostWhite", CRGBA(0xF8, 0xF8, 0xFF)),
- CNameToCol("Gold", CRGBA(0xFF, 0xD7, 0x00)),
- CNameToCol("GoldenRod", CRGBA(0xDA, 0xA5, 0x20)),
- CNameToCol("Gray", CRGBA(0x80, 0x80, 0x80)),
- CNameToCol("Green", CRGBA(0x00, 0x80, 0x00)),
- CNameToCol("GreenYellow", CRGBA(0xAD, 0xFF, 0x2F)),
- CNameToCol("HoneyDew", CRGBA(0xF0, 0xFF, 0xF0)),
- CNameToCol("HotPink", CRGBA(0xFF, 0x69, 0xB4)),
- CNameToCol("IndianRed ", CRGBA(0xCD, 0x5C, 0x5C)),
- CNameToCol("Indigo ", CRGBA(0x4B, 0x00, 0x82)),
- CNameToCol("Ivory", CRGBA(0xFF, 0xFF, 0xF0)),
- CNameToCol("Khaki", CRGBA(0xF0, 0xE6, 0x8C)),
- CNameToCol("Lavender", CRGBA(0xE6, 0xE6, 0xFA)),
- CNameToCol("LavenderBlush", CRGBA(0xFF, 0xF0, 0xF5)),
- CNameToCol("LawnGreen", CRGBA(0x7C, 0xFC, 0x00)),
- CNameToCol("LemonChiffon", CRGBA(0xFF, 0xFA, 0xCD)),
- CNameToCol("LightBlue", CRGBA(0xAD, 0xD8, 0xE6)),
- CNameToCol("LightCoral", CRGBA(0xF0, 0x80, 0x80)),
- CNameToCol("LightCyan", CRGBA(0xE0, 0xFF, 0xFF)),
- CNameToCol("LightGoldenRodYellow", CRGBA(0xFA, 0xFA, 0xD2)),
- CNameToCol("LightGrey", CRGBA(0xD3, 0xD3, 0xD3)),
- CNameToCol("LightGreen", CRGBA(0x90, 0xEE, 0x90)),
- CNameToCol("LightPink", CRGBA(0xFF, 0xB6, 0xC1)),
- CNameToCol("LightSalmon", CRGBA(0xFF, 0xA0, 0x7A)),
- CNameToCol("LightSeaGreen", CRGBA(0x20, 0xB2, 0xAA)),
- CNameToCol("LightSkyBlue", CRGBA(0x87, 0xCE, 0xFA)),
- CNameToCol("LightSlateBlue", CRGBA(0x84, 0x70, 0xFF)),
- CNameToCol("LightSlateGray", CRGBA(0x77, 0x88, 0x99)),
- CNameToCol("LightSteelBlue", CRGBA(0xB0, 0xC4, 0xDE)),
- CNameToCol("LightYellow", CRGBA(0xFF, 0xFF, 0xE0)),
- CNameToCol("Lime", CRGBA(0x00, 0xFF, 0x00)),
- CNameToCol("LimeGreen", CRGBA(0x32, 0xCD, 0x32)),
- CNameToCol("Linen", CRGBA(0xFA, 0xF0, 0xE6)),
- CNameToCol("Magenta", CRGBA(0xFF, 0x00, 0xFF)),
- CNameToCol("Maroon", CRGBA(0x80, 0x00, 0x00)),
- CNameToCol("MediumAquaMarine", CRGBA(0x66, 0xCD, 0xAA)),
- CNameToCol("MediumBlue", CRGBA(0x00, 0x00, 0xCD)),
- CNameToCol("MediumOrchid", CRGBA(0xBA, 0x55, 0xD3)),
- CNameToCol("MediumPurple", CRGBA(0x93, 0x70, 0xD8)),
- CNameToCol("MediumSeaGreen", CRGBA(0x3C, 0xB3, 0x71)),
- CNameToCol("MediumSlateBlue", CRGBA(0x7B, 0x68, 0xEE)),
- CNameToCol("MediumSpringGreen", CRGBA(0x00, 0xFA, 0x9A)),
- CNameToCol("MediumTurquoise", CRGBA(0x48, 0xD1, 0xCC)),
- CNameToCol("MediumVioletRed", CRGBA(0xC7, 0x15, 0x85)),
- CNameToCol("MidnightBlue", CRGBA(0x19, 0x19, 0x70)),
- CNameToCol("MintCream", CRGBA(0xF5, 0xFF, 0xFA)),
- CNameToCol("MistyRose", CRGBA(0xFF, 0xE4, 0xE1)),
- CNameToCol("Moccasin", CRGBA(0xFF, 0xE4, 0xB5)),
- CNameToCol("NavajoWhite", CRGBA(0xFF, 0xDE, 0xAD)),
- CNameToCol("Navy", CRGBA(0x00, 0x00, 0x80)),
- CNameToCol("OldLace", CRGBA(0xFD, 0xF5, 0xE6)),
- CNameToCol("Olive", CRGBA(0x80, 0x80, 0x00)),
- CNameToCol("OliveDrab", CRGBA(0x6B, 0x8E, 0x23)),
- CNameToCol("Orange", CRGBA(0xFF, 0xA5, 0x00)),
- CNameToCol("OrangeRed", CRGBA(0xFF, 0x45, 0x00)),
- CNameToCol("Orchid", CRGBA(0xDA, 0x70, 0xD6)),
- CNameToCol("PaleGoldenRod", CRGBA(0xEE, 0xE8, 0xAA)),
- CNameToCol("PaleGreen", CRGBA(0x98, 0xFB, 0x98)),
- CNameToCol("PaleTurquoise", CRGBA(0xAF, 0xEE, 0xEE)),
- CNameToCol("PaleVioletRed", CRGBA(0xD8, 0x70, 0x93)),
- CNameToCol("PapayaWhip", CRGBA(0xFF, 0xEF, 0xD5)),
- CNameToCol("PeachPuff", CRGBA(0xFF, 0xDA, 0xB9)),
- CNameToCol("Peru", CRGBA(0xCD, 0x85, 0x3F)),
- CNameToCol("Pink", CRGBA(0xFF, 0xC0, 0xCB)),
- CNameToCol("Plum", CRGBA(0xDD, 0xA0, 0xDD)),
- CNameToCol("PowderBlue", CRGBA(0xB0, 0xE0, 0xE6)),
- CNameToCol("Purple", CRGBA(0x80, 0x00, 0x80)),
- CNameToCol("Red", CRGBA(0xFF, 0x00, 0x00)),
- CNameToCol("RosyBrown", CRGBA(0xBC, 0x8F, 0x8F)),
- CNameToCol("RoyalBlue", CRGBA(0x41, 0x69, 0xE1)),
- CNameToCol("SaddleBrown", CRGBA(0x8B, 0x45, 0x13)),
- CNameToCol("Salmon", CRGBA(0xFA, 0x80, 0x72)),
- CNameToCol("SandyBrown", CRGBA(0xF4, 0xA4, 0x60)),
- CNameToCol("SeaGreen", CRGBA(0x2E, 0x8B, 0x57)),
- CNameToCol("SeaShell", CRGBA(0xFF, 0xF5, 0xEE)),
- CNameToCol("Sienna", CRGBA(0xA0, 0x52, 0x2D)),
- CNameToCol("Silver", CRGBA(0xC0, 0xC0, 0xC0)),
- CNameToCol("SkyBlue", CRGBA(0x87, 0xCE, 0xEB)),
- CNameToCol("SlateBlue", CRGBA(0x6A, 0x5A, 0xCD)),
- CNameToCol("SlateGray", CRGBA(0x70, 0x80, 0x90)),
- CNameToCol("Snow", CRGBA(0xFF, 0xFA, 0xFA)),
- CNameToCol("SpringGreen", CRGBA(0x00, 0xFF, 0x7F)),
- CNameToCol("SteelBlue", CRGBA(0x46, 0x82, 0xB4)),
- CNameToCol("Tan", CRGBA(0xD2, 0xB4, 0x8C)),
- CNameToCol("Teal", CRGBA(0x00, 0x80, 0x80)),
- CNameToCol("Thistle", CRGBA(0xD8, 0xBF, 0xD8)),
- CNameToCol("Tomato", CRGBA(0xFF, 0x63, 0x47)),
- CNameToCol("Turquoise", CRGBA(0x40, 0xE0, 0xD0)),
- CNameToCol("Violet", CRGBA(0xEE, 0x82, 0xEE)),
- CNameToCol("VioletRed", CRGBA(0xD0, 0x20, 0x90)),
- CNameToCol("Wheat", CRGBA(0xF5, 0xDE, 0xB3)),
- CNameToCol("White", CRGBA(0xFF, 0xFF, 0xFF)),
- CNameToCol("WhiteSmoke", CRGBA(0xF5, 0xF5, 0xF5)),
- CNameToCol("Yellow", CRGBA(0xFF, 0xFF, 0x00)),
- CNameToCol("YellowGreen", CRGBA(0x9A, 0xCD, 0x32))
- };
-
- // scan a color from a HTML form (#rrggbb format)
- bool scanHTMLColor(const char *src, CRGBA &dest)
- {
- if (!src || *src == '\0') return false;
- if (*src == '#')
- {
- ++src;
- if (strlen(src) == 3 || strlen(src) == 4)
- {
- bool hasAlpha = (strlen(src) == 4);
- // check RGB for valid hex
- if (isHexa(src[0]) && isHexa(src[1]) && isHexa(src[2]))
- {
- // check optional A for valid hex
- if (hasAlpha && !isHexa(src[3])) return false;
-
- dest.R = convertHexa(src[0]);
- dest.G = convertHexa(src[1]);
- dest.B = convertHexa(src[2]);
-
- dest.R = dest.R << 4 | dest.R;
- dest.G = dest.G << 4 | dest.G;
- dest.B = dest.B << 4 | dest.B;
-
- if (hasAlpha)
- {
- dest.A = convertHexa(src[3]);
- dest.A = dest.A << 4 | dest.A;
- }
- else
- dest.A = 255;
-
- return true;
- }
-
- return false;
- }
-
- CRGBA result;
- src = scanColorComponent(src, result.R); if (!src) return false;
- src = scanColorComponent(src, result.G); if (!src) return false;
- src = scanColorComponent(src, result.B); if (!src) return false;
- src = scanColorComponent(src, result.A);
- if (!src)
- {
- // Alpha is optional
- result.A = 255;
- }
- dest = result;
- return true;
- }
-
- if (strnicmp(src, "rgb(", 4) == 0 || strnicmp(src, "rgba(", 5) == 0)
- {
- src += 4;
- if (*src == '(') src++;
-
- vector parts;
- NLMISC::splitString(src, ",", parts);
- if (parts.size() >= 3)
- {
- CRGBA result;
- sint tmpv;
- float tmpf;
-
- // R
- if (getPercentage(tmpv, tmpf, parts[0].c_str())) tmpv = 255 * tmpf;
- clamp(tmpv, 0, 255);
- result.R = tmpv;
-
- // G
- if (getPercentage(tmpv, tmpf, parts[1].c_str())) tmpv = 255 * tmpf;
- clamp(tmpv, 0, 255);
- result.G = tmpv;
-
- // B
- if (getPercentage(tmpv, tmpf, parts[2].c_str())) tmpv = 255 * tmpf;
- clamp(tmpv, 0, 255);
- result.B = tmpv;
-
- // A
- if (parts.size() == 4)
- {
- if (!fromString(parts[3], tmpf)) return false;
- if (parts[3].find_first_of("%") != std::string::npos)
- tmpf /= 100;
-
- tmpv = 255 * tmpf;
- clamp(tmpv, 0, 255);
- result.A = tmpv;
- }
- else
- result.A = 255;
-
- dest = result;
- return true;
- }
-
- return false;
- }
-
- if (strnicmp(src, "hsl(", 4) == 0 || strnicmp(src, "hsla(", 5) == 0)
- {
- src += 4;
- if (*src == '(') src++;
-
- vector parts;
- NLMISC::splitString(src, ",", parts);
- if (parts.size() >= 3)
- {
- sint tmpv;
- float h, s, l;
- // hue
- if (!fromString(parts[0], tmpv)) return false;
- tmpv = ((tmpv % 360) + 360) % 360;
- h = (float) tmpv / 360.0f;
-
- // saturation
- if (!getPercentage(tmpv, s, parts[1].c_str())) return false;
- clamp(s, 0.0f, 1.0f);
-
- // lightness
- if (!getPercentage(tmpv, l, parts[2].c_str())) return false;
- clamp(l, 0.0f, 1.0f);
-
- CRGBA result;
- hslToRgb(h, s, l, result);
-
- // A
- if (parts.size() == 4)
- {
- float tmpf;
- if (!fromString(parts[3], tmpf)) return false;
- if (parts[3].find_first_of("%") != std::string::npos)
- tmpf /= 100;
- clamp(tmpf, 0.0f, 1.0f);
- result.A = 255 * tmpf;
- }
-
- dest = result;
- return true;
- }
-
- return false;
- }
-
- {
- // slow but should suffice for now
- for(uint k = 0; k < sizeofarray(htmlColorNameToRGBA); ++k)
- {
- if (nlstricmp(src, htmlColorNameToRGBA[k].Name) == 0)
- {
- dest = htmlColorNameToRGBA[k].Color;
- return true;
- }
- }
- return false;
- }
- }
-
// ***************************************************************************
void CGroupHTML::beginElement (uint element_number, const std::vector &present, const std::vector &value)
@@ -1546,10 +1164,10 @@ namespace NLGUI
{
case HTML_HTML:
if (present[MY_HTML_HTML_STYLE] && value[MY_HTML_HTML_STYLE])
- getStyleParams(value[MY_HTML_HTML_STYLE], _StyleDefault, _StyleDefault);
+ _Style.applyRootStyle(value[MY_HTML_HTML_STYLE]);
- _Style = _StyleDefault;
- setBackgroundColor(_Style.BackgroundColor);
+ _Style.Current = _Style.Root;
+ setBackgroundColor(_Style.Current.BackgroundColor);
break;
case HTML_HEAD:
_ReadingHeadTag = !_IgnoreHeadTag;
@@ -1607,17 +1225,17 @@ namespace NLGUI
{
registerAnchorName(MY_HTML_A);
- pushStyle();
- _Style.TextColor = LinkColor;
- _Style.Underlined = true;
- _Style.GlobalColor = LinkColorGlobalColor;
- _Style.BackgroundColor.A = 0;
- _Style.BackgroundColorOver.A = 0;
- _Style.Width = -1;
- _Style.Height = -1;
+ _Style.pushStyle();
+ _Style.Current.TextColor = LinkColor;
+ _Style.Current.Underlined = true;
+ _Style.Current.GlobalColor = LinkColorGlobalColor;
+ _Style.Current.BackgroundColor.A = 0;
+ _Style.Current.BackgroundColorOver.A = 0;
+ _Style.Current.Width = -1;
+ _Style.Current.Height = -1;
if (present[HTML_A_STYLE] && value[HTML_A_STYLE])
- getStyleParams(value[HTML_A_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_A_STYLE]);
_A.push_back(true);
_Link.push_back ("");
@@ -1656,7 +1274,7 @@ namespace NLGUI
{
_BlockLevelElement.push_back(true);
registerAnchorName(MY_HTML_DIV);
- pushStyle();
+ _Style.pushStyle();
if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME])
_DivName = value[MY_HTML_DIV_NAME];
@@ -1670,7 +1288,7 @@ namespace NLGUI
style = value[MY_HTML_DIV_STYLE];
if (!style.empty())
- getStyleParams(style, _Style, _StyleParams.back());
+ _Style.applyStyle(style);
// use generic template system
if (_TrustedDomain && !instClass.empty() && instClass == "ryzom-ui-grouptemplate")
@@ -1746,19 +1364,19 @@ namespace NLGUI
break;
case HTML_FONT:
{
- pushStyle();
+ _Style.pushStyle();
if (present[HTML_FONT_COLOR] && value[HTML_FONT_COLOR])
{
CRGBA color;
if (scanHTMLColor(value[HTML_FONT_COLOR], color))
- _Style.TextColor = color;
+ _Style.Current.TextColor = color;
}
if (present[HTML_FONT_SIZE] && value[HTML_FONT_SIZE])
{
uint fontsize;
fromString(value[HTML_FONT_SIZE], fontsize);
- _Style.FontSize = fontsize;
+ _Style.Current.FontSize = fontsize;
}
}
break;
@@ -1774,20 +1392,20 @@ namespace NLGUI
break;
case HTML_BODY:
{
- pushStyle();
+ _Style.pushStyle();
string style;
if (present[HTML_BODY_STYLE] && value[HTML_BODY_STYLE])
style = value[HTML_BODY_STYLE];
if (!style.empty())
- getStyleParams(style, _Style, _StyleParams.back());
+ _Style.applyStyle(style);
- CRGBA bgColor = _Style.BackgroundColor;
+ CRGBA bgColor = _Style.Current.BackgroundColor;
if (present[HTML_BODY_BGCOLOR] && value[HTML_BODY_BGCOLOR])
scanHTMLColor(value[HTML_BODY_BGCOLOR], bgColor);
- if (bgColor != _Style.BackgroundColor)
+ if (bgColor != _Style.Current.BackgroundColor)
setBackgroundColor(bgColor);
if (!style.empty())
@@ -1837,72 +1455,72 @@ namespace NLGUI
{
registerAnchorName(MY_HTML_H1);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H1FontSize;
- _Style.TextColor = H1Color;
- _Style.GlobalColor = H1ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H1FontSize;
+ _Style.Current.TextColor = H1Color;
+ _Style.Current.GlobalColor = H1ColorGlobalColor;
if (present[MY_HTML_H1_STYLE] && value[MY_HTML_H1_STYLE])
- getStyleParams(value[MY_HTML_H1_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H1_STYLE]);
}
break;
case HTML_H2:
{
registerAnchorName(MY_HTML_H2);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H2FontSize;
- _Style.TextColor = H2Color;
- _Style.GlobalColor = H2ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H2FontSize;
+ _Style.Current.TextColor = H2Color;
+ _Style.Current.GlobalColor = H2ColorGlobalColor;
if (present[MY_HTML_H2_STYLE] && value[MY_HTML_H2_STYLE])
- getStyleParams(value[MY_HTML_H2_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H2_STYLE]);
}
break;
case HTML_H3:
{
registerAnchorName(MY_HTML_H3);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H3FontSize;
- _Style.TextColor = H3Color;
- _Style.GlobalColor = H3ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H3FontSize;
+ _Style.Current.TextColor = H3Color;
+ _Style.Current.GlobalColor = H3ColorGlobalColor;
if (present[MY_HTML_H3_STYLE] && value[MY_HTML_H3_STYLE])
- getStyleParams(value[MY_HTML_H3_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H3_STYLE]);
}
break;
case HTML_H4:
{
registerAnchorName(MY_HTML_H4);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H4FontSize;
- _Style.TextColor = H4Color;
- _Style.GlobalColor = H4ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H4FontSize;
+ _Style.Current.TextColor = H4Color;
+ _Style.Current.GlobalColor = H4ColorGlobalColor;
if (present[MY_HTML_H4_STYLE] && value[MY_HTML_H4_STYLE])
- getStyleParams(value[MY_HTML_H4_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H4_STYLE]);
}
break;
case HTML_H5:
{
registerAnchorName(MY_HTML_H5);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H5FontSize;
- _Style.TextColor = H5Color;
- _Style.GlobalColor = H5ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H5FontSize;
+ _Style.Current.TextColor = H5Color;
+ _Style.Current.GlobalColor = H5ColorGlobalColor;
if (present[MY_HTML_H5_STYLE] && value[MY_HTML_H5_STYLE])
- getStyleParams(value[MY_HTML_H5_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H5_STYLE]);
}
break;
case HTML_H6:
{
registerAnchorName(MY_HTML_H6);
newParagraph(PBeginSpace);
- pushStyle();
- _Style.FontSize = H6FontSize;
- _Style.TextColor = H6Color;
- _Style.GlobalColor = H6ColorGlobalColor;
+ _Style.pushStyle();
+ _Style.Current.FontSize = H6FontSize;
+ _Style.Current.TextColor = H6Color;
+ _Style.Current.GlobalColor = H6ColorGlobalColor;
if (present[MY_HTML_H6_STYLE] && value[MY_HTML_H6_STYLE])
- getStyleParams(value[MY_HTML_H6_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_H6_STYLE]);
}
break;
case HTML_IMG:
@@ -1912,24 +1530,24 @@ namespace NLGUI
{
float tmpf;
std::string id;
- CStyleParams style;
- style.FontSize = _Style.FontSize;
+
+ _Style.pushStyle();
if (present[MY_HTML_IMG_ID] && value[MY_HTML_IMG_ID])
id = value[MY_HTML_IMG_ID];
if (present[MY_HTML_IMG_WIDTH] && value[MY_HTML_IMG_WIDTH])
- getPercentage(style.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
+ getPercentage(_Style.Current.Width, tmpf, value[MY_HTML_IMG_WIDTH]);
if (present[MY_HTML_IMG_HEIGHT] && value[MY_HTML_IMG_HEIGHT])
- getPercentage(style.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
+ getPercentage(_Style.Current.Height, tmpf, value[MY_HTML_IMG_HEIGHT]);
// Get the global color name
if (present[MY_HTML_IMG_GLOBAL_COLOR])
- style.GlobalColor = true;
+ _Style.Current.GlobalColor = true;
// width, height from inline css
if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE])
- getStyleParams(value[MY_HTML_IMG_STYLE], style, _Style);
+ _Style.applyStyle(value[MY_HTML_IMG_STYLE]);
// Tooltip
const char *tooltip = NULL;
@@ -1952,13 +1570,13 @@ namespace NLGUI
{
string params = "name=" + getId() + "|url=" + getLink ();
addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
- overSrc, "browse", params.c_str(), tooltip, style);
+ overSrc, "browse", params.c_str(), tooltip, _Style.Current);
}
else
if (tooltip || !overSrc.empty())
{
addButton(CCtrlButton::PushButton, id, value[MY_HTML_IMG_SRC], value[MY_HTML_IMG_SRC],
- overSrc, "", "", tooltip, style);
+ overSrc, "", "", tooltip, _Style.Current);
}
else
{
@@ -1979,8 +1597,10 @@ namespace NLGUI
reloadImg = true;
}
- addImage(id, value[MY_HTML_IMG_SRC], reloadImg, style);
+ addImage(id, value[MY_HTML_IMG_SRC], reloadImg, _Style.Current);
}
+
+ _Style.popStyle();
}
}
break;
@@ -2010,22 +1630,22 @@ namespace NLGUI
if (present[MY_HTML_INPUT_TYPE] && value[MY_HTML_INPUT_TYPE])
{
// by default not inherited, font family defaults to system font
- pushStyle();
- _Style.TextColor = TextColor;
- _Style.FontSize = TextFontSize;
- _Style.FontWeight = FONT_WEIGHT_NORMAL;
- _Style.FontOblique = false;
- _Style.TextShadow = STextShadow(true);
- _Style.Width = -1;
- _Style.Height = -1;
+ _Style.pushStyle();
+ _Style.Current.TextColor = TextColor;
+ _Style.Current.FontSize = TextFontSize;
+ _Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
+ _Style.Current.FontOblique = false;
+ _Style.Current.TextShadow = CStyleParams::STextShadow(true);
+ _Style.Current.Width = -1;
+ _Style.Current.Height = -1;
// by default background texture is transparent,
// using alpha value to decide if to change it to 'blank.tga' for coloring
- _Style.BackgroundColor.A = 0;
- _Style.BackgroundColorOver.A = 0;
+ _Style.Current.BackgroundColor.A = 0;
+ _Style.Current.BackgroundColorOver.A = 0;
// Global color flag
if (present[MY_HTML_INPUT_GLOBAL_COLOR])
- _Style.GlobalColor = true;
+ _Style.Current.GlobalColor = true;
// Tooltip
const char *tooltip = NULL;
@@ -2033,7 +1653,7 @@ namespace NLGUI
tooltip = value[MY_HTML_INPUT_ALT];
if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
- getStyleParams(value[MY_HTML_INPUT_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_INPUT_STYLE]);
string type = toLower(value[MY_HTML_INPUT_TYPE]);
if (type == "image")
@@ -2053,7 +1673,7 @@ namespace NLGUI
// Add the ctrl button
addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
- "html_submit_form", param.c_str(), tooltip, _Style);
+ "html_submit_form", param.c_str(), tooltip, _Style.Current);
}
if (type == "button" || type == "submit")
{
@@ -2108,7 +1728,7 @@ namespace NLGUI
if (!ctrlButton) ctrlButton = dynamic_cast(buttonGroup->getCtrl("b"));
if (ctrlButton)
{
- ctrlButton->setModulateGlobalColorAll (_Style.GlobalColor);
+ ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
// Translate the tooltip
if (tooltip)
@@ -2125,7 +1745,7 @@ namespace NLGUI
ctrlButton->setText(ucstring::makeFromUtf8(text));
- setTextButtonStyle(ctrlButton, _Style);
+ setTextButtonStyle(ctrlButton, _Style.Current);
}
getParagraph()->addChild (buttonGroup);
paragraphChange ();
@@ -2193,7 +1813,7 @@ namespace NLGUI
checked = (present[MY_HTML_INPUT_CHECKED] && value[MY_HTML_INPUT_CHECKED]);
// Add the ctrl button
- CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style);
+ CCtrlButton *checkbox = addButton (btnType, name, normal, pushed, over, "", "", tooltip, _Style.Current);
if (checkbox)
{
if (btnType == CCtrlButton::RadioButton)
@@ -2251,14 +1871,16 @@ namespace NLGUI
}
}
- popStyle();
+ _Style.popStyle();
}
}
break;
case HTML_SELECT:
if (!(_Forms.empty()))
{
- CStyleParams style;
+ _Style.pushStyle();
+ _Style.Current.Width = -1;
+ _Style.Current.Height = -1;
// A select box
string name;
@@ -2272,7 +1894,7 @@ namespace NLGUI
if (present[HTML_SELECT_MULTIPLE] && value[HTML_SELECT_MULTIPLE])
multiple = true;
if (present[HTML_SELECT_STYLE] && value[HTML_SELECT_STYLE])
- getStyleParams(value[HTML_SELECT_STYLE], style, _Style);
+ _Style.applyStyle(value[HTML_SELECT_STYLE]);
CGroupHTML::CForm::CEntry entry;
entry.Name = name;
@@ -2286,14 +1908,14 @@ namespace NLGUI
if (size < 1)
size = 4;
- if (style.Width > -1)
- sb->setMinW(style.Width);
+ if (_Style.Current.Width > -1)
+ sb->setMinW(_Style.Current.Width);
- if (style.Height > -1)
- sb->setMinH(style.Height);
+ if (_Style.Current.Height > -1)
+ sb->setMinH(_Style.Current.Height);
sb->setMaxVisibleLine(size);
- sb->setFontSize(style.FontSize);
+ sb->setFontSize(_Style.Current.FontSize);
}
entry.SelectBox = sb;
@@ -2308,10 +1930,12 @@ namespace NLGUI
// create view text
cb->updateCoords();
if (cb->getViewText())
- setTextStyle(cb->getViewText(), style);
+ setTextStyle(cb->getViewText(), _Style.Current);
}
}
_Forms.back().Entries.push_back (entry);
+
+ _Style.popStyle();
}
break;
case HTML_OPTION:
@@ -2354,9 +1978,9 @@ namespace NLGUI
if (present[HTML_LI_VALUE] && value[HTML_LI_VALUE])
fromString(value[HTML_LI_VALUE], _UL.back().Value);
- pushStyle();
+ _Style.pushStyle();
if (present[HTML_LI_STYLE] && value[HTML_LI_STYLE])
- getStyleParams(value[HTML_LI_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_LI_STYLE]);
ucstring str;
str.fromUtf8(_UL.back().getListMarkerText());
@@ -2377,18 +2001,18 @@ namespace NLGUI
case HTML_P:
{
newParagraph(PBeginSpace);
- pushStyle();
+ _Style.pushStyle();
if (present[MY_HTML_P_STYLE] && value[MY_HTML_P_STYLE])
- getStyleParams(value[MY_HTML_P_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_P_STYLE]);
}
break;
case HTML_PRE:
{
- pushStyle();
- _Style.FontFamily = "monospace";
+ _Style.pushStyle();
+ _Style.Current.FontFamily = "monospace";
if (present[HTML_PRE_STYLE] && value[HTML_PRE_STYLE])
- getStyleParams(value[HTML_PRE_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_PRE_STYLE]);
_PRE.push_back(true);
@@ -2396,7 +2020,7 @@ namespace NLGUI
break;
case HTML_TABLE:
{
- pushStyle();
+ _Style.pushStyle();
registerAnchorName(MY_HTML_TABLE);
// Get cells parameters
@@ -2416,7 +2040,7 @@ namespace NLGUI
if (present[MY_HTML_TABLE_CELLPADDING] && value[MY_HTML_TABLE_CELLPADDING])
fromString(value[MY_HTML_TABLE_CELLPADDING], table->CellPadding);
if (present[MY_HTML_TABLE_STYLE] && value[MY_HTML_TABLE_STYLE])
- getStyleParams(value[MY_HTML_TABLE_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_TABLE_STYLE]);
table->setMarginLeft(getIndent());
addHtmlGroup (table, 0);
@@ -2436,17 +2060,17 @@ namespace NLGUI
// Get cells parameters
getCellsParameters (MY_HTML_TD, true);
- pushStyle();
+ _Style.pushStyle();
if (element_number == HTML_TH)
{
- _Style.FontWeight = FONT_WEIGHT_BOLD;
+ _Style.Current.FontWeight = FONT_WEIGHT_BOLD;
// center if not specified otherwise. TD/TH present/value arrays have same indices
if (!(present[MY_HTML_TD_ALIGN] && value[MY_HTML_TD_ALIGN]))
_CellParams.back().Align = CGroupCell::Center;
}
if (present[MY_HTML_TD_STYLE] && value[MY_HTML_TD_STYLE])
- getStyleParams(value[MY_HTML_TD_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_TD_STYLE]);
CGroupTable *table = getTable();
if (table)
@@ -2527,21 +2151,21 @@ namespace NLGUI
}
break;
case HTML_TEXTAREA:
- pushStyle();
+ _Style.pushStyle();
_PRE.push_back(true);
// not inherited by default, font family defaults to system font
- _Style.TextColor = TextColor;
- _Style.FontWeight = FONT_WEIGHT_NORMAL;
- _Style.FontOblique = false;
- _Style.FontSize = TextFontSize;
- _Style.TextShadow = STextShadow(true);
- _Style.Width = -1;
- _Style.Height = -1;
- _Style.BackgroundColor.A = 0;
+ _Style.Current.TextColor = TextColor;
+ _Style.Current.FontWeight = FONT_WEIGHT_NORMAL;
+ _Style.Current.FontOblique = false;
+ _Style.Current.FontSize = TextFontSize;
+ _Style.Current.TextShadow = CStyleParams::STextShadow(true);
+ _Style.Current.Width = -1;
+ _Style.Current.Height = -1;
+ _Style.Current.BackgroundColor.A = 0;
if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
- getStyleParams(value[MY_HTML_TEXTAREA_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_TEXTAREA_STYLE]);
// Got one form ?
if (!(_Forms.empty()))
@@ -2595,9 +2219,9 @@ namespace NLGUI
if (!_TR.empty())
_TR.back() = true;
- pushStyle();
+ _Style.pushStyle();
if (present[MY_HTML_TR_STYLE] && value[MY_HTML_TR_STYLE])
- getStyleParams(value[MY_HTML_TR_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_TR_STYLE]);
}
break;
case HTML_UL:
@@ -2612,9 +2236,9 @@ namespace NLGUI
_Indent.push_back(getIndent() + ULIndent);
endParagraph();
- pushStyle();
+ _Style.pushStyle();
if (present[HTML_UL_STYLE] && value[HTML_UL_STYLE])
- getStyleParams(value[HTML_UL_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_UL_STYLE]);
break;
case HTML_OBJECT:
_ObjectType.clear();
@@ -2634,40 +2258,40 @@ namespace NLGUI
break;
case HTML_SPAN:
{
- pushStyle();
+ _Style.pushStyle();
if (present[MY_HTML_SPAN_STYLE] && value[MY_HTML_SPAN_STYLE])
- getStyleParams(value[MY_HTML_SPAN_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[MY_HTML_SPAN_STYLE]);
}
break;
case HTML_DEL:
{
- pushStyle();
- _Style.StrikeThrough = true;
+ _Style.pushStyle();
+ _Style.Current.StrikeThrough = true;
}
break;
case HTML_U:
{
- pushStyle();
- _Style.Underlined = true;
+ _Style.pushStyle();
+ _Style.Current.Underlined = true;
}
break;
case HTML_EM:
{
- pushStyle();
- _Style.FontOblique = true;
+ _Style.pushStyle();
+ _Style.Current.FontOblique = true;
}
break;
case HTML_STRONG:
{
- pushStyle();
- _Style.FontWeight = FONT_WEIGHT_BOLD;
+ _Style.pushStyle();
+ _Style.Current.FontWeight = FONT_WEIGHT_BOLD;
}
break;
case HTML_SMALL:
{
- pushStyle();
- _Style.FontSize = getFontSizeSmaller();
+ _Style.pushStyle();
+ _Style.Current.FontSize = _Style.getFontSizeSmaller();
}
break;
case HTML_STYLE:
@@ -2679,9 +2303,9 @@ namespace NLGUI
_DL.push_back(HTMLDListElement());
_LI = _DL.size() > 1 || !_UL.empty();
endParagraph();
- pushStyle();
+ _Style.pushStyle();
if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
- getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_GEN_STYLE]);
}
break;
case HTML_DT:
@@ -2692,19 +2316,19 @@ namespace NLGUI
{
_DL.back().DD = false;
popIfNotEmpty(_Indent);
- popStyle();
+ _Style.popStyle();
}
// close if still open
if (_DL.back().DT)
- popStyle();
+ _Style.popStyle();
_DL.back().DT = true;
- pushStyle();
- _Style.FontWeight = FONT_WEIGHT_BOLD;
+ _Style.pushStyle();
+ _Style.Current.FontWeight = FONT_WEIGHT_BOLD;
if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
- getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_GEN_STYLE]);
if (!_LI)
{
@@ -2724,22 +2348,22 @@ namespace NLGUI
if (_DL.back().DT)
{
_DL.back().DT = false;
- popStyle();
+ _Style.popStyle();
}
if (_DL.back().DD)
{
_DL.back().DD = false;
- popStyle();
+ _Style.popStyle();
popIfNotEmpty(_Indent);
}
_DL.back().DD = true;
_Indent.push_back(getIndent() + ULIndent);
- pushStyle();
+ _Style.pushStyle();
if (present[HTML_GEN_STYLE] && value[HTML_GEN_STYLE])
- getStyleParams(value[HTML_GEN_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_GEN_STYLE]);
if (!_LI)
{
@@ -2754,7 +2378,7 @@ namespace NLGUI
break;
case HTML_OL:
{
- pushStyle();
+ _Style.pushStyle();
sint32 start = 1;
std::string type("1");
@@ -2763,7 +2387,7 @@ namespace NLGUI
if (present[HTML_OL_TYPE] && value[HTML_OL_TYPE])
type = value[HTML_OL_TYPE];
if (present[HTML_OL_STYLE] && value[HTML_OL_STYLE])
- getStyleParams(value[HTML_OL_STYLE], _Style, _StyleParams.back());
+ _Style.applyStyle(value[HTML_OL_STYLE]);
_UL.push_back(HTMLOListElement(start, type));
// if LI is already present
@@ -2779,34 +2403,35 @@ namespace NLGUI
CInterfaceGroup *sep = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_hr", "", NULL, 0);
if (sep)
{
- CStyleParams style;
- style.FontSize = _Style.FontSize;
- style.TextColor = CRGBA(120, 120, 120, 255);
- style.Height = 0;
- style.Width = 0;
+ _Style.pushStyle();
+ _Style.Current.TextColor = CRGBA(120, 120, 120, 255);
+ _Style.Current.Height = -1;
+ _Style.Current.Width = -1;
if (present[HTML_HR_STYLE] && value[HTML_HR_STYLE])
- getStyleParams(value[HTML_HR_STYLE], style, _Style);
+ _Style.applyStyle(value[HTML_HR_STYLE]);
CViewBitmap *bitmap = dynamic_cast(sep->getView("hr"));
if (bitmap)
{
- bitmap->setColor(style.TextColor);
- if (style.Width > 0)
+ bitmap->setColor(_Style.Current.TextColor);
+ if (_Style.Current.Width > 0)
{
- clamp(style.Width, 1, 32000);
- bitmap->setW(style.Width);
+ clamp(_Style.Current.Width, 1, 32000);
+ bitmap->setW(_Style.Current.Width);
bitmap->setSizeRef(CInterfaceElement::none);
}
- if (style.Height > 0)
+ if (_Style.Current.Height > 0)
{
- clamp(style.Height, 1, 1000);
- bitmap->setH(style.Height);
+ clamp(_Style.Current.Height, 1, 1000);
+ bitmap->setH(_Style.Current.Height);
}
}
getParagraph()->addChild(sep);
endParagraph();
+
+ _Style.popStyle();
}
}
break;
@@ -2827,13 +2452,13 @@ namespace NLGUI
_ReadingHeadTag = false;
break;
case HTML_BODY:
- popStyle();
+ _Style.popStyle();
break;
case HTML_FONT:
- popStyle();
+ _Style.popStyle();
break;
case HTML_A:
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_A);
popIfNotEmpty (_Link);
popIfNotEmpty (_LinkTitle);
@@ -2845,19 +2470,19 @@ namespace NLGUI
case HTML_H4:
case HTML_H5:
case HTML_H6:
- popStyle();
+ _Style.popStyle();
endParagraph();
break;
case HTML_P:
- popStyle();
+ _Style.popStyle();
endParagraph();
break;
case HTML_PRE:
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_PRE);
break;
case HTML_DIV:
- popStyle();
+ _Style.popStyle();
if (isBlockLevelElement())
{
endParagraph();
@@ -2868,7 +2493,7 @@ namespace NLGUI
break;
case HTML_TABLE:
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_CellParams);
popIfNotEmpty (_TR);
popIfNotEmpty (_Cells);
@@ -2880,13 +2505,13 @@ namespace NLGUI
case HTML_TH:
// no break;
case HTML_TD:
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_CellParams);
if (!_Cells.empty())
_Cells.back() = NULL;
break;
case HTML_TR:
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_CellParams);
break;
case HTML_TEXTAREA:
@@ -2905,7 +2530,7 @@ namespace NLGUI
}
}
- popStyle();
+ _Style.popStyle();
popIfNotEmpty (_PRE);
}
break;
@@ -3013,14 +2638,14 @@ namespace NLGUI
if (!_UL.empty())
{
endParagraph();
- popStyle();
+ _Style.popStyle();
popIfNotEmpty(_UL);
popIfNotEmpty(_Indent);
}
break;
case HTML_LI:
{
- popStyle();
+ _Style.popStyle();
}
break;
case HTML_DL:
@@ -3031,25 +2656,25 @@ namespace NLGUI
// unclosed DT
if (_DL.back().DT)
{
- popStyle();
+ _Style.popStyle();
}
// unclosed DD
if (_DL.back().DD)
{
popIfNotEmpty(_Indent);
- popStyle();
+ _Style.popStyle();
}
popIfNotEmpty (_DL);
- popStyle();
+ _Style.popStyle();
}
break;
case HTML_DT:
if (!_DL.empty())
{
if (_DL.back().DT)
- popStyle();
+ _Style.popStyle();
_DL.back().DT = false;
}
break;
@@ -3061,27 +2686,27 @@ namespace NLGUI
{
_DL.back().DD = false;
popIfNotEmpty(_Indent);
- popStyle();
+ _Style.popStyle();
}
}
break;
case HTML_SPAN:
- popStyle();
+ _Style.popStyle();
break;
case HTML_DEL:
- popStyle();
+ _Style.popStyle();
break;
case HTML_U:
- popStyle();
+ _Style.popStyle();
break;
case HTML_EM:
- popStyle();
+ _Style.popStyle();
break;
case HTML_STRONG:
- popStyle();
+ _Style.popStyle();
break;
case HTML_SMALL:
- popStyle();
+ _Style.popStyle();
break;
case HTML_STYLE:
case HTML_SCRIPT:
@@ -4508,34 +4133,36 @@ namespace NLGUI
paragraphChange ();
}
+ CStyleParams &style = _Style.Current;
+
// Text added ?
bool added = false;
- bool embolden = _Style.FontWeight >= FONT_WEIGHT_BOLD;
+ bool embolden = style.FontWeight >= FONT_WEIGHT_BOLD;
// Number of child in this paragraph
if (_CurrentViewLink)
{
bool skipLine = !_CurrentViewLink->getText().empty() && *(_CurrentViewLink->getText().rbegin()) == (ucchar) '\n';
- bool sameShadow = _Style.TextShadow.Enabled && _CurrentViewLink->getShadow();
- if (sameShadow && _Style.TextShadow.Enabled)
+ bool sameShadow = style.TextShadow.Enabled && _CurrentViewLink->getShadow();
+ if (sameShadow && style.TextShadow.Enabled)
{
sint sx, sy;
_CurrentViewLink->getShadowOffset(sx, sy);
- sameShadow = (_Style.TextShadow.Color == _CurrentViewLink->getShadowColor());
- sameShadow = sameShadow && (_Style.TextShadow.Outline == _CurrentViewLink->getShadowOutline());
- sameShadow = sameShadow && (_Style.TextShadow.X == sx) && (_Style.TextShadow.Y == sy);
+ sameShadow = (style.TextShadow.Color == _CurrentViewLink->getShadowColor());
+ sameShadow = sameShadow && (style.TextShadow.Outline == _CurrentViewLink->getShadowOutline());
+ sameShadow = sameShadow && (style.TextShadow.X == sx) && (style.TextShadow.Y == sy);
}
// Compatible with current parameters ?
if (!skipLine && sameShadow &&
- (_Style.TextColor == _CurrentViewLink->getColor()) &&
- (_Style.FontFamily == _CurrentViewLink->getFontName()) &&
- (_Style.FontSize == (uint)_CurrentViewLink->getFontSize()) &&
- (_Style.Underlined == _CurrentViewLink->getUnderlined()) &&
- (_Style.StrikeThrough == _CurrentViewLink->getStrikeThrough()) &&
+ (style.TextColor == _CurrentViewLink->getColor()) &&
+ (style.FontFamily == _CurrentViewLink->getFontName()) &&
+ (style.FontSize == (uint)_CurrentViewLink->getFontSize()) &&
+ (style.Underlined == _CurrentViewLink->getUnderlined()) &&
+ (style.StrikeThrough == _CurrentViewLink->getStrikeThrough()) &&
(embolden == _CurrentViewLink->getEmbolden()) &&
- (_Style.FontOblique == _CurrentViewLink->getOblique()) &&
+ (style.FontOblique == _CurrentViewLink->getOblique()) &&
(getLink() == _CurrentViewLink->Link) &&
- (_Style.GlobalColor == _CurrentViewLink->getModulateGlobalColor()))
+ (style.GlobalColor == _CurrentViewLink->getModulateGlobalColor()))
{
// Concat the text
_CurrentViewLink->setText(_CurrentViewLink->getText()+tmpStr);
@@ -4574,7 +4201,7 @@ namespace NLGUI
ctrlButton->setDefaultContextHelp(ucstring::makeFromUtf8(getLinkTitle()));
ctrlButton->setText(tmpStr);
- setTextButtonStyle(ctrlButton, _Style);
+ setTextButtonStyle(ctrlButton, style);
}
getParagraph()->addChild (buttonGroup);
paragraphChange ();
@@ -4597,10 +4224,10 @@ namespace NLGUI
}
}
newLink->setText(tmpStr);
- newLink->setMultiLineSpace((uint)((float)(_Style.FontSize)*LineSpaceFontFactor));
+ newLink->setMultiLineSpace((uint)((float)(style.FontSize)*LineSpaceFontFactor));
newLink->setMultiLine(true);
- newLink->setModulateGlobalColor(_Style.GlobalColor);
- setTextStyle(newLink, _Style);
+ newLink->setModulateGlobalColor(style.GlobalColor);
+ setTextStyle(newLink, style);
// newLink->setLineAtBottom (true);
registerAnchor(newLink);
@@ -4705,22 +4332,23 @@ namespace NLGUI
// No more text in this text view
_CurrentViewLink = NULL;
+ CStyleParams &style = _Style.Current;
{
// override cols/rows values from style
- if (_Style.Width > 0) cols = _Style.Width / _Style.FontSize;
- if (_Style.Height > 0) rows = _Style.Height / _Style.FontSize;
+ if (style.Width > 0) cols = style.Width / style.FontSize;
+ if (style.Height > 0) rows = style.Height / style.FontSize;
// Not added ?
std::vector > templateParams;
- templateParams.push_back (std::pair ("w", toString (cols*_Style.FontSize)));
+ templateParams.push_back (std::pair ("w", toString (cols*style.FontSize)));
templateParams.push_back (std::pair ("id", name));
templateParams.push_back (std::pair ("prompt", ""));
templateParams.push_back (std::pair ("multiline", multiLine?"true":"false"));
- templateParams.push_back (std::pair ("fontsize", toString (_Style.FontSize)));
- templateParams.push_back (std::pair ("color", _Style.TextColor.toString()));
- if (_Style.FontWeight >= FONT_WEIGHT_BOLD)
+ templateParams.push_back (std::pair ("fontsize", toString (style.FontSize)));
+ templateParams.push_back (std::pair ("color", style.TextColor.toString()));
+ if (style.FontWeight >= FONT_WEIGHT_BOLD)
templateParams.push_back (std::pair ("fontweight", "bold"));
- if (_Style.FontOblique)
+ if (style.FontOblique)
templateParams.push_back (std::pair ("fontstyle", "oblique"));
if (multiLine)
templateParams.push_back (std::pair ("multi_min_line", toString(rows)));
@@ -4729,13 +4357,13 @@ namespace NLGUI
templateParams.push_back (std::pair ("enter_recover_focus", "false"));
if (maxlength > 0)
templateParams.push_back (std::pair ("max_num_chars", toString(maxlength)));
- templateParams.push_back (std::pair ("shadow", toString(_Style.TextShadow.Enabled)));
- if (_Style.TextShadow.Enabled)
+ templateParams.push_back (std::pair ("shadow", toString(style.TextShadow.Enabled)));
+ if (style.TextShadow.Enabled)
{
- templateParams.push_back (std::pair ("shadow_x", toString(_Style.TextShadow.X)));
- templateParams.push_back (std::pair ("shadow_y", toString(_Style.TextShadow.Y)));
- templateParams.push_back (std::pair ("shadow_color", _Style.TextShadow.Color.toString()));
- templateParams.push_back (std::pair ("shadow_outline", toString(_Style.TextShadow.Outline)));
+ templateParams.push_back (std::pair ("shadow_x", toString(style.TextShadow.X)));
+ templateParams.push_back (std::pair ("shadow_y", toString(style.TextShadow.Y)));
+ templateParams.push_back (std::pair ("shadow_color", style.TextShadow.Color.toString()));
+ templateParams.push_back (std::pair ("shadow_outline", toString(style.TextShadow.Outline)));
}
CInterfaceGroup *textArea = CWidgetManager::getInstance()->getParser()->createGroupInstance (templateName.c_str(),
@@ -4749,13 +4377,13 @@ namespace NLGUI
if (eb)
{
eb->setInputString(decodeHTMLEntities(content));
- if (_Style.BackgroundColor.A > 0)
+ if (style.BackgroundColor.A > 0)
{
CViewBitmap *bg = dynamic_cast(eb->getView("bg"));
if (bg)
{
bg->setTexture("blank.tga");
- bg->setColor(_Style.BackgroundColor);
+ bg->setColor(style.BackgroundColor);
}
}
}
@@ -6411,423 +6039,11 @@ namespace NLGUI
// ***************************************************************************
void CGroupHTML::resetCssStyle()
{
- _StyleDefault = CStyleParams();
- _StyleDefault.TextColor = TextColor;
- _StyleDefault.FontSize = TextFontSize;
- _StyleDefault.BackgroundColor = BgColor;
-
- _Style = _StyleDefault;
- _StyleParams.clear();
- }
-
- // ***************************************************************************
- // CGroupHTML::CStyleParams style;
- // style.FontSize; // font-size: 10px;
- // style.TextColor; // color: #ABCDEF;
- // style.Underlined; // text-decoration: underline; text-decoration-line: underline;
- // style.StrikeThrough; // text-decoration: line-through; text-decoration-line: line-through;
- void CGroupHTML::getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams ¤t)
- {
- float tmpf;
- TStyle styles = parseStyle(styleString);
- TStyle::iterator it;
-
- // first pass: get font-size for 'em' sizes
- for (it=styles.begin(); it != styles.end(); ++it)
- {
- if (it->first == "font")
- {
- if (it->second == "inherit")
- {
- style.FontSize = current.FontSize;
- style.FontFamily = current.FontFamily;
- style.FontWeight = current.FontWeight;
- style.FontOblique = current.FontOblique;
- }
- }
- else
- if (it->first == "font-size")
- {
- if (it->second == "inherit")
- {
- style.FontSize = current.FontSize;
- }
- else
- {
- std::string unit;
- if (getCssLength(tmpf, unit, it->second.c_str()))
- {
- if (unit == "rem")
- style.FontSize = _StyleDefault.FontSize * tmpf;
- else if (unit == "em")
- style.FontSize = current.FontSize * tmpf;
- else if (unit == "pt")
- style.FontSize = tmpf / 0.75f;
- else if (unit == "%")
- style.FontSize = current.FontSize * tmpf / 100.f;
- else
- style.FontSize = tmpf;
- }
- }
- }
- }
-
- // second pass: rest of style
- for (it=styles.begin(); it != styles.end(); ++it)
- {
- if (it->first == "border")
- {
- sint32 b;
- if (it->second == "none")
- style.BorderWidth = 0;
- else
- if (fromString(it->second, b))
- style.BorderWidth = b;
- }
- else
- if (it->first == "font-style")
- {
- if (it->second == "inherit")
- style.FontOblique = current.FontOblique;
- else
- if (it->second == "italic" || it->second == "oblique")
- style.FontOblique = true;
- }
- else
- if (it->first == "font-family")
- {
- if (it->second == "inherit")
- style.FontFamily = current.FontFamily;
- else
- style.FontFamily = it->second;
- }
- else
- if (it->first == "font-weight")
- {
- // https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
- uint weight = 400;
- if (it->second == "inherit")
- weight = current.FontWeight;
- else
- if (it->second == "normal")
- weight = 400;
- else
- if (it->second == "bold")
- weight = 700;
- else
- if (it->second == "lighter")
- {
- const uint lighter[] = {100, 100, 100, 100, 100, 400, 400, 700, 700};
- uint index = current.FontWeight / 100 - 1;
- clamp(index, 1u, 9u);
- weight = lighter[index-1];
- }
- else
- if (it->second == "bolder")
- {
- const uint bolder[] = {400, 400, 400, 700, 700, 900, 900, 900, 900};
- uint index = current.FontWeight / 100 + 1;
- clamp(index, 1u, 9u);
- weight = bolder[index-1];
- }
- else
- if (fromString(it->second, weight))
- {
- weight = (weight / 100);
- clamp(weight, 1u, 9u);
- weight *= 100;
- }
- style.FontWeight = weight;
- }
- else
- if (it->first == "color")
- if (it->second == "inherit")
- style.TextColor = current.TextColor;
- else
- scanHTMLColor(it->second.c_str(), style.TextColor);
- else
- if (it->first == "text-decoration" || it->first == "text-decoration-line")
- {
- std::string prop(toLower(it->second));
- style.Underlined = (prop.find("underline") != std::string::npos);
- style.StrikeThrough = (prop.find("line-through") != std::string::npos);
- }
- else
- if (it->first == "text-stroke" || it->first == "-webkit-text-stroke")
- {
- // text-stroke: length || color
- bool success = false;
- uint px = 0;
- CRGBA color;
- std::vector parts;
- NLMISC::splitString(it->second, " ", parts);
- if (parts.size() == 1)
- {
- success = scanCssLength(parts[0], px);
- if (!success)
- success = scanHTMLColor(parts[0].c_str(), color);
- }
- else if (parts.size() == 2)
- {
- success = scanCssLength(parts[0], px);
- if (success)
- success = scanHTMLColor(parts[1].c_str(), color);
- else
- {
- success = scanHTMLColor(parts[0].c_str(), color);
- success = success && scanCssLength(parts[1], px);
- }
- }
-
- // do not disable shadow if one is already set
- if (success)
- {
- style.TextShadow.Enabled = (px > 0);
- style.TextShadow.Color = color;
- style.TextShadow.X = px;
- style.TextShadow.Y = px;
- style.TextShadow.Outline = true;
- }
- }
- else
- if (it->first == "text-shadow")
- {
- if (it->second == "none")
- style.TextShadow = STextShadow(false);
- else
- if (it->second == "inherit")
- style.TextShadow = current.TextShadow;
- else
- {
- // text-shadow: offset-x offset-y | blur | #color
- // text-shadow: #color | offset-x offset-y
- bool success = true;
- std::string prop(it->second);
- size_t pos;
- pos = prop.find_first_of(",\n\r");
- if (pos != std::string::npos)
- prop = prop.substr(0, pos);
-
- std::vector parts;
- NLMISC::splitString(prop, " ", parts);
- switch(parts.size())
- {
- case 1:
- {
- success = scanHTMLColor(it->second.c_str(), style.TextShadow.Color);
- break;
- }
- // no case 2:
- case 3:
- {
- if (!fromString(parts[0], style.TextShadow.X))
- {
- success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
- success = success && fromString(parts[1], style.TextShadow.X);
- success = success && fromString(parts[2], style.TextShadow.Y);
- }
- else
- {
- success = fromString(parts[1], style.TextShadow.Y);
- success = success && scanHTMLColor(parts[2].c_str(), style.TextShadow.Color);
- }
- break;
- }
- case 4:
- {
- if (!fromString(parts[0], style.TextShadow.X))
- {
- success = scanHTMLColor(parts[0].c_str(), style.TextShadow.Color);
- success = success && fromString(parts[1], style.TextShadow.X);
- success = success && fromString(parts[2], style.TextShadow.Y);
- // ignore blur [3]
- }
- else
- {
- success = fromString(parts[0], style.TextShadow.X);
- success = success && fromString(parts[1], style.TextShadow.Y);
- // ignore blur [2]
- success = success && scanHTMLColor(parts[3].c_str(), style.TextShadow.Color);
- }
- break;
- }
- default:
- {
- // unsupported rule
- break;
- }
- }
-
- style.TextShadow.Enabled = success;
- }
- }
- else
- if (it->first == "width")
- {
- std::string unit;
- if (getCssLength(tmpf, unit, it->second.c_str()))
- {
- if (unit == "rem")
- style.Width = tmpf * _StyleDefault.FontSize;
- else if (unit == "em")
- style.Width = tmpf * style.FontSize;
- else if (unit == "pt")
- style.FontSize = tmpf / 0.75f;
- else
- style.Width = tmpf;
- }
- }
- else
- if (it->first == "height")
- {
- std::string unit;
- if (getCssLength(tmpf, unit, it->second.c_str()))
- {
- if (unit == "rem")
- style.Height = tmpf * _StyleDefault.FontSize;
- else if (unit == "em")
- style.Height = tmpf * style.FontSize;
- else if (unit == "pt")
- style.FontSize = tmpf / 0.75f;
- else
- style.Height = tmpf;
- }
- }
- else
- if (it->first == "max-width")
- {
- std::string unit;
- if (getCssLength(tmpf, unit, it->second.c_str()))
- {
- if (unit == "rem")
- style.MaxWidth = tmpf * _StyleDefault.FontSize;
- else if (unit == "em")
- style.MaxWidth = tmpf * style.FontSize;
- else if (unit == "pt")
- style.FontSize = tmpf / 0.75f;
- else
- style.MaxWidth = tmpf;
- }
- }
- else
- if (it->first == "max-height")
- {
- std::string unit;
- if (getCssLength(tmpf, unit, it->second.c_str()))
- {
- if (unit == "rem")
- style.MaxHeight = tmpf * _StyleDefault.FontSize;
- else if (unit == "em")
- style.MaxHeight = tmpf * style.FontSize;
- else if (unit == "pt")
- style.FontSize = tmpf / 0.75f;
- else
- style.MaxHeight = tmpf;
- }
- }
- else
- if (it->first == "-ryzom-modulate-color")
- {
- bool b;
- if (it->second == "inherit")
- style.GlobalColor = current.GlobalColor;
- else
- if (fromString(it->second, b))
- style.GlobalColor = b;
- }
- else
- if (it->first == "background-color")
- {
- if (it->second == "inherit")
- style.BackgroundColor = current.BackgroundColor;
- else
- scanHTMLColor(it->second.c_str(), style.BackgroundColor);
- }
- else
- if (it->first == "-ryzom-background-color-over")
- {
- if (it->second == "inherit")
- style.BackgroundColorOver = current.BackgroundColorOver;
- else
- scanHTMLColor(it->second.c_str(), style.BackgroundColorOver);
- }
- }
-
- // if outer element has underline set, then inner element cannot remove it
- if (current.Underlined)
- style.Underlined = current.Underlined;
-
- // if outer element has line-through set, then inner element cannot remove it
- if (current.StrikeThrough)
- style.StrikeThrough = current.StrikeThrough;
- }
-
- // ***************************************************************************
- void CGroupHTML::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh)
- {
- if (maxw <= 0) maxw = width;
- if (maxh <= 0) maxh = height;
-
- maxw = std::max(minw, maxw);
- maxh = std::max(minh, maxh);
-
- float ratio = (float) width / std::max(1, height);
- if (width > maxw)
- {
- width = maxw;
- height = std::max((sint32)(maxw /ratio), minh);
- }
- if (width < minw)
- {
- width = minw;
- height = std::min((sint32)(minw / ratio), maxh);
- }
- if (height > maxh)
- {
- width = std::max((sint32)(maxh * ratio), minw);
- height = maxh;
- }
- if (height < minh)
- {
- width = std::min((sint32)(minh * ratio), maxw);
- height = minh;
- }
- if (width > maxw && height > maxh)
- {
- if (maxw/width <= maxh/height)
- {
- width = maxw;
- height = std::max(minh, (sint32)(maxw / ratio));
- }
- else
- {
- width = std::max(minw, (sint32)(maxh * ratio));
- height = maxh;
- }
- }
- if (width < minw && height < minh)
- {
- if (minw / width <= minh / height)
- {
- width = std::min(maxw, (sint32)(minh * ratio));
- height = minh;
- }
- else
- {
- width = minw;
- height = std::min(maxh, (sint32)(minw / ratio));
- }
- }
- if (width < minw && height > maxh)
- {
- width = minw;
- height = maxh;
- }
- if (width > maxw && height < minh)
- {
- width = maxw;
- height = minh;
- }
+ _Style.reset();
+ _Style.Root.TextColor = TextColor;
+ _Style.Root.FontSize = TextFontSize;
+ _Style.Root.BackgroundColor = BgColor;
+ _Style.Current = _Style.Root;
}
// ***************************************************************************
diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp
index ca8920b14..50cac24bf 100644
--- a/code/nel/src/gui/libwww.cpp
+++ b/code/nel/src/gui/libwww.cpp
@@ -345,6 +345,368 @@ namespace NLGUI
}
}
+ static bool isHexa(char c)
+ {
+ return isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f');
+ }
+
+ static uint8 convertHexa(char c)
+ {
+ return (uint8) (tolower(c) - (isdigit(c) ? '0' : ('a' - 10)));
+ }
+
+ // scan a color component, and return pointer to next position
+ static const char *scanColorComponent(const char *src, uint8 &intensity)
+ {
+ if (!src) return NULL;
+ if (!isHexa(*src)) return NULL;
+ uint8 value = convertHexa(*src++) << 4;
+ if (!isHexa(*src)) return NULL;
+ value += convertHexa(*src++);
+ intensity = value;
+ return src;
+ }
+
+ static float hueToRgb(float m1, float m2, float h)
+ {
+ if (h < 0) h += 1.0f;
+ if (h > 1) h -= 1.0f;
+ if (h*6 < 1.0f) return m1 + (m2 - m1)*h*6;
+ if (h*2 < 1.0f) return m2;
+ if (h*3 < 2.0f) return m1 + (m2 - m1) * (2.0f/3.0f - h)*6;
+ return m1;
+ }
+
+ static void hslToRgb(float h, float s, float l, CRGBA &result)
+ {
+ float m1, m2;
+ if (l <= 0.5f)
+ m2 = l * (s + 1.0f);
+ else
+ m2 = l + s - l * s;
+ m1 = l*2 - m2;
+
+ result.R = 255 * hueToRgb(m1, m2, h + 1.0f/3.0f);
+ result.G = 255 * hueToRgb(m1, m2, h);
+ result.B = 255 * hueToRgb(m1, m2, h - 1.0f/3.0f);
+ result.A = 255;
+ }
+
+ class CNameToCol
+ {
+ public:
+ const char *Name;
+ CRGBA Color;
+ CNameToCol(const char *name, CRGBA color) : Name(name), Color(color) {}
+ };
+
+ static CNameToCol htmlColorNameToRGBA[] =
+ {
+ CNameToCol("AliceBlue", CRGBA(0xF0, 0xF8, 0xFF)),
+ CNameToCol("AntiqueWhite", CRGBA(0xFA, 0xEB, 0xD7)),
+ CNameToCol("Aqua", CRGBA(0x00, 0xFF, 0xFF)),
+ CNameToCol("Aquamarine", CRGBA(0x7F, 0xFF, 0xD4)),
+ CNameToCol("Azure", CRGBA(0xF0, 0xFF, 0xFF)),
+ CNameToCol("Beige", CRGBA(0xF5, 0xF5, 0xDC)),
+ CNameToCol("Bisque", CRGBA(0xFF, 0xE4, 0xC4)),
+ CNameToCol("Black", CRGBA(0x00, 0x00, 0x00)),
+ CNameToCol("BlanchedAlmond", CRGBA(0xFF, 0xEB, 0xCD)),
+ CNameToCol("Blue", CRGBA(0x00, 0x00, 0xFF)),
+ CNameToCol("BlueViolet", CRGBA(0x8A, 0x2B, 0xE2)),
+ CNameToCol("Brown", CRGBA(0xA5, 0x2A, 0x2A)),
+ CNameToCol("BurlyWood", CRGBA(0xDE, 0xB8, 0x87)),
+ CNameToCol("CadetBlue", CRGBA(0x5F, 0x9E, 0xA0)),
+ CNameToCol("Chartreuse", CRGBA(0x7F, 0xFF, 0x00)),
+ CNameToCol("Chocolate", CRGBA(0xD2, 0x69, 0x1E)),
+ CNameToCol("Coral", CRGBA(0xFF, 0x7F, 0x50)),
+ CNameToCol("CornflowerBlue", CRGBA(0x64, 0x95, 0xED)),
+ CNameToCol("Cornsilk", CRGBA(0xFF, 0xF8, 0xDC)),
+ CNameToCol("Crimson", CRGBA(0xDC, 0x14, 0x3C)),
+ CNameToCol("Cyan", CRGBA(0x00, 0xFF, 0xFF)),
+ CNameToCol("DarkBlue", CRGBA(0x00, 0x00, 0x8B)),
+ CNameToCol("DarkCyan", CRGBA(0x00, 0x8B, 0x8B)),
+ CNameToCol("DarkGoldenRod", CRGBA(0xB8, 0x86, 0x0B)),
+ CNameToCol("DarkGray", CRGBA(0xA9, 0xA9, 0xA9)),
+ CNameToCol("DarkGreen", CRGBA(0x00, 0x64, 0x00)),
+ CNameToCol("DarkKhaki", CRGBA(0xBD, 0xB7, 0x6B)),
+ CNameToCol("DarkMagenta", CRGBA(0x8B, 0x00, 0x8B)),
+ CNameToCol("DarkOliveGreen", CRGBA(0x55, 0x6B, 0x2F)),
+ CNameToCol("Darkorange", CRGBA(0xFF, 0x8C, 0x00)),
+ CNameToCol("DarkOrchid", CRGBA(0x99, 0x32, 0xCC)),
+ CNameToCol("DarkRed", CRGBA(0x8B, 0x00, 0x00)),
+ CNameToCol("DarkSalmon", CRGBA(0xE9, 0x96, 0x7A)),
+ CNameToCol("DarkSeaGreen", CRGBA(0x8F, 0xBC, 0x8F)),
+ CNameToCol("DarkSlateBlue", CRGBA(0x48, 0x3D, 0x8B)),
+ CNameToCol("DarkSlateGray", CRGBA(0x2F, 0x4F, 0x4F)),
+ CNameToCol("DarkTurquoise", CRGBA(0x00, 0xCE, 0xD1)),
+ CNameToCol("DarkViolet", CRGBA(0x94, 0x00, 0xD3)),
+ CNameToCol("DeepPink", CRGBA(0xFF, 0x14, 0x93)),
+ CNameToCol("DeepSkyBlue", CRGBA(0x00, 0xBF, 0xFF)),
+ CNameToCol("DimGray", CRGBA(0x69, 0x69, 0x69)),
+ CNameToCol("DodgerBlue", CRGBA(0x1E, 0x90, 0xFF)),
+ CNameToCol("Feldspar", CRGBA(0xD1, 0x92, 0x75)),
+ CNameToCol("FireBrick", CRGBA(0xB2, 0x22, 0x22)),
+ CNameToCol("FloralWhite", CRGBA(0xFF, 0xFA, 0xF0)),
+ CNameToCol("ForestGreen", CRGBA(0x22, 0x8B, 0x22)),
+ CNameToCol("Fuchsia", CRGBA(0xFF, 0x00, 0xFF)),
+ CNameToCol("Gainsboro", CRGBA(0xDC, 0xDC, 0xDC)),
+ CNameToCol("GhostWhite", CRGBA(0xF8, 0xF8, 0xFF)),
+ CNameToCol("Gold", CRGBA(0xFF, 0xD7, 0x00)),
+ CNameToCol("GoldenRod", CRGBA(0xDA, 0xA5, 0x20)),
+ CNameToCol("Gray", CRGBA(0x80, 0x80, 0x80)),
+ CNameToCol("Green", CRGBA(0x00, 0x80, 0x00)),
+ CNameToCol("GreenYellow", CRGBA(0xAD, 0xFF, 0x2F)),
+ CNameToCol("HoneyDew", CRGBA(0xF0, 0xFF, 0xF0)),
+ CNameToCol("HotPink", CRGBA(0xFF, 0x69, 0xB4)),
+ CNameToCol("IndianRed ", CRGBA(0xCD, 0x5C, 0x5C)),
+ CNameToCol("Indigo ", CRGBA(0x4B, 0x00, 0x82)),
+ CNameToCol("Ivory", CRGBA(0xFF, 0xFF, 0xF0)),
+ CNameToCol("Khaki", CRGBA(0xF0, 0xE6, 0x8C)),
+ CNameToCol("Lavender", CRGBA(0xE6, 0xE6, 0xFA)),
+ CNameToCol("LavenderBlush", CRGBA(0xFF, 0xF0, 0xF5)),
+ CNameToCol("LawnGreen", CRGBA(0x7C, 0xFC, 0x00)),
+ CNameToCol("LemonChiffon", CRGBA(0xFF, 0xFA, 0xCD)),
+ CNameToCol("LightBlue", CRGBA(0xAD, 0xD8, 0xE6)),
+ CNameToCol("LightCoral", CRGBA(0xF0, 0x80, 0x80)),
+ CNameToCol("LightCyan", CRGBA(0xE0, 0xFF, 0xFF)),
+ CNameToCol("LightGoldenRodYellow", CRGBA(0xFA, 0xFA, 0xD2)),
+ CNameToCol("LightGrey", CRGBA(0xD3, 0xD3, 0xD3)),
+ CNameToCol("LightGreen", CRGBA(0x90, 0xEE, 0x90)),
+ CNameToCol("LightPink", CRGBA(0xFF, 0xB6, 0xC1)),
+ CNameToCol("LightSalmon", CRGBA(0xFF, 0xA0, 0x7A)),
+ CNameToCol("LightSeaGreen", CRGBA(0x20, 0xB2, 0xAA)),
+ CNameToCol("LightSkyBlue", CRGBA(0x87, 0xCE, 0xFA)),
+ CNameToCol("LightSlateBlue", CRGBA(0x84, 0x70, 0xFF)),
+ CNameToCol("LightSlateGray", CRGBA(0x77, 0x88, 0x99)),
+ CNameToCol("LightSteelBlue", CRGBA(0xB0, 0xC4, 0xDE)),
+ CNameToCol("LightYellow", CRGBA(0xFF, 0xFF, 0xE0)),
+ CNameToCol("Lime", CRGBA(0x00, 0xFF, 0x00)),
+ CNameToCol("LimeGreen", CRGBA(0x32, 0xCD, 0x32)),
+ CNameToCol("Linen", CRGBA(0xFA, 0xF0, 0xE6)),
+ CNameToCol("Magenta", CRGBA(0xFF, 0x00, 0xFF)),
+ CNameToCol("Maroon", CRGBA(0x80, 0x00, 0x00)),
+ CNameToCol("MediumAquaMarine", CRGBA(0x66, 0xCD, 0xAA)),
+ CNameToCol("MediumBlue", CRGBA(0x00, 0x00, 0xCD)),
+ CNameToCol("MediumOrchid", CRGBA(0xBA, 0x55, 0xD3)),
+ CNameToCol("MediumPurple", CRGBA(0x93, 0x70, 0xD8)),
+ CNameToCol("MediumSeaGreen", CRGBA(0x3C, 0xB3, 0x71)),
+ CNameToCol("MediumSlateBlue", CRGBA(0x7B, 0x68, 0xEE)),
+ CNameToCol("MediumSpringGreen", CRGBA(0x00, 0xFA, 0x9A)),
+ CNameToCol("MediumTurquoise", CRGBA(0x48, 0xD1, 0xCC)),
+ CNameToCol("MediumVioletRed", CRGBA(0xC7, 0x15, 0x85)),
+ CNameToCol("MidnightBlue", CRGBA(0x19, 0x19, 0x70)),
+ CNameToCol("MintCream", CRGBA(0xF5, 0xFF, 0xFA)),
+ CNameToCol("MistyRose", CRGBA(0xFF, 0xE4, 0xE1)),
+ CNameToCol("Moccasin", CRGBA(0xFF, 0xE4, 0xB5)),
+ CNameToCol("NavajoWhite", CRGBA(0xFF, 0xDE, 0xAD)),
+ CNameToCol("Navy", CRGBA(0x00, 0x00, 0x80)),
+ CNameToCol("OldLace", CRGBA(0xFD, 0xF5, 0xE6)),
+ CNameToCol("Olive", CRGBA(0x80, 0x80, 0x00)),
+ CNameToCol("OliveDrab", CRGBA(0x6B, 0x8E, 0x23)),
+ CNameToCol("Orange", CRGBA(0xFF, 0xA5, 0x00)),
+ CNameToCol("OrangeRed", CRGBA(0xFF, 0x45, 0x00)),
+ CNameToCol("Orchid", CRGBA(0xDA, 0x70, 0xD6)),
+ CNameToCol("PaleGoldenRod", CRGBA(0xEE, 0xE8, 0xAA)),
+ CNameToCol("PaleGreen", CRGBA(0x98, 0xFB, 0x98)),
+ CNameToCol("PaleTurquoise", CRGBA(0xAF, 0xEE, 0xEE)),
+ CNameToCol("PaleVioletRed", CRGBA(0xD8, 0x70, 0x93)),
+ CNameToCol("PapayaWhip", CRGBA(0xFF, 0xEF, 0xD5)),
+ CNameToCol("PeachPuff", CRGBA(0xFF, 0xDA, 0xB9)),
+ CNameToCol("Peru", CRGBA(0xCD, 0x85, 0x3F)),
+ CNameToCol("Pink", CRGBA(0xFF, 0xC0, 0xCB)),
+ CNameToCol("Plum", CRGBA(0xDD, 0xA0, 0xDD)),
+ CNameToCol("PowderBlue", CRGBA(0xB0, 0xE0, 0xE6)),
+ CNameToCol("Purple", CRGBA(0x80, 0x00, 0x80)),
+ CNameToCol("Red", CRGBA(0xFF, 0x00, 0x00)),
+ CNameToCol("RosyBrown", CRGBA(0xBC, 0x8F, 0x8F)),
+ CNameToCol("RoyalBlue", CRGBA(0x41, 0x69, 0xE1)),
+ CNameToCol("SaddleBrown", CRGBA(0x8B, 0x45, 0x13)),
+ CNameToCol("Salmon", CRGBA(0xFA, 0x80, 0x72)),
+ CNameToCol("SandyBrown", CRGBA(0xF4, 0xA4, 0x60)),
+ CNameToCol("SeaGreen", CRGBA(0x2E, 0x8B, 0x57)),
+ CNameToCol("SeaShell", CRGBA(0xFF, 0xF5, 0xEE)),
+ CNameToCol("Sienna", CRGBA(0xA0, 0x52, 0x2D)),
+ CNameToCol("Silver", CRGBA(0xC0, 0xC0, 0xC0)),
+ CNameToCol("SkyBlue", CRGBA(0x87, 0xCE, 0xEB)),
+ CNameToCol("SlateBlue", CRGBA(0x6A, 0x5A, 0xCD)),
+ CNameToCol("SlateGray", CRGBA(0x70, 0x80, 0x90)),
+ CNameToCol("Snow", CRGBA(0xFF, 0xFA, 0xFA)),
+ CNameToCol("SpringGreen", CRGBA(0x00, 0xFF, 0x7F)),
+ CNameToCol("SteelBlue", CRGBA(0x46, 0x82, 0xB4)),
+ CNameToCol("Tan", CRGBA(0xD2, 0xB4, 0x8C)),
+ CNameToCol("Teal", CRGBA(0x00, 0x80, 0x80)),
+ CNameToCol("Thistle", CRGBA(0xD8, 0xBF, 0xD8)),
+ CNameToCol("Tomato", CRGBA(0xFF, 0x63, 0x47)),
+ CNameToCol("Turquoise", CRGBA(0x40, 0xE0, 0xD0)),
+ CNameToCol("Violet", CRGBA(0xEE, 0x82, 0xEE)),
+ CNameToCol("VioletRed", CRGBA(0xD0, 0x20, 0x90)),
+ CNameToCol("Wheat", CRGBA(0xF5, 0xDE, 0xB3)),
+ CNameToCol("White", CRGBA(0xFF, 0xFF, 0xFF)),
+ CNameToCol("WhiteSmoke", CRGBA(0xF5, 0xF5, 0xF5)),
+ CNameToCol("Yellow", CRGBA(0xFF, 0xFF, 0x00)),
+ CNameToCol("YellowGreen", CRGBA(0x9A, 0xCD, 0x32))
+ };
+
+ // scan a color from a HTML form (#rrggbb format)
+ bool scanHTMLColor(const char *src, CRGBA &dest)
+ {
+ if (!src || *src == '\0') return false;
+ if (*src == '#')
+ {
+ ++src;
+ if (strlen(src) == 3 || strlen(src) == 4)
+ {
+ bool hasAlpha = (strlen(src) == 4);
+ // check RGB for valid hex
+ if (isHexa(src[0]) && isHexa(src[1]) && isHexa(src[2]))
+ {
+ // check optional A for valid hex
+ if (hasAlpha && !isHexa(src[3])) return false;
+
+ dest.R = convertHexa(src[0]);
+ dest.G = convertHexa(src[1]);
+ dest.B = convertHexa(src[2]);
+
+ dest.R = dest.R << 4 | dest.R;
+ dest.G = dest.G << 4 | dest.G;
+ dest.B = dest.B << 4 | dest.B;
+
+ if (hasAlpha)
+ {
+ dest.A = convertHexa(src[3]);
+ dest.A = dest.A << 4 | dest.A;
+ }
+ else
+ dest.A = 255;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ CRGBA result;
+ src = scanColorComponent(src, result.R); if (!src) return false;
+ src = scanColorComponent(src, result.G); if (!src) return false;
+ src = scanColorComponent(src, result.B); if (!src) return false;
+ src = scanColorComponent(src, result.A);
+ if (!src)
+ {
+ // Alpha is optional
+ result.A = 255;
+ }
+ dest = result;
+ return true;
+ }
+
+ if (strnicmp(src, "rgb(", 4) == 0 || strnicmp(src, "rgba(", 5) == 0)
+ {
+ src += 4;
+ if (*src == '(') src++;
+
+ std::vector parts;
+ NLMISC::splitString(src, ",", parts);
+ if (parts.size() >= 3)
+ {
+ CRGBA result;
+ sint tmpv;
+ float tmpf;
+
+ // R
+ if (getPercentage(tmpv, tmpf, parts[0].c_str())) tmpv = 255 * tmpf;
+ clamp(tmpv, 0, 255);
+ result.R = tmpv;
+
+ // G
+ if (getPercentage(tmpv, tmpf, parts[1].c_str())) tmpv = 255 * tmpf;
+ clamp(tmpv, 0, 255);
+ result.G = tmpv;
+
+ // B
+ if (getPercentage(tmpv, tmpf, parts[2].c_str())) tmpv = 255 * tmpf;
+ clamp(tmpv, 0, 255);
+ result.B = tmpv;
+
+ // A
+ if (parts.size() == 4)
+ {
+ if (!fromString(parts[3], tmpf)) return false;
+ if (parts[3].find_first_of("%") != std::string::npos)
+ tmpf /= 100;
+
+ tmpv = 255 * tmpf;
+ clamp(tmpv, 0, 255);
+ result.A = tmpv;
+ }
+ else
+ result.A = 255;
+
+ dest = result;
+ return true;
+ }
+
+ return false;
+ }
+
+ if (strnicmp(src, "hsl(", 4) == 0 || strnicmp(src, "hsla(", 5) == 0)
+ {
+ src += 4;
+ if (*src == '(') src++;
+
+ std::vector parts;
+ NLMISC::splitString(src, ",", parts);
+ if (parts.size() >= 3)
+ {
+ sint tmpv;
+ float h, s, l;
+ // hue
+ if (!fromString(parts[0], tmpv)) return false;
+ tmpv = ((tmpv % 360) + 360) % 360;
+ h = (float) tmpv / 360.0f;
+
+ // saturation
+ if (!getPercentage(tmpv, s, parts[1].c_str())) return false;
+ clamp(s, 0.0f, 1.0f);
+
+ // lightness
+ if (!getPercentage(tmpv, l, parts[2].c_str())) return false;
+ clamp(l, 0.0f, 1.0f);
+
+ CRGBA result;
+ hslToRgb(h, s, l, result);
+
+ // A
+ if (parts.size() == 4)
+ {
+ float tmpf;
+ if (!fromString(parts[3], tmpf)) return false;
+ if (parts[3].find_first_of("%") != std::string::npos)
+ tmpf /= 100;
+ clamp(tmpf, 0.0f, 1.0f);
+ result.A = 255 * tmpf;
+ }
+
+ dest = result;
+ return true;
+ }
+
+ return false;
+ }
+
+ {
+ // slow but should suffice for now
+ for(uint k = 0; k < sizeofarray(htmlColorNameToRGBA); ++k)
+ {
+ if (nlstricmp(src, htmlColorNameToRGBA[k].Name) == 0)
+ {
+ dest = htmlColorNameToRGBA[k].Color;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
// ***************************************************************************
CRGBA getColor (const char *color)