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/>.
20 #include "nel/gui/libwww.h"
21 #include "nel/gui/css_length.h"
22 #include "nel/gui/css_background.h"
24 using namespace NLMISC
;
33 void CSSBackground::setImage(const std::string
&value
)
38 void CSSBackground::setPosition(const std::string
&value
)
40 std::vector
<std::string
> parts
;
41 splitString(toLowerAscii(value
), " ", parts
);
43 if (parts
.empty() || parts
.size() > 4)
49 positionFromOne(parts
);
52 positionFromTwo(parts
);
55 positionFromThree(parts
);
58 positionFromFour(parts
);
65 void CSSBackground::setSize(const std::string
&value
)
67 std::vector
<std::string
> parts
;
68 splitString(toLowerAscii(value
), " ", parts
);
72 if (parts
.size() == 1 && (parts
[0] == "cover" || parts
[0] == "contain"))
74 if (parts
[0] == "cover")
75 size
= CSS_VALUE_COVER
;
77 size
= CSS_VALUE_CONTAIN
;
84 // height will default to 'auto' if not set
85 if (parts
.size() == 1)
86 parts
.push_back("auto");
88 if (parts
[0] == "auto" && parts
[1] == "auto")
90 size
= CSS_VALUE_AUTO
;
98 if (parts
[0] == "auto")
106 if (!getCssLength(fval
, unit
, parts
[0]))
108 nlwarning("Failed to parse background-size[0] '%s'", parts
[0].c_str());
111 newW
.setFloatValue(fval
, unit
);
114 if (parts
[1] == "auto")
122 if (!getCssLength(fval
, unit
, parts
[1]))
124 nlwarning("Failed to parse background-size[1] '%s'", parts
[1].c_str());
127 newH
.setFloatValue(fval
, unit
);
130 size
= CSS_VALUE_LENGTH
;
135 void CSSBackground::setRepeat(const std::string
&value
)
137 std::vector
<std::string
> parts
;
138 splitString(toLowerAscii(value
), " ", parts
);
139 if (parts
.size() == 0 || parts
.size() > 2)
142 if (parts
.size() == 1)
144 if (parts
[0] == "repeat-x")
145 parts
.push_back("no-repeat");
146 else if (parts
[0] == "repeat-y")
147 parts
.insert(parts
.begin(), "no-repeat");
148 else //repeat, space, round, no-repeat
149 parts
.push_back(parts
[0]);
153 if (parts
[0] == "repeat") repeatX
= CSS_VALUE_REPEAT
;
154 else if (parts
[0] == "no-repeat") repeatX
= CSS_VALUE_NOREPEAT
;
155 else if (parts
[0] == "space") repeatX
= CSS_VALUE_SPACE
;
156 else if (parts
[0] == "round") repeatX
= CSS_VALUE_ROUND
;
157 else repeatX
= CSS_VALUE_REPEAT
;
159 if (parts
[1] == "repeat") repeatY
= CSS_VALUE_REPEAT
;
160 else if (parts
[1] == "no-repeat") repeatY
= CSS_VALUE_NOREPEAT
;
161 else if (parts
[1] == "space") repeatY
= CSS_VALUE_SPACE
;
162 else if (parts
[1] == "round") repeatY
= CSS_VALUE_ROUND
;
163 else repeatY
= CSS_VALUE_REPEAT
;
166 void CSSBackground::setOrigin(const std::string
&value
)
168 if (value
== "border-box") origin
= CSS_VALUE_BORDER_BOX
;
169 else if (value
== "padding-box") origin
= CSS_VALUE_PADDING_BOX
;
170 else if (value
== "content-box") origin
= CSS_VALUE_CONTENT_BOX
;
171 else origin
= CSS_VALUE_PADDING_BOX
;
174 void CSSBackground::setClip(const std::string
&value
)
176 if (value
== "border-box") clip
= CSS_VALUE_BORDER_BOX
;
177 else if (value
== "padding-box") clip
= CSS_VALUE_PADDING_BOX
;
178 else if (value
== "content-box") clip
= CSS_VALUE_CONTENT_BOX
;
179 //else if (value == "text") clip = CSSValueType::Text;
180 else clip
= CSS_VALUE_PADDING_BOX
;
183 void CSSBackground::setAttachment(const std::string
&value
)
185 if (value
== "fixed") attachment
= CSS_VALUE_FIXED
;
186 else if (value
== "local") attachment
= CSS_VALUE_LOCAL
;
187 else if (value
== "scroll") attachment
= CSS_VALUE_SCROLL
;
188 else attachment
= CSS_VALUE_SCROLL
;
191 void CSSBackground::setColor(const std::string
&value
)
194 if (scanHTMLColor(value
.c_str(), tmp
))
198 static bool isHorizontalKeyword(const std::string
&val
)
200 return val
== "left" || val
== "right";
203 static bool isVerticalKeyword(const std::string
&val
)
205 return val
== "top" || val
== "bottom";
208 void CSSBackground::positionFromOne(const std::vector
<std::string
> &parts
)
210 CSSValueType newH
= CSS_VALUE_LEFT
;
211 CSSValueType newV
= CSS_VALUE_TOP
;
212 CSSLength newX
, newY
;
213 newX
.setFloatValue(0, "%");
214 newY
.setFloatValue(0, "%");
219 if (isHorizontalKeyword(parts
[index
]))
221 newH
= parts
[index
] == "left" ? CSS_VALUE_LEFT
: CSS_VALUE_RIGHT
;
222 newV
= CSS_VALUE_CENTER
;
224 else if (isVerticalKeyword(parts
[index
]))
226 newH
= CSS_VALUE_CENTER
;
227 newV
= parts
[index
] == "top" ? CSS_VALUE_TOP
: CSS_VALUE_BOTTOM
;
229 else if (parts
[index
] == "center")
231 newH
= CSS_VALUE_CENTER
;
232 newV
= CSS_VALUE_CENTER
;
234 else if (getCssLength(fval
, unit
, parts
[index
], true))
236 newX
.setFloatValue(fval
, unit
);
237 newV
= CSS_VALUE_CENTER
;
250 void CSSBackground::positionFromTwo(const std::vector
<std::string
> &parts
)
252 CSSValueType newH
= CSS_VALUE_LEFT
;
253 CSSValueType newV
= CSS_VALUE_TOP
;
254 CSSLength newX
, newY
;
255 newX
.setFloatValue(0, "%");
256 newY
.setFloatValue(0, "%");
261 bool hasCenter
= false;
264 for (uint index
= 0; index
< parts
.size(); index
++)
266 if (parts
[index
] == "center")
270 else if (isHorizontalKeyword(parts
[index
]))
274 newH
= parts
[index
] == "left" ? CSS_VALUE_LEFT
: CSS_VALUE_RIGHT
;
276 else if (isVerticalKeyword(parts
[index
]))
280 newV
= parts
[index
] == "top" ? CSS_VALUE_TOP
: CSS_VALUE_BOTTOM
;
282 else if (getCssLength(fval
, unit
, parts
[index
], true))
284 // invalid: 'top 50%';
289 newX
.setFloatValue(fval
, unit
);
294 newY
.setFloatValue(fval
, unit
);
306 newH
= CSS_VALUE_CENTER
;
308 newV
= CSS_VALUE_CENTER
;
317 void CSSBackground::positionFromThree(const std::vector
<std::string
> &parts
)
319 CSSValueType newH
= CSS_VALUE_LEFT
;
320 CSSValueType newV
= CSS_VALUE_TOP
;
321 CSSLength newX
, newY
;
322 newX
.setFloatValue(0, "%");
323 newY
.setFloatValue(0, "%");
327 bool hasCenter
= false;
330 for(uint index
= 0; index
< 3; index
++)
332 if (parts
[index
] == "center")
334 if (hasCenter
) return;
337 else if (isHorizontalKeyword(parts
[index
]))
341 newH
= parts
[index
] == "left" ? CSS_VALUE_LEFT
: CSS_VALUE_RIGHT
;
342 if ((index
+1) < parts
.size() && getCssLength(fval
, unit
, parts
[index
+1], true))
344 newX
.setFloatValue(fval
, unit
);
348 else if (isVerticalKeyword(parts
[index
]))
352 newV
= parts
[index
] == "top" ? CSS_VALUE_TOP
: CSS_VALUE_BOTTOM
;
353 if ((index
+1) < parts
.size() && getCssLength(fval
, unit
, parts
[index
+1], true))
355 newY
.setFloatValue(fval
, unit
);
370 newH
= CSS_VALUE_CENTER
;
372 newV
= CSS_VALUE_CENTER
;
381 void CSSBackground::positionFromFour(const std::vector
<std::string
> &parts
)
383 CSSValueType newH
= CSS_VALUE_LEFT
;
384 CSSValueType newV
= CSS_VALUE_TOP
;
385 CSSLength newX
, newY
;
386 newX
.setFloatValue(0, "%");
387 newY
.setFloatValue(0, "%");
393 for(uint index
= 0; index
<4; index
+=2)
395 if (parts
[index
] == "center")
398 if (isHorizontalKeyword(parts
[index
]))
402 if (!getCssLength(fval
, unit
, parts
[index
+1], true)) return;
403 newH
= parts
[index
] == "left" ? CSS_VALUE_LEFT
: CSS_VALUE_RIGHT
;
404 newX
.setFloatValue(fval
, unit
);
406 else if (isVerticalKeyword(parts
[index
]))
410 if (!getCssLength(fval
, unit
, parts
[index
+1], true)) return;
411 newV
= parts
[index
] == "top" ? CSS_VALUE_TOP
: CSS_VALUE_BOTTOM
;
412 newY
.setFloatValue(fval
, unit
);