From c760b1e3d9309092247b1108fd13939494f876b3 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 29 Mar 2015 17:28:33 +0300 Subject: [PATCH 1/3] Add embolden, oblique font styles (NL3D) --HG-- branch : develop --- code/nel/include/nel/3d/font_generator.h | 4 +++- code/nel/include/nel/3d/font_manager.h | 8 +++++++ code/nel/include/nel/3d/text_context.h | 22 ++++++++++++++----- code/nel/include/nel/3d/text_context_user.h | 4 ++++ code/nel/include/nel/3d/texture_font.h | 4 ++++ code/nel/include/nel/3d/u_text_context.h | 18 ++++++++++++++++ code/nel/src/3d/font_generator.cpp | 15 +++++++++++-- code/nel/src/3d/font_manager.cpp | 12 ++++++++++- code/nel/src/3d/ps_util.cpp | 2 ++ code/nel/src/3d/text_context.cpp | 6 ++++-- code/nel/src/3d/text_context_user.cpp | 24 +++++++++++++++++++++ code/nel/src/3d/texture_font.cpp | 19 +++++++++++----- 12 files changed, 122 insertions(+), 16 deletions(-) diff --git a/code/nel/include/nel/3d/font_generator.h b/code/nel/include/nel/3d/font_generator.h index 36dbf309a..5a07733a0 100644 --- a/code/nel/include/nel/3d/font_generator.h +++ b/code/nel/include/nel/3d/font_generator.h @@ -54,11 +54,13 @@ public: /** generate and return a bitmap * \param c the unicode char * \param size size of the generated font in ??? format + * \param embolden set embolden style (bold) + * \param oblique set oblique style (slanted, italic) * \param width width of the generated bitmap, this value is set by this function * \param height height of the generated bitmap, this value is set by this function * \param pitch pitch of the generated bitmap (+ or - the number of bytes per row), this value is set by this function */ - uint8 *getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex); + uint8 *getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex); /** returns the width and height of a character using a specific size and * diff --git a/code/nel/include/nel/3d/font_manager.h b/code/nel/include/nel/3d/font_manager.h index 41bb935e5..26ea02ce0 100644 --- a/code/nel/include/nel/3d/font_manager.h +++ b/code/nel/include/nel/3d/font_manager.h @@ -102,6 +102,8 @@ public: * \param fontGen font generator * \param color primitive blocks color * \param fontSize font size + * \param embolden font style bold + * \param oblique font style slanted (italic) * \param desc display descriptor (screen size, font ratio) * \param output computed string * \param keep800x600Ratio true if you want that CFontManager look at Driver window size, and resize fontSize so it keeps same size... @@ -110,6 +112,8 @@ public: CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString& output, bool keep800x600Ratio= true); @@ -121,6 +125,8 @@ public: CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString &output, bool keep800x600Ratio= true); @@ -132,6 +138,8 @@ public: CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString &output, bool keep800x600Ratio= true); diff --git a/code/nel/include/nel/3d/text_context.h b/code/nel/include/nel/3d/text_context.h index 8cf7ad7f0..156ea9f79 100644 --- a/code/nel/include/nel/3d/text_context.h +++ b/code/nel/include/nel/3d/text_context.h @@ -74,6 +74,10 @@ public: void setFontSize (uint32 fontSize) { _FontSize = fontSize; } + void setEmbolden (bool b) { _Embolden = b; } + + void setOblique (bool b) { _Oblique = b; } + void setHotSpot (CComputedString::THotSpot hotSpot) { _HotSpot = hotSpot; } void setScaleX (float scaleX) { _ScaleX = scaleX; } @@ -101,6 +105,10 @@ public: uint32 getFontSize () const { return _FontSize; } + bool getEmbolden () const { return _Embolden; } + + bool getOblique () const { return _Oblique; } + CComputedString::THotSpot getHotSpot() const { return _HotSpot; } float getScaleX() const { return _ScaleX; } @@ -240,7 +248,7 @@ public: nlassert(_FontGen); // compute the string just one time - _FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); + _FontManager->computeString (ucstr, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, _TempString, _Keep800x600Ratio); // draw shaded if (_Shaded) @@ -279,7 +287,7 @@ public: // compute the string just one time char *str; NLMISC_CONVERT_VARGS (str, format, NLMISC::MaxCStringSize); - _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, _TempString, _Keep800x600Ratio); + _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, _TempString, _Keep800x600Ratio); // draw shaded if (_Shaded) @@ -334,7 +342,7 @@ public: */ void computeString (const std::string& s, CComputedString& output) { - _FontManager->computeString (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio); + _FontManager->computeString (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio); } /** @@ -345,12 +353,12 @@ public: */ void computeString (const ucstring& s, CComputedString& output) { - _FontManager->computeString (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio); + _FontManager->computeString (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio); } void computeStringInfo (const ucstring& s, CComputedString& output) { - _FontManager->computeStringInfo (s, _FontGen, _Color, _FontSize, _Driver, output, _Keep800x600Ratio); + _FontManager->computeStringInfo (s, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, output, _Keep800x600Ratio); } /// Debug : write to the disk the texture cache @@ -381,6 +389,10 @@ private: /// Font size; uint32 _FontSize; + bool _Embolden; + + bool _Oblique; + /// Current text color NLMISC::CRGBA _Color; diff --git a/code/nel/include/nel/3d/text_context_user.h b/code/nel/include/nel/3d/text_context_user.h index 8e14dc878..b05238dbf 100644 --- a/code/nel/include/nel/3d/text_context_user.h +++ b/code/nel/include/nel/3d/text_context_user.h @@ -66,6 +66,10 @@ public: void setColor(NLMISC::CRGBA color); void setFontSize(uint32 fontSize); uint32 getFontSize() const; + void setEmbolden(bool b); + bool getEmbolden() const; + void setOblique(bool b); + bool getOblique() const; void setHotSpot(THotSpot hotSpot); THotSpot getHotSpot() const; void setScaleX(float scaleX); diff --git a/code/nel/include/nel/3d/texture_font.h b/code/nel/include/nel/3d/texture_font.h index 98e94c82f..3aeb77b65 100644 --- a/code/nel/include/nel/3d/texture_font.h +++ b/code/nel/include/nel/3d/texture_font.h @@ -43,6 +43,8 @@ public: ucchar Char; CFontGenerator *FontGenerator; sint Size; + bool Embolden; + bool Oblique; // The less recently used infos @@ -66,6 +68,8 @@ public: ucchar Char; CFontGenerator *FontGenerator; sint Size; + bool Embolden; + bool Oblique; uint32 getVal(); //bool operator < (const SLetterKey&k) const; diff --git a/code/nel/include/nel/3d/u_text_context.h b/code/nel/include/nel/3d/u_text_context.h index 1056d3839..0aa9ea2f9 100644 --- a/code/nel/include/nel/3d/u_text_context.h +++ b/code/nel/include/nel/3d/u_text_context.h @@ -137,6 +137,24 @@ public: * \return the font size */ virtual uint32 getFontSize () const = 0; + /** + * set embolden (bold) state + * \param embolden the embbolden state + */ + virtual void setEmbolden (bool b) = 0; + /** + * \return the embolden state + */ + virtual bool getEmbolden () const = 0; + /** + * set oblique (italic) state + * \param oblique the oblique state + */ + virtual void setOblique (bool b) = 0; + /** + * \return the oblique state + */ + virtual bool getOblique () const = 0; /** * set the hot spot * \param fonSize the font size diff --git a/code/nel/src/3d/font_generator.cpp b/code/nel/src/3d/font_generator.cpp index 0e268a0c2..3c73a0a20 100644 --- a/code/nel/src/3d/font_generator.cpp +++ b/code/nel/src/3d/font_generator.cpp @@ -31,6 +31,7 @@ using namespace std; #include #include FT_FREETYPE_H +#include FT_SYNTHESIS_H // for freetype 2.0 #ifdef FTERRORS_H @@ -171,7 +172,7 @@ void CFontGenerator::getSizes (ucchar c, uint32 size, uint32 &width, uint32 &hei height = _Face->glyph->metrics.height >> 6; } -uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex) +uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex) { FT_Error error; @@ -209,6 +210,16 @@ uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 & return NULL; } + if (embolden) + { + FT_GlyphSlot_Embolden(_Face->glyph); + } + + if (oblique) + { + FT_GlyphSlot_Oblique(_Face->glyph); + } + // convert to an anti-aliased bitmap error = FT_Render_Glyph (_Face->glyph, ft_render_mode_normal); if (error) @@ -389,7 +400,7 @@ void CFontGenerator::getSizes (ucchar c, uint32 size, uint32 &width, uint32 &hei HFONT hFont = NULL; uint32 CurrentFontSize = 0; -uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex) +uint8 *CFontGenerator::getBitmap (ucchar c, uint32 size, bool embolden, bool oblique, uint32 &width, uint32 &height, uint32 &pitch, sint32 &left, sint32 &top, sint32 &advx, uint32 &glyphIndex) { /* FT_Error error; diff --git a/code/nel/src/3d/font_manager.cpp b/code/nel/src/3d/font_manager.cpp index c589e934a..45a097b3b 100644 --- a/code/nel/src/3d/font_manager.cpp +++ b/code/nel/src/3d/font_manager.cpp @@ -64,6 +64,8 @@ void CFontManager::computeString (const std::string &s, CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString &output, bool keep800x600Ratio) @@ -71,7 +73,7 @@ void CFontManager::computeString (const std::string &s, // static to avoid reallocation static ucstring ucs; ucs= s; - computeString(ucs, fontGen, color, fontSize, driver, output, keep800x600Ratio); + computeString(ucs, fontGen, color, fontSize, embolden, oblique, driver, output, keep800x600Ratio); } @@ -80,6 +82,8 @@ void CFontManager::computeString (const ucstring &s, CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString &output, bool keep800x600Ratio) @@ -147,6 +151,8 @@ void CFontManager::computeString (const ucstring &s, k.Char = s[i]; k.FontGenerator = fontGen; k.Size = fontSize; + k.Embolden = embolden; + k.Oblique = oblique; CTextureFont::SLetterInfo *pLI = pTexFont->getLetterInfo (k); if(pLI != NULL) { @@ -227,6 +233,8 @@ void CFontManager::computeStringInfo ( const ucstring &s, CFontGenerator *fontGen, const NLMISC::CRGBA &color, uint32 fontSize, + bool embolden, + bool oblique, IDriver *driver, CComputedString &output, bool keep800x600Ratio ) @@ -259,6 +267,8 @@ void CFontManager::computeStringInfo ( const ucstring &s, k.Char = s[i]; k.FontGenerator = fontGen; k.Size = fontSize; + k.Embolden = embolden; + k.Oblique = oblique; pLI = pTexFont->getLetterInfo (k); if(pLI != NULL) { diff --git a/code/nel/src/3d/ps_util.cpp b/code/nel/src/3d/ps_util.cpp index 84e8c096a..a09108ed5 100644 --- a/code/nel/src/3d/ps_util.cpp +++ b/code/nel/src/3d/ps_util.cpp @@ -277,6 +277,8 @@ void CPSUtil::print(IDriver *driver, const std::string &text, CFontGenerator &fg &fg, col, 16, + false, + false, driver, cptedString); diff --git a/code/nel/src/3d/text_context.cpp b/code/nel/src/3d/text_context.cpp index 456ab77a6..1cca5145a 100644 --- a/code/nel/src/3d/text_context.cpp +++ b/code/nel/src/3d/text_context.cpp @@ -31,6 +31,8 @@ CTextContext::CTextContext() _FontGen = NULL; _FontSize = 12; + _Embolden = false; + _Oblique = false; _Color = NLMISC::CRGBA(0,0,0); @@ -81,7 +83,7 @@ uint32 CTextContext::textPush (const char *format, ...) // compute the string. uint32 index = _CacheFreePlaces[_CacheNbFreePlaces-1]; CComputedString &strToFill = _CacheStrings[index]; - _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Driver, strToFill, _Keep800x600Ratio); + _FontManager->computeString (str, _FontGen, _Color, _FontSize, _Embolden, _Oblique, _Driver, strToFill, _Keep800x600Ratio); _CacheNbFreePlaces--; @@ -109,7 +111,7 @@ uint32 CTextContext::textPush (const ucstring &str) nlassert (index < _CacheStrings.size()); CComputedString &strToFill = _CacheStrings[index]; _FontManager->computeString (str, _FontGen, _Color - , _FontSize, _Driver, strToFill, _Keep800x600Ratio); + , _FontSize, _Embolden, _Oblique, _Driver, strToFill, _Keep800x600Ratio); _CacheNbFreePlaces--; diff --git a/code/nel/src/3d/text_context_user.cpp b/code/nel/src/3d/text_context_user.cpp index 6ee880d91..441d463f5 100644 --- a/code/nel/src/3d/text_context_user.cpp +++ b/code/nel/src/3d/text_context_user.cpp @@ -100,6 +100,30 @@ uint32 CTextContextUser::getFontSize() const return _TextContext.getFontSize(); } +void CTextContextUser::setEmbolden(bool b) +{ + H_AUTO2; + + _TextContext.setEmbolden(b); +} +bool CTextContextUser::getEmbolden() const +{ + H_AUTO2; + + return _TextContext.getEmbolden(); +} +void CTextContextUser::setOblique(bool b) +{ + H_AUTO2; + + _TextContext.setOblique(b); +} +bool CTextContextUser::getOblique() const +{ + H_AUTO2; + + return _TextContext.getOblique(); +} void CTextContextUser::setHotSpot(THotSpot hotSpot) { H_AUTO2; diff --git a/code/nel/src/3d/texture_font.cpp b/code/nel/src/3d/texture_font.cpp index f27705494..4e9e3a0a4 100644 --- a/code/nel/src/3d/texture_font.cpp +++ b/code/nel/src/3d/texture_font.cpp @@ -47,11 +47,14 @@ const int NbLine[TEXTUREFONT_NBCATEGORY] = { 4, 6, 4, 1 }; // Based on textsize // --------------------------------------------------------------------------- inline uint32 CTextureFont::SLetterKey::getVal() { - + // this limits Size to 6bits + // Large sizes already render wrong when many + // different glyphs are used due to limited texture atlas + uint8 eb = ((uint)Embolden) + ((uint)Oblique << 1); if (FontGenerator == NULL) - return Char + ((Size&255)<<16); + return Char + ((Size&255)<<16) + (eb << 22); else - return Char + ((Size&255)<<16) + ((FontGenerator->getUID()&0xFF)<<24); + return Char + ((Size&255)<<16) + (eb << 22) + ((FontGenerator->getUID()&0xFF)<<24); } // --------------------------------------------------------------------------- @@ -86,6 +89,8 @@ CTextureFont::CTextureFont() rLetter.Char = 0xffff; rLetter.FontGenerator = NULL; rLetter.Size= 0; + rLetter.Embolden = false; + rLetter.Oblique = false; // The less recently used infos if (j < Letters[i].size()-1) @@ -164,7 +169,7 @@ void CTextureFont::rebuildLetter (sint cat, sint x, sint y) sint posy = catTopY + y * Categories[cat]; uint32 pitch = 0; - uint8 *bitmap = rLetter.FontGenerator->getBitmap ( rLetter.Char, rLetter.Size, + uint8 *bitmap = rLetter.FontGenerator->getBitmap ( rLetter.Char, rLetter.Size, rLetter.Embolden, rLetter.Oblique, rLetter.CharWidth, rLetter.CharHeight, pitch, rLetter.Left, rLetter.Top, rLetter.AdvX, rLetter.GlyphIndex ); @@ -303,7 +308,7 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k) // \todo mat : Temp !!! Try to use freetype cache uint32 nPitch, nGlyphIndex; sint32 nLeft, nTop, nAdvX; - k.FontGenerator->getBitmap (k.Char, k.Size, width, height, nPitch, nLeft, nTop, + k.FontGenerator->getBitmap (k.Char, k.Size, k.Embolden, k.Oblique, width, height, nPitch, nLeft, nTop, nAdvX, nGlyphIndex ); // Add 1 pixel space for black border to get correct category @@ -323,6 +328,8 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k) k2.Char = Back[cat]->Char; k2.FontGenerator = Back[cat]->FontGenerator; k2.Size = Back[cat]->Size; + k2.Embolden = Back[cat]->Embolden; + k2.Oblique = Back[cat]->Oblique; itAccel = Accel.find (k2.getVal()); if (itAccel != Accel.end()) @@ -336,6 +343,8 @@ CTextureFont::SLetterInfo* CTextureFont::getLetterInfo (SLetterKey& k) Back[cat]->Char = k.Char; Back[cat]->FontGenerator = k.FontGenerator; Back[cat]->Size = k.Size; + Back[cat]->Embolden = k.Embolden; + Back[cat]->Oblique = k.Oblique; Back[cat]->CharWidth = width; Back[cat]->CharHeight = height; Back[cat]->Top = nTop; From 55672485c97cb67d90319718fbfcdc971da27260 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 29 Mar 2015 18:24:16 +0300 Subject: [PATCH 2/3] Add embolden, oblique, underline, strikethrough styles to CViewText --HG-- branch : develop --- code/nel/include/nel/gui/view_text.h | 9 ++ code/nel/src/gui/view_text.cpp | 121 ++++++++++++++++++++++++++- 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index d4377f38e..35069a9ea 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -81,6 +81,8 @@ namespace NLGUI void setText (const ucstring &text); void setFontSize (sint nFontSize); + void setEmbolden (bool nEmbolden); + void setOblique (bool nOblique); void setColor (const NLMISC::CRGBA &color); void setShadow (bool bShadow); void setShadowOutline (bool bShadowOutline); @@ -101,6 +103,8 @@ namespace NLGUI ucstring getText() const { return _Text; } sint getFontSize() const; + bool getEmbolden() { return _Embolden; } + bool getOblique() { return _Oblique; } NLMISC::CRGBA getColor() { return _Color; } bool getShadow() { return _Shadow; } bool getShadowOutline() { return _ShadowOutline; } @@ -125,6 +129,8 @@ namespace NLGUI uint getLastLineW () const; void setUnderlined (bool underlined) { _Underlined = underlined; } bool getUnderlined () const { return _Underlined; } + void setStrikeThrough (bool linethrough) { _StrikeThrough = linethrough; } + bool getStrikeThrough () const { return _StrikeThrough; } // true if the viewText is a single line clamped. bool isSingleLineTextClamped() const {return _SingleLineTextClamped;} @@ -220,6 +226,8 @@ namespace NLGUI NL3D::UTextContext::CStringInfo _Info; /// the font size sint _FontSize; + bool _Embolden; + bool _Oblique; // width of the font in pixel. Just a Hint for tabing format (computed with '_') uint _FontWidth; // height of the font in pixel. @@ -374,6 +382,7 @@ namespace NLGUI bool _TextSelection : 1; bool _InvalidTextContext : 1; bool _Underlined : 1; + bool _StrikeThrough : 1; bool _ContinuousUpdate : 1; bool _Setuped : 1; diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index db069a29d..0e3b420a0 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -44,6 +44,7 @@ namespace NLGUI { _CaseMode = CaseNormal; _Underlined = false; + _StrikeThrough = false; _ContinuousUpdate = false; _Active = true; _X = 0; @@ -58,6 +59,8 @@ namespace NLGUI _FontSize = 12 + CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32(); + _Embolden = false; + _Oblique = false; _Color = CRGBA(255,255,255,255); _Shadow = false; _ShadowOutline = false; @@ -157,6 +160,10 @@ namespace NLGUI _PosRef = vt._PosRef; _FontSize = vt._FontSize; + _Embolden = vt._Embolden; + _Oblique = vt._Oblique; + _Underlined = vt._Underlined; + _StrikeThrough = vt._StrikeThrough; _Color = vt._Color; _Shadow = vt._Shadow; _ShadowOutline = vt._ShadowOutline; @@ -221,6 +228,21 @@ namespace NLGUI ); } else + if( name == "fontweight" ) + { + if (_Embolden) + return "bold"; + + return "normal"; + } + if( name == "fontstyle" ) + { + if (_Oblique) + return "oblique"; + + return "normal"; + } + else if( name == "shadow" ) { return toString( _Shadow ); @@ -286,6 +308,11 @@ namespace NLGUI return toString( _Underlined ); } else + if( name == "strikthrough" ) + { + return toString( _StrikeThrough ); + } + else if( name == "case_mode" ) { return toString( uint32( _CaseMode ) ); @@ -358,6 +385,20 @@ namespace NLGUI return true; } else + if( name == "fontweight" ) + { + if (value == "bold") + _Embolden = true; + + return true; + } + if( name == "fontstyle" ) + { + if( value == "oblique" ) + _Oblique = true; + return true; + } + else if( name == "shadow" ) { bool b; @@ -444,6 +485,14 @@ namespace NLGUI return true; } else + if( name == "strikethrough" ) + { + bool b; + if( fromString( value, b ) ) + _StrikeThrough = b; + return true; + } + else if( name == "case_mode" ) { uint32 i; @@ -533,6 +582,16 @@ namespace NLGUI _FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32() ).c_str() ); + std::string fontweight("normal"); + if (_Embolden) + fontweight = "bold"; + xmlSetProp( node, BAD_CAST "fontweight", BAD_CAST fontweight.c_str() ); + + std::string fontstyle("normal"); + if (_Oblique) + fontstyle = "oblique"; + xmlSetProp( node, BAD_CAST "fontstyle", BAD_CAST fontstyle.c_str() ); + xmlSetProp( node, BAD_CAST "shadow", BAD_CAST toString( _Shadow ).c_str() ); xmlSetProp( node, BAD_CAST "shadow_outline", BAD_CAST toString( _ShadowOutline ).c_str() ); xmlSetProp( node, BAD_CAST "shadow_color", BAD_CAST toString( _ShadowColor ).c_str() ); @@ -561,6 +620,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "multi_line_maxw_only", BAD_CAST toString( _MultiLineMaxWOnly ).c_str() ); xmlSetProp( node, BAD_CAST "multi_max_line", BAD_CAST toString( _MultiMaxLine ).c_str() ); xmlSetProp( node, BAD_CAST "underlined", BAD_CAST toString( _Underlined ).c_str() ); + xmlSetProp( node, BAD_CAST "strikethrough", BAD_CAST toString( _StrikeThrough ).c_str() ); xmlSetProp( node, BAD_CAST "case_mode", BAD_CAST toString( uint32( _CaseMode ) ).c_str() ); xmlSetProp( node, BAD_CAST "over_extend_view_text", BAD_CAST toString( _OverExtendViewText ).c_str() ); xmlSetProp( node, BAD_CAST "over_extend_parent_rect", @@ -614,6 +674,22 @@ namespace NLGUI _FontSize += CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32(); } + prop = (char*) xmlGetProp( cur, (xmlChar*)"fontweight" ); + _Embolden = false; + if (prop) + { + if (nlstricmp("bold", (const char*)prop) == 0) _Embolden = true; + else nlwarning(" bad fontweight '%s'", (const char *)prop); + } + + prop = (char*) xmlGetProp( cur, (xmlChar*)"fontstyle" ); + _Oblique = false; + if (prop) + { + if (nlstricmp("oblique", (const char *) prop) == 0) _Oblique = true; + else nlwarning(" bad fontstyle '%s'", (const char *)prop); + } + prop = (char*) xmlGetProp( cur, (xmlChar*)"shadow" ); _Shadow = false; if (prop) @@ -668,6 +744,11 @@ namespace NLGUI if (prop) _Underlined = convertBool(prop); + prop = (char*) xmlGetProp( cur, (xmlChar*)"strikethrough" ); + _StrikeThrough = false; + if (prop) + _StrikeThrough = convertBool(prop); + prop = (char*) xmlGetProp( cur, (xmlChar*)"case_mode" ); _CaseMode = CaseNormal; if (prop) @@ -887,6 +968,8 @@ namespace NLGUI TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); float y = (float)(_YReal) * ooh; // y is expressed in scree, coordinates [0..1] //y += _LinesInfos[_LinesInfos.size()-1].StringLine / h; @@ -953,7 +1036,7 @@ namespace NLGUI // skip spaces before current word float firstSpace = currWord.NumSpaces * currLine.getSpaceWidth(); sint line_width = 0; - if (_Underlined) + if (_Underlined || _StrikeThrough) { line_width = (sint)floorf(currLine.getWidthWithoutSpaces() + currLine.getSpaceWidth()); line_width -= (sint)floorf(firstSpace); @@ -971,6 +1054,9 @@ namespace NLGUI if (_Underlined) rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1, 0, false, rVR.getBlankTextureId(), col); + if (_StrikeThrough) + rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1, 0, false, rVR.getBlankTextureId(), col); + // skip word px += currWord.Info.StringWidth; } @@ -1002,6 +1088,8 @@ namespace NLGUI TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); if(_LetterColors!=NULL && !TextContext->isSameLetterColors(_LetterColors, _Index)) @@ -1032,6 +1120,9 @@ namespace NLGUI if (_Underlined) rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); + if (_StrikeThrough) + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+(_FontLegHeight/2), _WReal, 1, 0, false, rVR.getBlankTextureId(), col); + // reset selection if(_TextSelection) TextContext->resetStringSelection(_Index); @@ -1154,6 +1245,22 @@ namespace NLGUI return _FontSize - CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont).getValSInt32(); } + // *************************************************************************** + void CViewText::setEmbolden (bool embolden) + { + _Embolden = embolden; + computeFontSize (); + invalidateContent(); + } + + // *************************************************************************** + void CViewText::setOblique (bool oblique) + { + _Oblique = oblique; + computeFontSize (); + invalidateContent(); + } + // *************************************************************************** void CViewText::setColor(const NLMISC::CRGBA & color) { @@ -1679,6 +1786,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); // default state _SingleLineTextClamped= false; @@ -2000,6 +2109,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); // CViewRenderer &rVR = *CViewRenderer::getInstance(); height = getFontHeight(); // @@ -2132,6 +2243,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); // find the line where the character is // CViewRenderer &rVR = *CViewRenderer::getInstance(); uint charPos = 0; @@ -2407,6 +2520,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); TCharPos linePos = 0; while (linePos < _Text.length()) @@ -2492,6 +2607,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); // Current position in text TCharPos currPos = 0; @@ -2544,6 +2661,8 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setFontSize (_FontSize); + TextContext->setEmbolden (_Embolden); + TextContext->setOblique (_Oblique); // Letter size UTextContext::CStringInfo si = TextContext->getStringInfo(ucstring("|")); // for now we can't now that directly from UTextContext From eeb881d49e24921910115b23ca958384a263458d Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 29 Mar 2015 18:24:19 +0300 Subject: [PATCH 3/3] Add span tag and bold, italic, underline, strikethrough styles to CGroupHTML --HG-- branch : develop --- 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);