From 976b5d568911d2a4b259c7ef5a374a24c07b29f3 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 24 Jul 2016 16:05:04 +0300 Subject: [PATCH] Changed: Support custom font --- code/nel/include/nel/gui/view_text.h | 10 ++- code/nel/src/gui/view_text.cpp | 101 +++++++++++++++++---------- 2 files changed, 71 insertions(+), 40 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index 95507ffe3..a00932667 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -80,6 +80,7 @@ namespace NLGUI /// Set void setText (const ucstring &text); + void setFontName (const std::string &name); void setFontSize (sint nFontSize); void setEmbolden (bool nEmbolden); void setOblique (bool nOblique); @@ -104,6 +105,7 @@ namespace NLGUI ucstring getText() const { return _Text; } sint getFontSize() const; + std::string getFontName() const { return _FontName; } bool getEmbolden() { return _Embolden; } bool getOblique() { return _Oblique; } NLMISC::CRGBA getColor() { return _Color; } @@ -227,6 +229,8 @@ namespace NLGUI uint _Index; /// info on the computed String associated to this text control NL3D::UTextContext::CStringInfo _Info; + /// Font name to get TextContext + std::string _FontName; /// the font size sint _FontSize; bool _Embolden; @@ -320,7 +324,7 @@ namespace NLGUI CFormatInfo Format; public: // build from a string, using the current text context - void build(const ucstring &text, uint numSpaces= 0); + void build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces= 0); }; typedef std::vector TWordVect; @@ -331,9 +335,9 @@ namespace NLGUI // ctor CLine(); // Clear the line & remove text contexts - void clear(); + void clear(NL3D::UTextContext &textContext); // Add a new word (and its context) in the line + a number of spaces to append at the end of the line - void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth); + void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth, NL3D::UTextContext &textContext); void addWord(const CWord &word, uint fontWidth); uint getNumWords() const { return (uint)_Words.size(); } CWord &getWord(uint index) { return _Words[index]; } diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 8c2ca96d3..c88dd8173 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -61,6 +61,7 @@ namespace NLGUI _FontSize = 12 + CWidgetManager::getInstance()->getSystemOption( CWidgetManager::OptionAddCoefFont ).getValSInt32(); + _FontName.clear(); _Embolden = false; _Oblique = false; _Color = CRGBA(255,255,255,255); @@ -134,7 +135,7 @@ namespace NLGUI CViewText::~CViewText() { if (_Index != 0xFFFFFFFF) - CViewRenderer::getTextContext()->erase (_Index); + CViewRenderer::getTextContext(_FontName)->erase (_Index); clearLines(); if (!_Setuped) @@ -148,7 +149,7 @@ namespace NLGUI CViewText &CViewText::operator=(const CViewText &vt) { if (_Index != 0xFFFFFFFF) - CViewRenderer::getTextContext()->erase (_Index); + CViewRenderer::getTextContext(_FontName)->erase (_Index); // Create database entries _Active = vt._Active; @@ -958,7 +959,7 @@ namespace NLGUI return; rVR.getScreenOOSize (oow, ooh); - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); // *** get current color @@ -983,8 +984,6 @@ namespace NLGUI { if (_Lines.size() == 0) return; - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); - TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); @@ -1260,6 +1259,24 @@ namespace NLGUI _FormatTags.clear(); } + // *************************************************************************** + void CViewText::setFontName(const std::string &name) + { + if (_FontName == name) + return; + + if (_FontName.length() > 0) + { + if (_Index != 0xFFFFFFFF) + CViewRenderer::getTextContext(_FontName)->erase (_Index); + clearLines(); + } + + _FontName = name; + computeFontSize (); + invalidateContent(); + } + // *************************************************************************** void CViewText::setFontSize (sint nFontSize) { @@ -1403,6 +1420,7 @@ namespace NLGUI // *************************************************************************** void CViewText::flushWordInLine(ucstring &ucCurrentWord, bool &linePushed, const CFormatInfo &wordFormat) { + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); // create a new line? if(!linePushed) { @@ -1410,7 +1428,7 @@ namespace NLGUI linePushed= true; } // Append to the last line - _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth); + _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth, *TextContext); // reset the word ucCurrentWord = ucstring(""); } @@ -1446,7 +1464,7 @@ namespace NLGUI rWidthCurrentLine= max(rWidthCurrentLine, (float)wordFormat.TabX*_FontWidth); } - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); // Parse the letter { @@ -1492,6 +1510,7 @@ namespace NLGUI // *************************************************************************** void CViewText::addDontClipWordLine(std::vector &currLine) { + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); // create a new line _Lines.push_back(TLineSPtr(new CLine)); @@ -1506,7 +1525,7 @@ namespace NLGUI if(currLine[i].Format!=lineWordFormat) { // add the current lineWord to the line. - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); // get new lineWordFormat lineWordFormat= currLine[i].Format; // and clear @@ -1521,7 +1540,7 @@ namespace NLGUI } if(!lineWord.empty()) - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); // clear currLine.clear(); @@ -1531,6 +1550,7 @@ namespace NLGUI // *************************************************************************** void CViewText::updateTextContextMultiLineJustified(uint nMaxWidth, bool expandSpaces) { + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); UTextContext::CStringInfo si; // TCharPos currPos = 0; @@ -1624,7 +1644,7 @@ namespace NLGUI // Get the word value. wordValue = _Text.substr(spaceEnd, wordEnd - spaceEnd); // compute width of word - si = CViewRenderer::getTextContext()->getStringInfo(wordValue); + si = TextContext->getStringInfo(wordValue); // compute size of spaces/Tab + word newLineWidth = lineWidth + numSpaces * _SpaceWidth; @@ -1681,7 +1701,7 @@ namespace NLGUI { uint maxNumSpaces = std::max(1U, (uint) (nMaxWidth / _SpaceWidth)); CWord spaceWord; // a word with only spaces in it - spaceWord.build (ucstring (""), maxNumSpaces); + spaceWord.build (ucstring (""), *TextContext, maxNumSpaces); spaceWord.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); _Lines.back()->addWord(spaceWord, _FontWidth); @@ -1703,14 +1723,14 @@ namespace NLGUI for(currChar = 0; currChar < wordValue.length(); ++currChar) { oneChar = wordValue[currChar]; - si = CViewRenderer::getTextContext()->getStringInfo(oneChar); + si = TextContext->getStringInfo(oneChar); if ((uint) (px + si.StringWidth) > nMaxWidth) break; px += si.StringWidth; } currChar = std::max((uint) 1, currChar); // must fit at least one character otherwise there's an infinite loop wordValue = _Text.substr(spaceEnd, currChar); CWord word; - word.build(wordValue, numSpaces); + word.build(wordValue, *TextContext, numSpaces); word.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); float roomForSpaces = (float) nMaxWidth - word.Info.StringWidth; @@ -1745,7 +1765,7 @@ namespace NLGUI if (!wordValue.empty() || numSpaces != 0) { CWord word; - word.build(wordValue, numSpaces); + word.build(wordValue, *TextContext, numSpaces); word.Format= wordFormat; // update line width _Lines.back()->addWord(word, _FontWidth); @@ -1822,7 +1842,7 @@ namespace NLGUI // *************************************************************************** void CViewText::updateTextContext () { - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); @@ -1856,13 +1876,13 @@ namespace NLGUI { while (_Lines.size() > _MultiMaxLine) { - _Lines.back()->clear(); + _Lines.back()->clear(*TextContext); _Lines.pop_back(); } _Lines.pop_back(); CViewText::CLine *endLine = new CViewText::CLine; CViewText::CWord w; - w.build(string("...")); + w.build(string("..."), *TextContext); endLine->addWord(w, _FontWidth); _Lines.push_back(TLineSPtr(endLine)); } @@ -2150,7 +2170,7 @@ namespace NLGUI void CViewText::getCharacterPositionFromIndex(sint index, bool cursorAtPreviousLineEnd, sint &x, sint &y, sint &height) const { NLMISC::clamp(index, 0, (sint) _Text.length()); - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); @@ -2257,7 +2277,7 @@ namespace NLGUI // *************************************************************************** // Tool fct : From a word and a x coordinate, give the matching character index - static uint getCharacterIndex(const ucstring &textValue, float x) + static uint getCharacterIndex(const ucstring &textValue, float x, NL3D::UTextContext &textContext) { float px = 0.f; UTextContext::CStringInfo si; @@ -2267,7 +2287,7 @@ namespace NLGUI { // get character width singleChar[0] = textValue[i]; - si = CViewRenderer::getTextContext()->getStringInfo(singleChar); + si = textContext.getStringInfo(singleChar); px += si.StringWidth; // the character is at the i - 1 position if (px > x) @@ -2284,7 +2304,7 @@ namespace NLGUI // *************************************************************************** void CViewText::getCharacterIndexFromPosition(sint x, sint y, uint &index, bool &cursorAtPreviousLineEnd) const { - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); // setup the text context TextContext->setHotSpot (UTextContext::BottomLeft); @@ -2365,7 +2385,7 @@ namespace NLGUI else { // the coord is in the word itself - index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth)); + index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth), *TextContext); cursorAtPreviousLineEnd = false; return; } @@ -2390,7 +2410,7 @@ namespace NLGUI index = 0; return; } - index = getCharacterIndex(_Text, (float) x); + index = getCharacterIndex(_Text, (float) x, *TextContext); return; } } @@ -2428,15 +2448,16 @@ namespace NLGUI quadSize--; } // select what quad to skip - CViewRenderer::getTextContext()->setStringSelection(stringId, quadStart, quadSize); + CViewRenderer::getTextContext(_FontName)->setStringSelection(stringId, quadStart, quadSize); } // *************************************************************************** void CViewText::clearLines() { + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); for(uint k = 0; k < _Lines.size(); ++k) { - _Lines[k]->clear(); + _Lines[k]->clear(*TextContext); } _Lines.clear(); } @@ -2490,10 +2511,10 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth) + void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth, NL3D::UTextContext &textContext) { CWord word; - word.build(text, numSpaces); + word.build(text, textContext, numSpaces); word.Format= wordFormat; addWord(word, fontWidth); } @@ -2515,12 +2536,12 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CLine::clear() + void CViewText::CLine::clear(NL3D::UTextContext &textContext) { for(uint k = 0; k < _Words.size(); ++k) { if (_Words[k].Index != 0xffffffff) - CViewRenderer::getTextContext()->erase(_Words[k].Index); + textContext.erase(_Words[k].Index); } _Words.clear(); _NumChars = 0; @@ -2537,13 +2558,12 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CWord::build(const ucstring &text, uint numSpaces/*=0*/) + void CViewText::CWord::build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces) { Text = text; NumSpaces = numSpaces; - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); - Index = TextContext->textPush(text); - Info = TextContext->getStringInfo(Index); + Index = textContext.textPush(text); + Info = textContext.getStringInfo(Index); } // *************************************************************************** @@ -2564,7 +2584,7 @@ namespace NLGUI static const ucstring lineFeedStr("\n"); float maxWidth = 0; - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); @@ -2651,7 +2671,7 @@ namespace NLGUI // If we can't clip the words, return the size of the largest word else if ((_TextMode == DontClipWord) || (_TextMode == Justified)) { - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); @@ -2709,7 +2729,7 @@ namespace NLGUI // *************************************************************************** void CViewText::computeFontSize () { - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); @@ -2727,6 +2747,13 @@ namespace NLGUI // for now we can't know that directly from UTextContext UTextContext::CStringInfo si = TextContext->getStringInfo(chars); + + // font generator changes unknown glyphs to dot '.'. use fallback if it looks odd + if (_FontSize > (si.StringHeight + si.StringLine)) + { + chars.fromUtf8("|"); + si = TextContext->getStringInfo(chars); + } // add a padding of 1 pixel else the top will be truncated _FontHeight = (uint) si.StringHeight+1; _FontLegHeight = (uint) si.StringLine; @@ -3081,7 +3108,7 @@ namespace NLGUI } // convert in ULetterColors - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); ULetterColors * letterColors = TextContext->createLetterColors(); for(uint i=0; i