1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 Winch Gate Property Limited
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.
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"
32 typedef std::map
<std::string
, std::string
> TStyle
;
33 typedef std::pair
<std::string
, std::string
> TStylePair
;
34 typedef std::vector
<TStylePair
> TStyleVec
;
37 * \brief CSS style rules
38 * \date 2019-03-15 10:50 GMT
39 * \author Meelis Mägi (Nimetu)
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
)
58 CStyleParams () : FontFamily(""), TextColor(255,255,255,255), TextShadow()
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
: "");
92 std::string FontFamily
;
93 NLMISC::CRGBA TextColor
;
94 STextShadow TextShadow
;
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
;
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>'
133 // current element style
134 CStyleParams Current
;
136 // known style rules sorted by specificity
137 std::vector
<SStyleRule
> _StyleRules
;
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
¤t
) const;
150 void getStyleParams(const TStyle
&styleRules
, CStyleParams
&style
, const CStyleParams
¤t
) 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
¤t
) const;
155 // apply style.StyleRyles
156 void apply(CStyleParams
&style
, const CStyleParams
¤t
) 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
¤tWidth
) const;
186 void applyBorderColor(const std::string
&value
, NLMISC::CRGBA
*dest
, const NLMISC::CRGBA
¤tColor
, const NLMISC::CRGBA
&textColor
) const;
187 void applyLineStyle(const std::string
&value
, CSSLineStyle
*dest
, const CSSLineStyle
¤tStyle
) 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;
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)
210 return Current
.FontSize
-2;
213 inline void pushStyle()
215 _StyleStack
.push_back(Current
);
217 Current
.GlobalColor
= false;
218 Current
.DisplayBlock
= false;
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())
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
);
279 #endif // CL_CSS_STYLE_H