From 2b74943a5bb556af842502bcaf56769d96af72ae Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 29 Mar 2015 18:24:19 +0300 Subject: [PATCH] Add span tag and bold, italic, underline, strikethrough styles to CGroupHTML --- code/nel/include/nel/gui/group_html.h | 56 +++++++++- code/nel/include/nel/gui/libwww.h | 7 ++ code/nel/src/gui/group_html.cpp | 144 +++++++++++++++++++++++++- code/nel/src/gui/libwww.cpp | 10 ++ 4 files changed, 213 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 4f9bee46c..920c58948 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -425,6 +425,38 @@ namespace NLGUI return _FontSize.back(); } + std::vector _FontWeight; + inline uint getFontWeight() const + { + if (_FontWeight.empty()) + return 400; + return _FontWeight.back(); + } + + std::vector _FontOblique; + inline uint getFontOblique() const + { + if (_FontOblique.empty()) + return false; + return _FontOblique.back(); + } + + std::vector _FontUnderlined; + inline uint getFontUnderlined() const + { + if (_FontUnderlined.empty()) + return false; + return _FontUnderlined.back(); + } + + std::vector _FontStrikeThrough; + inline uint getFontStrikeThrough() const + { + if (_FontStrikeThrough.empty()) + return false; + return _FontStrikeThrough.back(); + } + // Current link std::vector _Link; inline const char *getLink() const @@ -544,6 +576,26 @@ namespace NLGUI }; std::vector _CellParams; + class CStyleParams + { + public: + CStyleParams () : TextColor(255,255,255,255) + { + FontSize=10; + FontWeight=400; + FontOblique=false; + Underlined=false; + StrikeThrough=false; + } + uint FontSize; + uint FontWeight; + bool FontOblique; + NLMISC::CRGBA TextColor; + bool Underlined; + bool StrikeThrough; + + }; + // Indentation uint _Indent; @@ -613,8 +665,10 @@ namespace NLGUI typedef std::map > TGroupHtmlByUIDMap; static TGroupHtmlByUIDMap _GroupHtmlByUID; - private: + // read style attribute + void getStyleParams(const std::string &styleString, CStyleParams &style, bool inherit = true); + private: // decode all HTML entities static ucstring decodeHTMLEntities(const ucstring &str); diff --git a/code/nel/include/nel/gui/libwww.h b/code/nel/include/nel/gui/libwww.h index bb6b2da86..b1f070ddd 100644 --- a/code/nel/include/nel/gui/libwww.h +++ b/code/nel/include/nel/gui/libwww.h @@ -218,6 +218,13 @@ namespace NLGUI HTML_ATTR(DIV,STYLE), }; + enum + { + HTML_ATTR(SPAN,CLASS) = 0, + HTML_ATTR(SPAN,ID), + HTML_ATTR(SPAN,STYLE), + }; + #undef HTML_ATTR diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 656e36ca8..4dd9ea7ac 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -485,7 +485,7 @@ namespace NLGUI string fullstyle = style[1]; for (uint j=2; j < style.size(); j++) fullstyle += ":"+style[j]; - styles[trim(style[0])] = fullstyle; + styles[trim(style[0])] = trim(fullstyle); } } @@ -894,7 +894,20 @@ namespace NLGUI switch(element_number) { case HTML_A: - _TextColor.push_back(LinkColor); + { + CStyleParams style; + style.FontSize = getFontSize(); + style.TextColor = LinkColor; + style.Underlined = true; + style.StrikeThrough = getFontStrikeThrough(); + + if (present[HTML_A_STYLE] && value[HTML_A_STYLE]) + getStyleParams(value[HTML_A_STYLE], style); + + _FontSize.push_back(style.FontSize); + _TextColor.push_back(style.TextColor); + _FontUnderlined.push_back(style.Underlined); + _FontStrikeThrough.push_back(style.StrikeThrough); _GlobalColor.push_back(LinkColorGlobalColor); _A.push_back(true); @@ -903,6 +916,7 @@ namespace NLGUI if (present[MY_HTML_A_CLASS] && value[MY_HTML_A_CLASS]) _LinkClass.push_back(value[MY_HTML_A_CLASS]); + } break; case HTML_DIV: @@ -1634,6 +1648,28 @@ namespace NLGUI _Object = true; break; + case HTML_SPAN: + { + CStyleParams style; + style.TextColor = getTextColor(); + style.FontSize = getFontSize(); + style.FontWeight = getFontWeight(); + style.FontOblique = getFontOblique(); + style.Underlined = getFontUnderlined(); + style.StrikeThrough = getFontStrikeThrough(); + + if (present[MY_HTML_SPAN_STYLE] && value[MY_HTML_SPAN_STYLE]) + getStyleParams(value[MY_HTML_SPAN_STYLE], style); + + _TextColor.push_back(style.TextColor); + _FontSize.push_back(style.FontSize); + _FontWeight.push_back(style.FontWeight); + _FontOblique.push_back(style.FontOblique); + _FontUnderlined.push_back(style.Underlined); + _FontStrikeThrough.push_back(style.StrikeThrough); + } + break; + case HTML_STYLE: _IgnoreText = true; break; @@ -1655,7 +1691,10 @@ namespace NLGUI popIfNotEmpty (_FontSize); break; case HTML_A: + popIfNotEmpty (_FontSize); popIfNotEmpty (_TextColor); + popIfNotEmpty (_FontUnderlined); + popIfNotEmpty (_FontStrikeThrough); popIfNotEmpty (_GlobalColor); popIfNotEmpty (_A); popIfNotEmpty (_Link); @@ -1763,6 +1802,14 @@ namespace NLGUI popIfNotEmpty (_UL); } break; + case HTML_SPAN: + popIfNotEmpty (_FontSize); + popIfNotEmpty (_FontWeight); + popIfNotEmpty (_FontOblique); + popIfNotEmpty (_TextColor); + popIfNotEmpty (_FontUnderlined); + popIfNotEmpty (_FontStrikeThrough); + break; case HTML_STYLE: _IgnoreText = false; break; @@ -3077,6 +3124,7 @@ namespace NLGUI // Text added ? bool added = false; + bool embolden = getFontWeight() >= 700; // Number of child in this paragraph if (_CurrentViewLink) @@ -3086,6 +3134,10 @@ namespace NLGUI if (!skipLine && (getTextColor() == _CurrentViewLink->getColor()) && (getFontSize() == (uint)_CurrentViewLink->getFontSize()) && + (getFontUnderlined() == _CurrentViewLink->getUnderlined()) && + (getFontStrikeThrough() == _CurrentViewLink->getStrikeThrough()) && + (embolden == _CurrentViewLink->getEmbolden()) && + (getFontOblique() == _CurrentViewLink->getOblique()) && (getLink() == _CurrentViewLink->Link) && (getGlobalColor() == _CurrentViewLink->getModulateGlobalColor())) { @@ -3141,12 +3193,15 @@ namespace NLGUI if (!newLink->Link.empty()) { newLink->setHTMLView (this); - newLink->setUnderlined (true); } } newLink->setText(tmpStr); newLink->setColor(getTextColor()); newLink->setFontSize(getFontSize()); + newLink->setEmbolden(embolden); + newLink->setOblique(getFontOblique()); + newLink->setUnderlined(getFontUnderlined()); + newLink->setStrikeThrough(getFontStrikeThrough()); newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor)); newLink->setMultiLine(true); newLink->setModulateGlobalColor(getGlobalColor()); @@ -3422,6 +3477,10 @@ namespace NLGUI _TextColor.clear(); _GlobalColor.clear(); _FontSize.clear(); + _FontWeight.clear(); + _FontOblique.clear(); + _FontUnderlined.clear(); + _FontStrikeThrough.clear(); _Indent = 0; _LI = false; _UL.clear(); @@ -4590,5 +4649,84 @@ namespace NLGUI return result; } + + // *************************************************************************** + // 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, bool inherit) + { + TStyle styles = parseStyle(styleString); + TStyle::iterator it; + for (it=styles.begin(); it != styles.end(); ++it) + { + if (it->first == "font-size") + { + float tmp; + sint size = 0; + getPercentage (size, tmp, it->second.c_str()); + if (size > 0) + style.FontSize = size; + } + else + if (it->first == "font-style") + { + if (it->second == "italic" || it->second == "oblique") + style.FontOblique = true; + } + else + if (it->first == "font-weight") + { + // https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight + uint weight = 400; + 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}; + int index = getFontWeight() / 100 - 1; + clamp(index, 1, 9); + weight = lighter[index-1]; + } + else + if (it->second == "bolder") + { + const uint bolder[] = {400, 400, 400, 700, 700, 900, 900, 900, 900}; + uint index = getFontWeight() / 100 + 1; + clamp(index, 1, 9); + weight = bolder[index-1]; + } + else + if (fromString(it->second, weight)) + { + weight = (weight / 100); + clamp(weight, 1, 9); + weight *= 100; + } + style.FontWeight = weight; + } + else + if (it->first == "color") + scanHTMLColor(it->second.c_str(), style.TextColor); + else + if (it->first == "text-decoration" || it->first == "text-decoration-line") + { + std::string prop(strlwr(it->second)); + style.Underlined = (prop.find("underline") != std::string::npos); + style.StrikeThrough = (prop.find("line-through") != std::string::npos); + } + } + if (inherit) + { + style.Underlined = getFontUnderlined() || style.Underlined; + style.StrikeThrough = getFontStrikeThrough() || style.StrikeThrough; + } + } } diff --git a/code/nel/src/gui/libwww.cpp b/code/nel/src/gui/libwww.cpp index b17d1cccb..14e921aea 100644 --- a/code/nel/src/gui/libwww.cpp +++ b/code/nel/src/gui/libwww.cpp @@ -233,6 +233,14 @@ namespace NLGUI { 0 } }; + HTAttr span_attr[] = + { + HTML_ATTR(SPAN,CLASS), + HTML_ATTR(SPAN,ID), + HTML_ATTR(SPAN,STYLE), + { 0 } + }; + // *************************************************************************** void _VerifyLibWWW(const char *function, bool ok, const char *file, int line) @@ -699,6 +707,8 @@ namespace NLGUI HTML_DTD->tags[HTML_I].number_of_attributes = 0; HTML_DTD->tags[HTML_DIV].attributes = div_attr; HTML_DTD->tags[HTML_DIV].number_of_attributes = sizeof(div_attr) / sizeof(HTAttr) - 1; + HTML_DTD->tags[HTML_SPAN].attributes = span_attr; + HTML_DTD->tags[HTML_SPAN].number_of_attributes = sizeof(span_attr) / sizeof(HTAttr) - 1; // Set a request timeout // HTHost_setEventTimeout (30000);