Dotted/dashed border styles
[ryzomcore.git] / nel / include / nel / gui / css_style.h
blob042486d1775650b5f145b13fbc11ea514fc73543
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef CL_CSS_STYLE_H
18 #define CL_CSS_STYLE_H
20 #include "nel/misc/types_nl.h"
21 #include "nel/misc/rgba.h"
22 #include "nel/gui/css_selector.h"
23 #include "nel/gui/css_types.h"
24 #include "nel/gui/css_length.h"
25 #include "nel/gui/css_background.h"
26 #include "nel/gui/css_border.h"
28 namespace NLGUI
30 class CHtmlElement;
32 typedef std::map<std::string, std::string> TStyle;
33 typedef std::pair<std::string, std::string> TStylePair;
34 typedef std::vector<TStylePair> TStyleVec;
36 /**
37 * \brief CSS style rules
38 * \date 2019-03-15 10:50 GMT
39 * \author Meelis Mägi (Nimetu)
41 class CStyleParams
43 public:
44 struct STextShadow
46 public:
47 STextShadow(bool enabled = false, bool outline = false, sint32 x=1, sint32 y=1, NLMISC::CRGBA color=NLMISC::CRGBA::Black)
48 : Enabled(enabled), Outline(outline), X(x), Y(y), Color(color)
49 { }
51 bool Enabled;
52 bool Outline;
53 sint32 X;
54 sint32 Y;
55 NLMISC::CRGBA Color;
57 public:
58 CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
60 FontSize=10;
61 FontWeight=400;
62 FontOblique=false;
63 Underlined=false;
64 StrikeThrough=false;
65 GlobalColor=false;
66 DisplayBlock=false;
67 Width=-1;
68 Height=-1;
69 MaxWidth=-1;
70 MaxHeight=-1;
71 // background
72 BackgroundColorOver=NLMISC::CRGBA::Black;
73 MarginTop = MarginRight = MarginBottom = MarginLeft = 0;
74 PaddingTop = PaddingRight = PaddingBottom = PaddingLeft = 0;
77 bool hasStyle(const std::string &key) const
79 return StyleRules.find(key) != StyleRules.end();
82 std::string getStyle(const std::string &key) const
84 TStyle::const_iterator it = StyleRules.find(key);
85 return (it != StyleRules.end() ? it->second : "");
88 public:
89 uint FontSize;
90 uint FontWeight;
91 bool FontOblique;
92 std::string FontFamily;
93 NLMISC::CRGBA TextColor;
94 STextShadow TextShadow;
95 bool GlobalColor;
96 bool Underlined;
97 bool StrikeThrough;
98 bool DisplayBlock;
99 sint32 Width;
100 sint32 Height;
101 sint32 MaxWidth;
102 sint32 MaxHeight;
103 CSSRect<CSSBorder> Border;
104 CSSBackground Background;
105 NLMISC::CRGBA BackgroundColorOver;
106 uint32 MarginTop, MarginRight, MarginBottom, MarginLeft;
107 uint32 PaddingTop, PaddingRight, PaddingBottom, PaddingLeft;
109 std::string WhiteSpace;
110 std::string TextAlign;
111 std::string VerticalAlign;
113 TStyle StyleRules;
116 class CCssStyle {
117 public:
119 struct SStyleRule {
120 std::vector<CCssSelector> Selector;
121 TStyleVec Properties;
123 // pseudo element like ':before'
124 std::string PseudoElement;
126 // returns selector specificity
127 uint specificity() const;
130 // 'browser' style, overwriten with '<html>'
131 CStyleParams Root;
133 // current element style
134 CStyleParams Current;
136 // known style rules sorted by specificity
137 std::vector<SStyleRule> _StyleRules;
139 private:
140 std::vector<CStyleParams> _StyleStack;
142 // test if str is one of "thin/medium/thick" and return its pixel value
143 bool scanCssLength(const std::string& str, uint32 &px) const;
145 // split css properties string, ie '1px solid rgb(100, 100, 100)' split by ' ' returns 3 parts.
146 void splitParams(const std::string &str, char sep, std::vector<std::string> &result) const;
148 // read style attribute
149 void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams &current) const;
150 void getStyleParams(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const;
152 // extract from styleRules into style.StyleRules (expand shorthand, normalize, calculate current font-size)
153 void normalize(const TStyle &styleRules, CStyleParams &style, const CStyleParams &current) const;
155 // apply style.StyleRyles
156 void apply(CStyleParams &style, const CStyleParams &current) const;
158 // merge src into dest by overwriting key in dest
159 void merge(TStyle &dst, const TStyleVec &src) const;
161 // match selector to dom path
162 bool match(const std::vector<CCssSelector> &selector, const CHtmlElement &elm) const;
164 // get shorthang 'top right bottom left' index values based size, ie 'padding' syntax
165 bool getShorthandIndices(const uint32 size, uint8 &t, uint8 &r, uint8 &b, uint8 &l) const;
167 // break 'border' into 'border-top-color', 'border-top-style', etc rules
168 bool tryBorderWidthShorthand(const std::string &prop, const std::string &value, TStyle &style) const;
169 bool tryBorderStyleShorthand(const std::string &prop, const std::string &value, TStyle &style) const;
170 bool tryBorderColorShorthand(const std::string &prop, const std::string &value, TStyle &style) const;
171 void expandBorderShorthand(const std::string &prop, const std::string &value, TStyle &style) const;
173 // parse 'background' into 'background-color', 'background-image', etc
174 void expandBackgroundShorthand(const std::string &value, TStyle &style) const;
176 // parse 'padding' into 'padding-top', 'padding-left', etc
177 void expandPaddingShorthand(const std::string &value, TStyle &style) const;
178 void expandMarginShorthand(const std::string &value, TStyle &style) const;
180 // expand shorthand rule, ie "border", into longhand names, ie "border-top-width"
181 // if shorthand is present in style, then its removed
182 void expandShorthand(const std::string &prop, const std::string &value, TStyle &style) const;
184 // parse string value into corresponding value
185 void applyBorderWidth(const std::string &value, CSSLength *dest, const CSSLength &currentWidth) const;
186 void applyBorderColor(const std::string &value, NLMISC::CRGBA *dest, const NLMISC::CRGBA &currentColor, const NLMISC::CRGBA &textColor) const;
187 void applyLineStyle(const std::string &value, CSSLineStyle *dest, const CSSLineStyle &currentStyle) const;
188 void applyPaddingWidth(const std::string &value, uint32 *dest, const uint32 currentPadding, uint32 fontSize) const;
189 void applyMarginWidth(const std::string &value, uint32 *dest, const uint32 current, uint32 fontSize) const;
191 // parse and replace var(--name, fallback) function
192 // return false if property should be ignored
193 bool cssFuncVar(std::string &func, const TStyle &styleRules, const std::set<std::string> &seenProperties) const;
194 // return false if property was not defined
195 bool lookupPropertyValue(const std::string &name, std::string &value, const TStyle &styleRules) const;
197 public:
198 void reset();
200 // parse <style>..</style> tag or css file content
201 void parseStylesheet(const std::string &styleString);
203 // set element style from matching css rules
204 void getStyleFor(CHtmlElement &elm) const;
206 inline uint getFontSizeSmaller() const
208 if (Current.FontSize < 5)
209 return 3;
210 return Current.FontSize-2;
213 inline void pushStyle()
215 _StyleStack.push_back(Current);
217 Current.GlobalColor = false;
218 Current.DisplayBlock = false;
219 Current.Width=-1;
220 Current.Height=-1;
221 Current.MaxWidth=-1;
222 Current.MaxHeight=-1;
224 Current.Border.Top.reset();
225 Current.Border.Right.reset();
226 Current.Border.Bottom.reset();
227 Current.Border.Left.reset();
229 Current.Background = CSSBackground();
230 Current.BackgroundColorOver = NLMISC::CRGBA::Transparent;
232 Current.MarginTop = Current.MarginRight = Current.MarginBottom = Current.MarginLeft = 0;
233 Current.PaddingTop = Current.PaddingRight = Current.PaddingBottom = Current.PaddingLeft = 0;
235 Current.StyleRules.clear();
238 inline void popStyle()
240 if (_StyleStack.empty())
242 Current = Root;
244 else
246 Current = _StyleStack.back();
247 _StyleStack.pop_back();
251 // apply style to this.Root
252 void applyRootStyle(const std::string &styleString);
253 void applyRootStyle(const TStyle &styleRules);
255 // apply style to this.Current
256 void applyStyle(const std::string &styleString);
257 void applyStyle(const TStyle &styleRules);
259 void applyCssMinMax(sint32 &width, sint32 &height, sint32 minw=0, sint32 minh=0, sint32 maxw=0, sint32 maxh=0) const;
261 // check if current style property matches value
262 bool checkStyle(const std::string &key, const std::string &val) const
264 return Current.hasStyle(key) && Current.getStyle(key) == val;
267 bool hasStyle(const std::string &key) const
269 return Current.hasStyle(key);
272 std::string getStyle(const std::string &key) const
274 return Current.getStyle(key);
277 }//namespace
279 #endif // CL_CSS_STYLE_H