From cf357edcb9fff57b14aafbd6374ea78828d90b01 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 3 Jun 2016 14:24:56 +0300 Subject: [PATCH 01/25] Added: Interface auto scaling to view renderer --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_renderer.h | 15 ++++- code/nel/src/gui/view_renderer.cpp | 77 +++++++++++++++++++----- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/code/nel/include/nel/gui/view_renderer.h b/code/nel/include/nel/gui/view_renderer.h index a54708b04..c737037a1 100644 --- a/code/nel/include/nel/gui/view_renderer.h +++ b/code/nel/include/nel/gui/view_renderer.h @@ -176,6 +176,12 @@ namespace NLGUI */ void getScreenOOSize (float &oow, float &ooh); + /* + * UI scaling + */ + void setInterfaceScale(float scale, sint32 width = 0, sint32 height = 0); + float getInterfaceScale() const { return _InterfaceScale; } + /* * is the Screen minimized? */ @@ -526,6 +532,13 @@ namespace NLGUI float _OneOverScreenW, _OneOverScreenH; bool _IsMinimized; + // UI scaling + float _InterfaceScale; + float _InterfaceUserScale; + sint32 _InterfaceBaseW, _InterfaceBaseH; + sint32 _EffectiveScreenW, _EffectiveScreenH; + + void updateInterfaceScale(); //map linking a uint to a bitmap. Used to display figurs std::vector _IndexesToTextureIds; @@ -585,14 +598,12 @@ namespace NLGUI static CViewRenderer *instance; static NL3D::UDriver *driver; static NL3D::UTextContext *textcontext; - public: static NL3D::UTextContext* getTextContext(){ return textcontext; } /// Set of hw cursor images static std::set< std::string > *hwCursors; static float hwCursorScale; - }; diff --git a/code/nel/src/gui/view_renderer.cpp b/code/nel/src/gui/view_renderer.cpp index 0b4d837f3..b2d793e46 100644 --- a/code/nel/src/gui/view_renderer.cpp +++ b/code/nel/src/gui/view_renderer.cpp @@ -91,16 +91,13 @@ namespace NLGUI if(w!=0 && h!=0) { _IsMinimized= false; - _ScreenW = w; - _ScreenH = h; - if(_ScreenW>0) - _OneOverScreenW = 1.0f / (float)_ScreenW; - else - _OneOverScreenW = 1000; - if(_ScreenH>0) - _OneOverScreenH = 1.0f / (float)_ScreenH; - else - _OneOverScreenH = 1000; + if (w != _ScreenW || h != _ScreenH) + { + _ScreenW = w; + _ScreenH = h; + + updateInterfaceScale(); + } } else { @@ -109,14 +106,48 @@ namespace NLGUI } } + void CViewRenderer::updateInterfaceScale() + { + if(_ScreenW>0) + _OneOverScreenW = 1.0f / (float)_ScreenW; + else + _OneOverScreenW = 1000; + if(_ScreenH>0) + _OneOverScreenH = 1.0f / (float)_ScreenH; + else + _OneOverScreenH = 1000; + + _InterfaceScale = _InterfaceUserScale; + if (_InterfaceBaseW > 0 && _InterfaceBaseH > 0) + { + float wRatio = (float)_ScreenW / _InterfaceBaseW; + float rRatio = (float)_ScreenH / _InterfaceBaseH; + _InterfaceScale *= std::min(wRatio, rRatio); + } + + if (_InterfaceScale != 1.0f) + { + _OneOverScreenW *= _InterfaceScale; + _OneOverScreenH *= _InterfaceScale; + + _EffectiveScreenW = sint(_ScreenW / _InterfaceScale); + _EffectiveScreenH = sint(_ScreenH / _InterfaceScale); + } + else + { + _EffectiveScreenW = _ScreenW; + _EffectiveScreenH = _ScreenH; + } + } + /* * getScreenSize : get the screen window size */ void CViewRenderer::getScreenSize (uint32 &w, uint32 &h) { - w = _ScreenW; - h = _ScreenH; + w = _EffectiveScreenW; + h = _EffectiveScreenH; } /* @@ -128,6 +159,20 @@ namespace NLGUI ooh= _OneOverScreenH; } + void CViewRenderer::setInterfaceScale(float scale, sint32 width/*=0*/, sint32 height/*=0*/) + { + // prevent #div/0 + if (sint(scale*100) > 0) + _InterfaceUserScale = scale; + else + _InterfaceUserScale = 1.0f; + + _InterfaceBaseW = width; + _InterfaceBaseH = height; + + updateInterfaceScale(); + } + void CViewRenderer::setup() { _ClipX = _ClipY = 0; @@ -135,8 +180,10 @@ namespace NLGUI _ClipH = 600; _ScreenW = 800; _ScreenH = 600; - _OneOverScreenW= 1.0f / (float)_ScreenW; - _OneOverScreenH= 1.0f / (float)_ScreenH; + _InterfaceScale = 1.0f; + _InterfaceUserScale = 1.0f; + _InterfaceBaseW = 0; + _InterfaceBaseH = 0; _IsMinimized= false; _WFigurTexture= 0; _HFigurTexture= 0; @@ -152,6 +199,8 @@ namespace NLGUI _EmptyLayer[i]= true; } _BlankGlobalTexture = NULL; + + updateInterfaceScale(); } From b474f39970c7af55527f2638a2cbfe8b734bffee Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 3 Jun 2016 14:26:17 +0300 Subject: [PATCH 02/25] Added: Scaling options to client config --HG-- branch : experimental-ui-scaling --- .../data/gamedev/interfaces_v3/game_config.xml | 16 +++++++++++++++- code/ryzom/client/src/client_cfg.cpp | 6 ++++++ code/ryzom/client/src/client_cfg.h | 3 +++ code/ryzom/client/src/connection.cpp | 11 +++++++++++ code/ryzom/client/src/init.cpp | 1 + .../src/interface_v3/interface_manager.cpp | 10 ++++++++++ .../client/src/interface_v3/interface_manager.h | 3 +++ code/ryzom/client/src/main_loop_utilities.cpp | 6 +++++- 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml index 38e63cb24..001d2be1d 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml @@ -878,10 +878,17 @@ posparent="lum" x="0" y="-2" /> + @@ -3086,6 +3093,13 @@ realtime="true" widget="sbfloat" link="Gamma" /> + setInterfaceScale(ClientCfg.InterfaceScale); } @@ -290,6 +293,8 @@ void setOutGameFullScreen() */ } + // Enable auto scaling in login window + CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768); } @@ -454,6 +459,9 @@ bool connection (const string &cookie, const string &fsaddr) firstConnection = false; + // Restore user UI scaling + CViewRenderer::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale); + // Disable inputs Actions.enable(false); EditActions.enable(false); @@ -586,6 +594,9 @@ bool reconnection() InterfaceState = globalMenu(); } + // Restore user UI scaling + CViewRenderer::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale); + // Disable inputs Actions.enable(false); EditActions.enable(false); diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 7b1ca728f..8105d9351 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1316,6 +1316,7 @@ void prelogInit() CInterfaceManager::getInstance(); + CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768); // Yoyo: initialize NOW the InputHandler for Event filtering. CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance(); diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 3e2a0ba0e..802f98c70 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -475,6 +475,8 @@ CInterfaceManager::CInterfaceManager() interfaceLinkUpdater = new CInterfaceLink::CInterfaceLinkUpdater(); _ScreenW = _ScreenH = 0; _LastInGameScreenW = _LastInGameScreenH = 0; + _InterfaceScaleChanged = false; + _InterfaceScale = 1.0f; _DescTextTarget = NULL; _ConfigLoaded = false; _LogState = false; @@ -1984,6 +1986,14 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera) _CurrentPlayerCharac[i] = node ? node->getValue32() : 0; } + // update value change from ingame config window + // must update it here, right before widget manager checks it + if (_InterfaceScaleChanged) + { + CViewRenderer::getInstance()->setInterfaceScale(_InterfaceScale); + _InterfaceScaleChanged = false; + } + CWidgetManager::getInstance()->drawViews( camera ); // flush obs diff --git a/code/ryzom/client/src/interface_v3/interface_manager.h b/code/ryzom/client/src/interface_v3/interface_manager.h index 6025868e5..c5c641033 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.h +++ b/code/ryzom/client/src/interface_v3/interface_manager.h @@ -543,6 +543,7 @@ public: NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_FACTION_TYPE; void updateDesktops( uint32 newScreenW, uint32 newScreenH ); + void setInterfaceScale( float scale ) { _InterfaceScaleChanged = true; _InterfaceScale = scale; } private: @@ -581,6 +582,8 @@ private: uint32 _ScreenW, _ScreenH; // Change res detection sint32 _LastInGameScreenW, _LastInGameScreenH; // Resolution used for last InGame interface + float _InterfaceScale; + bool _InterfaceScaleChanged; // Modes CInterfaceConfig::CDesktopImage _Modes[MAX_NUM_MODES]; diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index 415764bfa..e62c033e4 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -36,6 +36,7 @@ #include "input.h" #include "sound_manager.h" #include "camera.h" +#include "interface_v3/interface_manager.h" using namespace NLMISC; using namespace NL3D; @@ -100,6 +101,9 @@ void updateFromClientCfg() Driver->forceTextureResize(1); } + if (ClientCfg.InterfaceScale != LastClientCfg.InterfaceScale) + CInterfaceManager::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale); + //--------------------------------------------------- if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) { @@ -395,4 +399,4 @@ void updateFromClientCfg() LastClientCfg = ClientCfg; } -/* end of file */ \ No newline at end of file +/* end of file */ From 8965ce50d5fa03d5b0923930874e033e60fa4131 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 3 Jun 2016 16:02:37 +0300 Subject: [PATCH 03/25] Changed: Font scaling --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_text.h | 12 ++- code/nel/src/gui/view_renderer.cpp | 19 ++++ code/nel/src/gui/view_text.cpp | 140 ++++++++++++++------------- 3 files changed, 100 insertions(+), 71 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index 95507ffe3..c814bcb7b 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -232,12 +232,14 @@ namespace NLGUI bool _Embolden; bool _Oblique; // width of the font in pixel. Just a Hint for tabing format (computed with '_') - uint _FontWidth; + float _FontWidth; // height of the font in pixel. // use getFontHeight - uint _FontHeight; - uint _FontLegHeight; + float _FontHeight; + float _FontLegHeight; float _SpaceWidth; + /// last UI scale used to calculate font size + float _Scale; /// the text color NLMISC::CRGBA _Color; /// the shadow mode @@ -333,8 +335,8 @@ namespace NLGUI // Clear the line & remove text contexts void clear(); // 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 CWord &word, uint fontWidth); + void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth); + void addWord(const CWord &word, float fontWidth); uint getNumWords() const { return (uint)_Words.size(); } CWord &getWord(uint index) { return _Words[index]; } float getSpaceWidth() const { return _SpaceWidth; } diff --git a/code/nel/src/gui/view_renderer.cpp b/code/nel/src/gui/view_renderer.cpp index b2d793e46..f8a8152b9 100644 --- a/code/nel/src/gui/view_renderer.cpp +++ b/code/nel/src/gui/view_renderer.cpp @@ -1938,6 +1938,25 @@ namespace NLGUI void CViewRenderer::drawText (sint layerId, float x, float y, uint wordIndex, float xmin, float ymin, float xmax, float ymax, UTextContext &textContext) { + xmin = xmin * _OneOverScreenW; + ymin = ymin * _OneOverScreenH; + xmax = xmax * _OneOverScreenW; + ymax = ymax * _OneOverScreenH; + + if (_InterfaceScale != 1.0f && _InterfaceScale != 2.0f) + { + // align to screen pixel + x *= _OneOverScreenW * _ScreenW; + y *= _OneOverScreenH * _ScreenH; + x = floorf(x) * 1.f / (float) _ScreenW; + y = floorf(y) * 1.f / (float) _ScreenH; + } + else + { + x = floorf(x) * _OneOverScreenW; + y = floorf(y) * _OneOverScreenH; + } + if (_WorldSpaceTransformation) { textContext.printClipAtUnProjected(*getStringRenderBuffer(layerId), _CameraFrustum, _WorldSpaceMatrix, x, y, _CurrentZ, wordIndex, xmin, ymin, xmax, ymax); diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 8c2ca96d3..6a66bdf74 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -79,6 +79,7 @@ namespace NLGUI _MultiMaxLine = 0; _Index = 0xFFFFFFFF; + _Scale = 1.0f; _FontWidth= 0; _FontHeight = 0; _FontLegHeight = 0; @@ -877,12 +878,13 @@ namespace NLGUI // *************************************************************************** sint CViewText::getCurrentMultiLineMaxW() const { + sint maxw = ceilf(_LineMaxW * _Scale); if(_MultiLineMaxWOnly) - return _LineMaxW; + return maxw; else { sint parentWidth = std::min(_Parent->getMaxWReal(), _Parent->getWReal()); - return std::min(parentWidth-(sint)(_XReal-_Parent->getXReal()), (sint)_LineMaxW); + return std::min(parentWidth-(sint)(_XReal-_Parent->getXReal()), maxw); } } @@ -890,6 +892,9 @@ namespace NLGUI // *************************************************************************** void CViewText::checkCoords () { + if (_Scale != CViewRenderer::getInstance()->getInterfaceScale()) + invalidateContent(); + if ((_MultiLine)&&(_Parent != NULL)) { // If never setuped, and if text is not empty @@ -943,6 +948,8 @@ namespace NLGUI CViewRenderer &rVR = *CViewRenderer::getInstance(); + //rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(64,64,64,255)); + // *** Out Of Clip? sint32 ClipX, ClipY, ClipW, ClipH; rVR.getClipWindow (ClipX, ClipY, ClipW, ClipH); @@ -951,12 +958,8 @@ namespace NLGUI return; // *** Screen Minimized? - uint32 w, h; - float oow, ooh; - rVR.getScreenSize (w, h); if (rVR.isMinimized()) return; - rVR.getScreenOOSize (oow, ooh); NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); @@ -989,22 +992,22 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); - float y = (float)(_YReal) * ooh; // y is expressed in scree, coordinates [0..1] + float y = _YReal; //y += _LinesInfos[_LinesInfos.size()-1].StringLine / h; // Y is the base line of the string, so it must be grown up. - y += (float)_FontLegHeight * ooh; + y += _FontLegHeight; - sint y_line = _YReal+_FontLegHeight-2; + sint y_line = _YReal+_FontLegHeight-2.0f*_Scale; if (_MultiMinLine > _Lines.size()) { uint dy = getMultiMinOffsetY(); - y += dy * ooh; + y += dy; y_line += dy; } @@ -1076,8 +1079,7 @@ namespace NLGUI px= max(px, (float)(_XReal + currWord.Format.TabX*_FontWidth)); // draw. We take floorf px to avoid filtering of letters that are not located on a pixel boundary - rVR.drawText (_RenderLayer, floorf(px) * oow, y, currWord.Index, (float)ClipX * oow, (float)ClipY * ooh, - (float)(ClipX+ClipW) * oow, (float)(ClipY+ClipH) * ooh, *TextContext); + rVR.drawText (_RenderLayer, px, y, currWord.Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); // Draw a line if (_Underlined) @@ -1090,7 +1092,7 @@ namespace NLGUI px += currWord.Info.StringWidth; } // go one line up - y += (_FontHeight + _MultiLineSpace) * ooh; + y += (_FontHeight + _MultiLineSpace); y_line += _FontHeight+_MultiLineSpace; } @@ -1116,22 +1118,19 @@ namespace NLGUI TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); TextContext->setShadeColor (shcol); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); - if(_LetterColors!=NULL && !TextContext->isSameLetterColors(_LetterColors, _Index)) { TextContext->setLetterColors(_LetterColors, _Index); } - - float x = (float)(_XReal) * oow; - float y = (float)(_YReal) * ooh; + float y = _YReal; // Y is the base line of the string, so it must be grown up. - y += (float)_FontLegHeight * ooh; + y += _FontLegHeight; // special selection code if(_TextSelection) @@ -1142,12 +1141,11 @@ namespace NLGUI TextContext->setStringColor(_Index, col); // draw - rVR.drawText (_RenderLayer, x, y, _Index, (float)ClipX * oow, (float)ClipY * ooh, - (float)(ClipX+ClipW) * oow, (float)(ClipY+ClipH) * ooh, *TextContext); + rVR.drawText (_RenderLayer, _XReal, y, _Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2.0f*_Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); if (_StrikeThrough) rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+(_FontLegHeight/2), _WReal, 1, 0, false, rVR.getBlankTextureId(), col); @@ -1336,7 +1334,7 @@ namespace NLGUI sint32 value; if(CLuaIHM::popSINT32(ls, value)) { - setLineMaxW(value); + setLineMaxW(ceilf(value / _Scale)); } return 0; } @@ -1463,7 +1461,7 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth); + rWidthLetter = (si.StringWidth / _Scale); if ((rWidthCurrentLine + rWidthLetter) > nMaxWidth) { flushWordInLine(ucCurrentWord, linePushed, wordFormat); @@ -1538,7 +1536,7 @@ namespace NLGUI static const ucstring spaceStr(" "); // precLineWidth valid only id precedent line is part of same paragraph. float precLineWidth= 0; - float lineWidth = (float)_FirstLineX; // width of the current line + float lineWidth = (float)_FirstLineX * _Scale; // width of the current line uint numWordsInLine = 0; // number of words in the current line bool isParagraphStart = true; // A paragraph is a group of characters between 2 \n bool lineFeed; @@ -1554,7 +1552,7 @@ namespace NLGUI TCharPos spaceEnd; TCharPos wordEnd; uint numSpaces; - float newLineWidth; + float newLineWidth = 0; breakLine = false; // if (_Text[currPos] == (ucchar) '\n') @@ -1629,7 +1627,7 @@ namespace NLGUI // compute size of spaces/Tab + word newLineWidth = lineWidth + numSpaces * _SpaceWidth; newLineWidth = max(newLineWidth, (float)wordFormat.TabX*_FontWidth); - newLineWidth+= si.StringWidth; + newLineWidth+= si.StringWidth / _Scale; } // // Does the word go beyond the end of line ? @@ -1704,8 +1702,8 @@ namespace NLGUI { oneChar = wordValue[currChar]; si = CViewRenderer::getTextContext()->getStringInfo(oneChar); - if ((uint) (px + si.StringWidth) > nMaxWidth) break; - px += si.StringWidth; + if ((uint) (px + si.StringWidth / _Scale) > nMaxWidth) break; + px += si.StringWidth / _Scale; } currChar = std::max((uint) 1, currChar); // must fit at least one character otherwise there's an infinite loop wordValue = _Text.substr(spaceEnd, currChar); @@ -1822,12 +1820,15 @@ namespace NLGUI // *************************************************************************** void CViewText::updateTextContext () { + if (_Scale != CViewRenderer::getInstance()->getInterfaceScale()) + computeFontSize(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); @@ -1836,7 +1837,7 @@ namespace NLGUI if ((_MultiLine)&&(_Parent != NULL)) { - sint nMaxWidth = getCurrentMultiLineMaxW(); + float nMaxWidth = getCurrentMultiLineMaxW(); _LastMultiLineMaxW = nMaxWidth; clearLines(); if (nMaxWidth <= 0) @@ -1873,8 +1874,8 @@ namespace NLGUI { rTotalW = std::max(_Lines[i]->getWidth() + ((i==0)?_FirstLineX:0), rTotalW); } - _W = (sint)rTotalW; - _H = std::max(_FontHeight, uint(_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * _MultiLineSpace)); + _W = (sint)ceilf(rTotalW); + _H = std::max(_FontHeight, ceilf(_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * _MultiLineSpace)); // See if we should pretend to have at least X lines if (_MultiMinLine > 1) @@ -1895,7 +1896,7 @@ namespace NLGUI { CCtrlToolTip *pTooltip = _Tooltips[word.Format.IndexTt]; - sint y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i - 1)); + sint y = (sint) ceilf((_FontHeight + _MultiLineSpace) * (_Lines.size() - i - 1)); pTooltip->setX(0); pTooltip->setY(y); @@ -1914,7 +1915,8 @@ namespace NLGUI // Common case: no W clamp _Index = TextContext->textPush (_Text); _Info = TextContext->getStringInfo (_Index); - _W = (sint)(_Info.StringWidth); + _Info.StringWidth /= _Scale; + _W = (sint)ceilf(_Info.StringWidth); // Rare case: clamp W => recompute slowly, cut letters if(_W>_LineMaxW) @@ -1927,7 +1929,7 @@ namespace NLGUI ucCurrentLine.reserve(_Text.size()); // Append ... to the end of line si = TextContext->getStringInfo (ucstring("...")); - float dotWidth= si.StringWidth; + float dotWidth= si.StringWidth / _Scale; float rWidthCurrentLine = 0, rWidthLetter; // for all the text if (_ClampRight) @@ -1938,7 +1940,7 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth); + rWidthLetter = (si.StringWidth / _Scale); if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW) { break; @@ -1962,7 +1964,7 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth); + rWidthLetter = (si.StringWidth / _Scale); if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW) { break; @@ -1982,13 +1984,14 @@ namespace NLGUI // And so setup this trunc text _Index = TextContext->textPush (ucCurrentLine); _Info = TextContext->getStringInfo (_Index); - _W = (sint)(_Info.StringWidth); + _Info.StringWidth /= _Scale; + _W = (sint)ceilf(_Info.StringWidth); _SingleLineTextClamped= true; } // same height always - _H = _FontHeight; + _H = (sint)ceilf(_FontHeight); } _InvalidTextContext= false; @@ -2025,12 +2028,12 @@ namespace NLGUI if (_ClampRight) { sint32 parentRight = parent->getXReal() + parent->getWReal() - (sint32) _AutoClampOffset; - setLineMaxW(std::max((sint32) 0, parentRight - _XReal)); + setLineMaxW(ceilf(std::max((sint32) 0, parentRight - _XReal) / _Scale)); } else { sint32 parentLeft = parent->getXReal() + (sint32) _AutoClampOffset; - setLineMaxW(std::max((sint32) 0, _XReal + _WReal - parentLeft)); + setLineMaxW(ceilf(std::max((sint32) 0, _XReal + _WReal - parentLeft) / _Scale)); } } } @@ -2154,7 +2157,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); // CViewRenderer &rVR = *CViewRenderer::getInstance(); @@ -2224,14 +2227,14 @@ namespace NLGUI ucstring subStr = currWord.Text.substr(0, index - charIndex - currWord.NumSpaces); // compute the size UTextContext::CStringInfo si = TextContext->getStringInfo(subStr); - x = (sint) (px + si.StringWidth + currWord.NumSpaces * currLine.getSpaceWidth()); + x = (sint) ceilf(px + si.StringWidth / _Scale + currWord.NumSpaces * currLine.getSpaceWidth()); height = getFontHeight(); return; } else { // character is in the spaces preceding the word - x = (sint) (px + currLine.getSpaceWidth() * (index - charIndex)); + x = (sint) ceilf(px + currLine.getSpaceWidth() * (index - charIndex)); height = getFontHeight(); return; } @@ -2251,7 +2254,7 @@ namespace NLGUI // compute the size UTextContext::CStringInfo si = TextContext->getStringInfo(subStr); y = 0; - x = (sint) si.StringWidth; + x = (sint) ceilf(si.StringWidth / _Scale); } } @@ -2260,6 +2263,7 @@ namespace NLGUI static uint getCharacterIndex(const ucstring &textValue, float x) { float px = 0.f; + float sw; UTextContext::CStringInfo si; ucstring singleChar(" "); uint i; @@ -2268,12 +2272,13 @@ namespace NLGUI // get character width singleChar[0] = textValue[i]; si = CViewRenderer::getTextContext()->getStringInfo(singleChar); - px += si.StringWidth; + sw = si.StringWidth / CViewRenderer::getInstance()->getInterfaceScale(); + px += sw / CViewRenderer::getInstance()->getInterfaceScale(); // the character is at the i - 1 position if (px > x) { // if the half of the character is after the cursor, then prefer select the next one (like in Word) - if(px-si.StringWidth/2 < x) + if(px-sw/2 < x) i++; break; } @@ -2290,7 +2295,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); // find the line where the character is @@ -2490,7 +2495,7 @@ 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, float fontWidth) { CWord word; word.build(text, numSpaces); @@ -2499,7 +2504,7 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CLine::addWord(const CWord &word, uint fontWidth) + void CViewText::CLine::addWord(const CWord &word, float fontWidth) { _Words.push_back(word); _NumChars += word.NumSpaces + uint(word.Text.length()); @@ -2509,7 +2514,7 @@ namespace NLGUI _StringLine = word.Info.StringLine; } // the width of the line must reach at least the Tab - _WidthWithoutSpaces= max(_WidthWithoutSpaces, word.Format.TabX * float(fontWidth)); + _WidthWithoutSpaces= max(_WidthWithoutSpaces, word.Format.TabX * fontWidth); // append the text space _WidthWithoutSpaces += word.Info.StringWidth; } @@ -2544,6 +2549,7 @@ namespace NLGUI NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); Index = TextContext->textPush(text); Info = TextContext->getStringInfo(Index); + Info.StringWidth /= CViewRenderer::getInstance()->getInterfaceScale(); } // *************************************************************************** @@ -2568,7 +2574,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); @@ -2617,7 +2623,7 @@ namespace NLGUI si = TextContext->getStringInfo(wordValue); // compute size of spaces + word - lineWidth += numSpaces * _SpaceWidth + si.StringWidth; + lineWidth += numSpaces * _SpaceWidth + si.StringWidth / _Scale; currPos = wordEnd; } @@ -2629,14 +2635,14 @@ namespace NLGUI linePos = lineEnd+1; } - return (sint32)maxWidth; + return (sint32)ceilf(maxWidth); } // *************************************************************************** sint32 CViewText::getMinUsedW() const { static const ucstring spaceOrLineFeedStr(" \n\t"); - sint32 maxWidth = 0; + float maxWidth = 0.0f; // Not multi line ? Same size than min if (!_MultiLine) @@ -2646,7 +2652,7 @@ namespace NLGUI if (_TextMode == ClipWord) { // No largest font parameter, return the font height - return _FontHeight; + return (sint32)ceilf(_FontHeight); } // If we can't clip the words, return the size of the largest word else if ((_TextMode == DontClipWord) || (_TextMode == Justified)) @@ -2655,7 +2661,7 @@ namespace NLGUI TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); @@ -2683,7 +2689,7 @@ namespace NLGUI si = TextContext->getStringInfo(wordValue); // Larger ? - sint32 stringWidth = (sint32)si.StringWidth; + float stringWidth = (si.StringWidth / _Scale); if (stringWidth>maxWidth) maxWidth = stringWidth; @@ -2692,7 +2698,7 @@ namespace NLGUI } } - return maxWidth; + return ceilf(maxWidth); } // *************************************************************************** @@ -2709,11 +2715,13 @@ namespace NLGUI // *************************************************************************** void CViewText::computeFontSize () { + _Scale = CViewRenderer::getInstance()->getInterfaceScale(); + NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); TextContext->setShadeOutline (_ShadowOutline); - TextContext->setFontSize (_FontSize); + TextContext->setFontSize (_FontSize * _Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); @@ -2728,16 +2736,16 @@ namespace NLGUI // for now we can't know that directly from UTextContext UTextContext::CStringInfo 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; + _FontHeight = (si.StringHeight / _Scale) + 1; + _FontLegHeight = si.StringLine / _Scale; // Space width si = TextContext->getStringInfo(ucstring(" ")); - _SpaceWidth = si.StringWidth; + _SpaceWidth = si.StringWidth / _Scale; // Font Width si = TextContext->getStringInfo(ucstring("_")); - _FontWidth = (uint)si.StringWidth; + _FontWidth = si.StringWidth / _Scale; } From 34fa04644e941fe1fb1f3cbd04dff31749707eb2 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 6 Jun 2016 19:48:08 +0300 Subject: [PATCH 04/25] Fixed: In scene text bubble position --HG-- branch : experimental-ui-scaling --- code/ryzom/client/src/interface_v3/group_in_scene.cpp | 6 ++++-- .../ryzom/client/src/interface_v3/group_in_scene_bubble.cpp | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/group_in_scene.cpp b/code/ryzom/client/src/interface_v3/group_in_scene.cpp index fccf2e9e6..b547f7fb0 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene.cpp @@ -86,8 +86,10 @@ void CGroupInScene::computeWindowPos(sint32 &newX, sint32 &newY, CVector &newPro tmp = pVR.getFrustum().projectZ (tmp); // Get the width and height - tmp.x *= (float)CViewRenderer::getInstance()->getDriver()->getWindowWidth(); - tmp.y *= (float)CViewRenderer::getInstance()->getDriver()->getWindowHeight(); + uint32 width, height; + CViewRenderer::getInstance()->getScreenSize(width, height); + tmp.x *= width; + tmp.y *= height; // position without offset, in float newProjCenter.x= tmp.x; diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp index e964911c3..eb935bc40 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp @@ -668,9 +668,8 @@ CGroupInSceneBubbleManager::CPopupContext *CGroupInSceneBubbleManager::buildCont if (target) { // Find a position - NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver(); - const uint width = Driver->getWindowWidth(); - const uint height = Driver->getWindowHeight(); + uint32 width, height; + CViewRenderer::getInstance()->getScreenSize(width, height); h = (target->getXReal() < ((sint)width-target->getXReal()-target->getWReal()))?"l":"r"; v = (target->getYReal() < ((sint)height-target->getYReal()-target->getHReal()))?"b":"t"; target->setActive(true); From 2cb71e654ae945a67cb9a306847e2b28de84220a Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 7 Jun 2016 17:27:00 +0300 Subject: [PATCH 05/25] Fixed: Update text widget parent size when interface scale changes --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/widget_manager.h | 1 + code/nel/src/gui/widget_manager.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index cfb51af8e..7566a8ad4 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -614,6 +614,7 @@ namespace NLGUI uint32 _ScreenH; uint32 _ScreenW; + float _InterfaceScale; std::vector< CInterfaceAnim* > activeAnims; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index f866594c9..0288bff12 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1850,9 +1850,10 @@ namespace NLGUI class InvalidateTextVisitor : public CInterfaceElementVisitor { public: - InvalidateTextVisitor( bool reset ) + InvalidateTextVisitor( bool reset, bool invalidate ) { this->reset = reset; + this->invalidate = invalidate; } void visitGroup( CInterfaceGroup *group ) @@ -1865,13 +1866,17 @@ namespace NLGUI { if( reset ) vt->resetTextIndex(); - vt->updateTextContext(); + if( invalidate ) + vt->invalidateContent(); + else + vt->updateTextContext(); } } } private: bool reset; + bool invalidate; }; // ------------------------------------------------------------------------------------------------ @@ -1884,6 +1889,8 @@ namespace NLGUI CViewRenderer::getInstance()->checkNewScreenSize (); CViewRenderer::getInstance()->getScreenSize (w, h); + bool scaleChanged = _InterfaceScale != CViewRenderer::getInstance()->getInterfaceScale(); + // Update ui:* (limit the master containers to the height of the screen) for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++) { @@ -1902,7 +1909,7 @@ namespace NLGUI { SMasterGroup &rMG = _MasterGroups[nMasterGroup]; - InvalidateTextVisitor inv( false ); + InvalidateTextVisitor inv( false, scaleChanged ); rMG.Group->visitGroupAndChildren( &inv ); rMG.Group->invalidateCoords (); @@ -3725,6 +3732,7 @@ namespace NLGUI inGame = false; setScreenWH(0, 0); + _InterfaceScale = 1.0f; _GroupSelection = false; multiSelection = false; From 6bfc777496fe5506575d516c3c55e49322504b3c Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 14 Jul 2016 20:20:55 +0300 Subject: [PATCH 06/25] Fixed: Restore scaled interface from icfg --HG-- branch : experimental-ui-scaling --- code/ryzom/client/src/interface_v3/interface_manager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 802f98c70..c75d880b6 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -1787,8 +1787,12 @@ bool CInterfaceManager::loadConfig (const string &filename) CWidgetManager::getInstance()->setScreenWH(_LastInGameScreenW, _LastInGameScreenH); // NB: we are typically InGame here (even though the _InGame flag is not yet set) // Use the screen size of the config file. Don't update current UI, just _Modes - CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(ClientCfg.Width, ClientCfg.Height, false); - updateDesktops( ClientCfg.Width, ClientCfg.Height ); + // + // ClientCfg has W/H set to screen size, but interface expects scaled size + sint32 scaledW = ClientCfg.Width / ClientCfg.InterfaceScale; + sint32 scaledH = ClientCfg.Height / ClientCfg.InterfaceScale; + CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false); + updateDesktops(scaledW, scaledH); } // *** apply the current mode From 87aa86e01687da4babd991e3f8c9418a7f9d5881 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 14 Jul 2016 20:20:55 +0300 Subject: [PATCH 07/25] Fixed: Mouse pointer location after exiting freelook --HG-- branch : experimental-ui-scaling --- code/ryzom/client/src/input.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/ryzom/client/src/input.cpp b/code/ryzom/client/src/input.cpp index 403947538..f0a3133b9 100644 --- a/code/ryzom/client/src/input.cpp +++ b/code/ryzom/client/src/input.cpp @@ -179,9 +179,9 @@ void SetMouseCursor (bool updatePos) // Get the last cursor float x = 0.5f, y = 0.5f; - // Window size - uint width = Driver->getWindowWidth(); - uint height = Driver->getWindowHeight(); + // Screen size + uint width, height; + CViewRenderer::getInstance()->getScreenSize(width, height); // Update the interface pointer CInterfaceManager *instance = CInterfaceManager::getInstance(); From 5e1c6cd287f4718efbfae34e34f62a47cbdd99da Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 14 Jul 2016 20:20:55 +0300 Subject: [PATCH 08/25] Added: Bilinear filtering option for texture atlas textures --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_renderer.h | 2 ++ code/nel/src/gui/view_renderer.cpp | 5 +++-- code/ryzom/client/src/client_cfg.cpp | 2 ++ code/ryzom/client/src/client_cfg.h | 1 + code/ryzom/client/src/init.cpp | 1 + code/ryzom/client/src/main_loop_utilities.cpp | 3 +++ 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/view_renderer.h b/code/nel/include/nel/gui/view_renderer.h index c737037a1..64cbfc888 100644 --- a/code/nel/include/nel/gui/view_renderer.h +++ b/code/nel/include/nel/gui/view_renderer.h @@ -181,6 +181,7 @@ namespace NLGUI */ void setInterfaceScale(float scale, sint32 width = 0, sint32 height = 0); float getInterfaceScale() const { return _InterfaceScale; } + void setBilinearFiltering(bool b) { _Bilinear = b; } /* * is the Screen minimized? @@ -537,6 +538,7 @@ namespace NLGUI float _InterfaceUserScale; sint32 _InterfaceBaseW, _InterfaceBaseH; sint32 _EffectiveScreenW, _EffectiveScreenH; + bool _Bilinear; void updateInterfaceScale(); diff --git a/code/nel/src/gui/view_renderer.cpp b/code/nel/src/gui/view_renderer.cpp index f8a8152b9..fe86dce1f 100644 --- a/code/nel/src/gui/view_renderer.cpp +++ b/code/nel/src/gui/view_renderer.cpp @@ -199,6 +199,7 @@ namespace NLGUI _EmptyLayer[i]= true; } _BlankGlobalTexture = NULL; + _Bilinear = false; updateInterfaceScale(); } @@ -1279,7 +1280,7 @@ namespace NLGUI _Material.setTexture(0, ite->Texture); // Special Case if _WorldSpaceTransformation and _WorldSpaceScale, enable bilinear - if(_WorldSpaceTransformation && _WorldSpaceScale) + if(_Bilinear || (_WorldSpaceTransformation && _WorldSpaceScale)) ite->Texture->setFilterMode(UTexture::Linear, UTexture::LinearMipMapOff); // draw quads and empty list @@ -1296,7 +1297,7 @@ namespace NLGUI } // Special Case if _WorldSpaceTransformation and _WorldSpaceScale, reset - if(_WorldSpaceTransformation && _WorldSpaceScale) + if(_Bilinear || (_WorldSpaceTransformation && _WorldSpaceScale)) ite->Texture->setFilterMode(UTexture::Nearest, UTexture::NearestMipMapOff); } if (!layer.FilteredAlphaBlendedQuads.empty() || diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index e321fdd6a..237892dbf 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -301,6 +301,7 @@ CClientConfig::CClientConfig() Gamma = 0.f; // Default Monitor Gamma. InterfaceScale = 1.0f; // Resize UI + BilinearUI = false; VREnable = false; VRDisplayDevice = "Auto"; @@ -839,6 +840,7 @@ void CClientConfig::setValues() READ_FLOAT_FV(InterfaceScale); // 50% smaller / 2x bigger clamp(ClientCfg.InterfaceScale, 0.5f, 2.0f); + READ_BOOL_FV(BilinearUI); // 3D Driver varPtr = ClientCfg.ConfigFile.getVarPtr ("Driver3D"); if (varPtr) diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index 157503957..2fc561c4d 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -148,6 +148,7 @@ struct CClientConfig // UI scaling float InterfaceScale; + bool BilinearUI; // VR bool VREnable; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 8105d9351..d0f38f7b6 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1317,6 +1317,7 @@ void prelogInit() CInterfaceManager::getInstance(); CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768); + CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI); // Yoyo: initialize NOW the InputHandler for Event filtering. CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance(); diff --git a/code/ryzom/client/src/main_loop_utilities.cpp b/code/ryzom/client/src/main_loop_utilities.cpp index e62c033e4..37bfc3247 100644 --- a/code/ryzom/client/src/main_loop_utilities.cpp +++ b/code/ryzom/client/src/main_loop_utilities.cpp @@ -104,6 +104,9 @@ void updateFromClientCfg() if (ClientCfg.InterfaceScale != LastClientCfg.InterfaceScale) CInterfaceManager::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale); + if (ClientCfg.BilinearUI != LastClientCfg.BilinearUI) + CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI); + //--------------------------------------------------- if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) { From d8e1d3b25487b4f3e1380fa8a369e85446db6cd3 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 14 Jul 2016 20:20:55 +0300 Subject: [PATCH 09/25] Added: Border duplication option to texture atlas builder. --HG-- branch : experimental-ui-scaling --- code/nel/tools/3d/build_interface/main.cpp | 30 ++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/code/nel/tools/3d/build_interface/main.cpp b/code/nel/tools/3d/build_interface/main.cpp index 1b13a0f71..f2d3aa49c 100644 --- a/code/nel/tools/3d/build_interface/main.cpp +++ b/code/nel/tools/3d/build_interface/main.cpp @@ -201,10 +201,13 @@ int main(int nNbArg, char **ppArgs) outString ("ERROR : Wrong number of arguments\n"); outString ("USAGE : build_interface [-s] [path_maps2] [path_maps3] ....\n"); outString (" -s : build a subset of an existing interface definition while preserving the existing texture ids,"); + outString (" -b : border duplication to enable bi-linear filtering"); outString (" to support freeing up VRAM by switching to the subset without rebuilding the entire interface\n"); return -1; } - + + uint borderSize = 0; + // build as a subset of existing interface bool buildSubset = false; string existingUVfilename; @@ -215,6 +218,10 @@ int main(int nNbArg, char **ppArgs) { switch ( ppArgs[i][1] ) { + case 'B': + case 'b': + borderSize = 1; + break; case 'S': case 's': buildSubset = true; @@ -274,6 +281,19 @@ int main(int nNbArg, char **ppArgs) pBtmp->convertToType(CBitmap::RGBA); } + // duplicate bitmap border to enable bilinear filtering + { + NLMISC::CBitmap *tmp = new NLMISC::CBitmap; + tmp->resize(pBtmp->getWidth(), pBtmp->getHeight()); + tmp->blit(pBtmp, 0, 0); + // upscale image to get borders + tmp->resample(tmp->getWidth()+borderSize*2, tmp->getHeight()+borderSize*2); + // copy original + tmp->blit(pBtmp, borderSize, borderSize); + delete pBtmp; + pBtmp = tmp; + } + AllMaps[i] = pBtmp; } catch (const NLMISC::Exception &e) @@ -325,10 +345,10 @@ int main(int nNbArg, char **ppArgs) } putIn (AllMaps[i], &GlobalTexture, x, y); putIn (AllMaps[i], &GlobalMask, x, y, false); - UVMin[i].U = (float)x; - UVMin[i].V = (float)y; - UVMax[i].U = (float)x+AllMaps[i]->getWidth(); - UVMax[i].V = (float)y+AllMaps[i]->getHeight(); + UVMin[i].U = (float)x+borderSize; + UVMin[i].V = (float)y+borderSize; + UVMax[i].U = (float)x+borderSize+AllMaps[i]->getWidth()-borderSize*2; + UVMax[i].V = (float)y+borderSize+AllMaps[i]->getHeight()-borderSize*2; /* // Do not remove this is useful for debugging { From 44208ba1ad7358917c03cf5ee83e16aca52626d7 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 19 Jul 2016 11:12:47 +0300 Subject: [PATCH 10/25] Changed: Use float for bitmap pos for better pixel align when scale is used --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_renderer.h | 2 +- code/nel/src/gui/view_renderer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/view_renderer.h b/code/nel/include/nel/gui/view_renderer.h index 64cbfc888..99d92a7cd 100644 --- a/code/nel/include/nel/gui/view_renderer.h +++ b/code/nel/include/nel/gui/view_renderer.h @@ -192,7 +192,7 @@ namespace NLGUI * drawBitmap : this is the interface with all the views * */ - void drawRotFlipBitmap (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height, uint8 rot, bool flipv, + void drawRotFlipBitmap (sint layerId, float x, float y, float width, float height, uint8 rot, bool flipv, sint32 nTxId, const NLMISC::CRGBA &col = NLMISC::CRGBA(255,255,255,255)); /* diff --git a/code/nel/src/gui/view_renderer.cpp b/code/nel/src/gui/view_renderer.cpp index fe86dce1f..d0bb214b2 100644 --- a/code/nel/src/gui/view_renderer.cpp +++ b/code/nel/src/gui/view_renderer.cpp @@ -496,7 +496,7 @@ namespace NLGUI /* * drawBitmap */ - void CViewRenderer::drawRotFlipBitmap (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height, + void CViewRenderer::drawRotFlipBitmap (sint layerId, float x, float y, float width, float height, uint8 rot, bool flipv, sint32 nTxId, const CRGBA &col) { if (width <= 0 || height <= 0) return; From 8d09471a6dda49912bbecdc35d3c4a629c0e568b Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 19 Jul 2016 11:12:51 +0300 Subject: [PATCH 11/25] Fixed: Pixel align underline/strikethrough line on text --HG-- branch : experimental-ui-scaling --- code/nel/src/gui/view_text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6a66bdf74..ea0c96ca5 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1083,10 +1083,10 @@ namespace NLGUI // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1.0f / rVR.getInterfaceScale(), 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); + rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1.0f / rVR.getInterfaceScale(), 0, false, rVR.getBlankTextureId(), col); // skip word px += currWord.Info.StringWidth; From 7b0d1cd0563e757e7bdeb663fa9b6a571d3fb550 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 13 Aug 2016 23:32:54 +0300 Subject: [PATCH 12/25] Fixed: Double font width scaling --HG-- branch : experimental-ui-scaling --- code/nel/src/gui/view_text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 0ff74c963..2be91d0d0 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -2293,7 +2293,7 @@ namespace NLGUI singleChar[0] = textValue[i]; si = textContext.getStringInfo(singleChar); sw = si.StringWidth / CViewRenderer::getInstance()->getInterfaceScale(); - px += sw / CViewRenderer::getInstance()->getInterfaceScale(); + px += sw; // the character is at the i - 1 position if (px > x) { From 279f67fc2dc087e4d93b87dc2622bf18d4871309 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 13 Aug 2016 23:34:49 +0300 Subject: [PATCH 13/25] Changed: Use current scale value instead of asking CViewRenderer --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_text.h | 4 ++-- code/nel/src/gui/view_text.cpp | 34 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index 265935067..3c5b8622d 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -326,7 +326,7 @@ namespace NLGUI CFormatInfo Format; public: // build from a string, using the current text context - void build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces= 0); + void build(const ucstring &text, NL3D::UTextContext &textContext, float scale, uint numSpaces= 0); }; typedef std::vector TWordVect; @@ -339,7 +339,7 @@ namespace NLGUI // Clear the line & remove text contexts 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, float fontWidth, NL3D::UTextContext &textContext); + void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext, float scale); void addWord(const CWord &word, float 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 2be91d0d0..f28f9c3ed 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1082,10 +1082,10 @@ namespace NLGUI // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1.0f / rVR.getInterfaceScale(), 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); if (_StrikeThrough) - rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1.0f / rVR.getInterfaceScale(), 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); // skip word px += currWord.Info.StringWidth; @@ -1426,7 +1426,7 @@ namespace NLGUI linePushed= true; } // Append to the last line - _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth, *TextContext); + _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth, *TextContext, _Scale); // reset the word ucCurrentWord = ucstring(""); } @@ -1523,7 +1523,7 @@ namespace NLGUI if(currLine[i].Format!=lineWordFormat) { // add the current lineWord to the line. - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext, _Scale); // get new lineWordFormat lineWordFormat= currLine[i].Format; // and clear @@ -1538,7 +1538,7 @@ namespace NLGUI } if(!lineWord.empty()) - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext, _Scale); // clear currLine.clear(); @@ -1699,7 +1699,7 @@ namespace NLGUI { uint maxNumSpaces = std::max(1U, (uint) (nMaxWidth / _SpaceWidth)); CWord spaceWord; // a word with only spaces in it - spaceWord.build (ucstring (""), *TextContext, maxNumSpaces); + spaceWord.build (ucstring (""), *TextContext, _Scale, maxNumSpaces); spaceWord.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); _Lines.back()->addWord(spaceWord, _FontWidth); @@ -1728,7 +1728,7 @@ namespace NLGUI 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, *TextContext, numSpaces); + word.build(wordValue, *TextContext, _Scale, numSpaces); word.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); float roomForSpaces = (float) nMaxWidth - word.Info.StringWidth; @@ -1763,7 +1763,7 @@ namespace NLGUI if (!wordValue.empty() || numSpaces != 0) { CWord word; - word.build(wordValue, *TextContext, numSpaces); + word.build(wordValue, *TextContext, _Scale, numSpaces); word.Format= wordFormat; // update line width _Lines.back()->addWord(word, _FontWidth); @@ -1883,7 +1883,7 @@ namespace NLGUI _Lines.pop_back(); CViewText::CLine *endLine = new CViewText::CLine; CViewText::CWord w; - w.build(string("..."), *TextContext); + w.build(string("..."), *TextContext, _Scale); endLine->addWord(w, _FontWidth); _Lines.push_back(TLineSPtr(endLine)); } @@ -2280,7 +2280,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, NL3D::UTextContext &textContext) + static uint getCharacterIndex(const ucstring &textValue, float x, NL3D::UTextContext &textContext, float scale) { float px = 0.f; float sw; @@ -2292,7 +2292,7 @@ namespace NLGUI // get character width singleChar[0] = textValue[i]; si = textContext.getStringInfo(singleChar); - sw = si.StringWidth / CViewRenderer::getInstance()->getInterfaceScale(); + sw = si.StringWidth / scale; px += sw; // the character is at the i - 1 position if (px > x) @@ -2390,7 +2390,7 @@ namespace NLGUI else { // the coord is in the word itself - index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth), *TextContext); + index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth), *TextContext, _Scale); cursorAtPreviousLineEnd = false; return; } @@ -2415,7 +2415,7 @@ namespace NLGUI index = 0; return; } - index = getCharacterIndex(_Text, (float) x, *TextContext); + index = getCharacterIndex(_Text, (float) x, *TextContext, _Scale); return; } } @@ -2516,10 +2516,10 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext) + void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext, float scale) { CWord word; - word.build(text, textContext, numSpaces); + word.build(text, textContext, scale, numSpaces); word.Format= wordFormat; addWord(word, fontWidth); } @@ -2563,13 +2563,13 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CWord::build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces) + void CViewText::CWord::build(const ucstring &text, NL3D::UTextContext &textContext, float scale, uint numSpaces) { Text = text; NumSpaces = numSpaces; Index = textContext.textPush(text); Info = textContext.getStringInfo(Index); - Info.StringWidth /= CViewRenderer::getInstance()->getInterfaceScale(); + Info.StringWidth /= scale; } // *************************************************************************** From 4a722c7783754c6fead120a6f63cb73d32caf03e Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 14 Aug 2016 02:25:10 +0300 Subject: [PATCH 14/25] Changed: Use UI scale change event to change CViewText font scale --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/interface_element.h | 16 +++++- code/nel/include/nel/gui/view_text.h | 1 + code/nel/include/nel/gui/widget_manager.h | 7 +++ code/nel/src/gui/view_text.cpp | 27 ++++++---- code/nel/src/gui/widget_manager.cpp | 56 ++++++++++++++++---- 5 files changed, 87 insertions(+), 20 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 65a0fcaff..5177e322a 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -38,6 +38,16 @@ namespace NLGUI class IActionHandler; class CGroupParagraph; + /** + * Interface for UI scale change event + */ + class IInterfaceScaleWatcher + { + public: + virtual ~IInterfaceScaleWatcher(){} + virtual void onInterfaceScaleChanged()=0; + }; + /** * A visitor to walk a tree of interface elements and apply a teartment on them. * @@ -66,7 +76,7 @@ namespace NLGUI * \author Nevrax France * \date 2002 */ - class CInterfaceElement : public CReflectableRefPtrTarget, public NLMISC::IStreamable + class CInterfaceElement : public IInterfaceScaleWatcher, public CReflectableRefPtrTarget, public NLMISC::IStreamable { public: @@ -402,6 +412,10 @@ namespace NLGUI */ virtual void onInvalidateContent() {} + /* Element UI scale change event callback + */ + virtual void onInterfaceScaleChanged() {} + // called by interfaceManager for master window only void resetInvalidCoords(); diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index 3c5b8622d..95b8d2e4a 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -70,6 +70,7 @@ namespace NLGUI virtual void checkCoords(); virtual void updateCoords(); virtual void onAddToGroup(); + virtual void onInterfaceScaleChanged(); /// From CInterfaceElement sint32 getMaxUsedW() const; diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8cca08cc6..827e35224 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -49,6 +49,7 @@ namespace NLGUI class CProcedure; class IEditorSelectionWatcher; class IWidgetAdditionWatcher; + class IInterfaceScaleWatcher; /** GUI Widget Manager @@ -530,6 +531,11 @@ namespace NLGUI bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } + float getInterfaceScale() const { return _InterfaceScale; } + void notifyInterfaceScaleWatchers(); + void registerInterfaceScaleWatcher(IInterfaceScaleWatcher *watcher); + void unregisterInterfaceScaleWatcher(IInterfaceScaleWatcher *watcher); + bool createNewGUI( const std::string &project, const std::string &window ); private: @@ -623,6 +629,7 @@ namespace NLGUI std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers; std::vector< IEditorSelectionWatcher* > selectionWatchers; std::vector< IWidgetWatcher* > widgetWatchers; + std::vector< IInterfaceScaleWatcher* > scaleWatchers; std::vector< std::string > editorSelection; bool _GroupSelection; diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index f28f9c3ed..3e649c1c3 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -80,7 +80,7 @@ namespace NLGUI _MultiMaxLine = 0; _Index = 0xFFFFFFFF; - _Scale = 1.0f; + _Scale = CWidgetManager::getInstance()->getInterfaceScale(); _FontWidth= 0; _FontHeight = 0; _FontLegHeight = 0; @@ -113,6 +113,8 @@ namespace NLGUI :CViewBase(param) { setupDefault (); + + CWidgetManager::getInstance()->registerInterfaceScaleWatcher(this); } ///constructor @@ -130,11 +132,15 @@ namespace NLGUI _ShadowOutline = ShadowOutline; setText(Text); computeFontSize (); + + CWidgetManager::getInstance()->registerInterfaceScaleWatcher(this); } // *************************************************************************** CViewText::~CViewText() { + CWidgetManager::getInstance()->unregisterInterfaceScaleWatcher(this); + if (_Index != 0xFFFFFFFF) CViewRenderer::getTextContext(_FontName)->erase (_Index); clearLines(); @@ -893,9 +899,6 @@ namespace NLGUI // *************************************************************************** void CViewText::checkCoords () { - if (_Scale != CViewRenderer::getInstance()->getInterfaceScale()) - invalidateContent(); - if ((_MultiLine)&&(_Parent != NULL)) { // If never setuped, and if text is not empty @@ -1840,9 +1843,6 @@ namespace NLGUI // *************************************************************************** void CViewText::updateTextContext () { - if (_Scale != CViewRenderer::getInstance()->getInterfaceScale()) - computeFontSize(); - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); @@ -2732,11 +2732,20 @@ namespace NLGUI invalidateCoords(); } + // *************************************************************************** + void CViewText::onInterfaceScaleChanged() + { + _Scale = CWidgetManager::getInstance()->getInterfaceScale(); + + computeFontSize (); + invalidateContent(); + + CViewBase::onInterfaceScaleChanged(); + } + // *************************************************************************** void CViewText::computeFontSize () { - _Scale = CViewRenderer::getInstance()->getInterfaceScale(); - NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5d278a29a..a215dbf08 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1850,10 +1850,9 @@ namespace NLGUI class InvalidateTextVisitor : public CInterfaceElementVisitor { public: - InvalidateTextVisitor( bool reset, bool invalidate ) + InvalidateTextVisitor( bool reset) { this->reset = reset; - this->invalidate = invalidate; } void visitGroup( CInterfaceGroup *group ) @@ -1866,17 +1865,13 @@ namespace NLGUI { if( reset ) vt->resetTextIndex(); - if( invalidate ) - vt->invalidateContent(); - else - vt->updateTextContext(); + vt->updateTextContext(); } } } private: bool reset; - bool invalidate; }; // ------------------------------------------------------------------------------------------------ @@ -1889,8 +1884,6 @@ namespace NLGUI CViewRenderer::getInstance()->checkNewScreenSize (); CViewRenderer::getInstance()->getScreenSize (w, h); - bool scaleChanged = _InterfaceScale != CViewRenderer::getInstance()->getInterfaceScale(); - // Update ui:* (limit the master containers to the height of the screen) for (nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++) { @@ -1900,6 +1893,13 @@ namespace NLGUI } CViewRenderer::getInstance()->setClipWindow(0, 0, w, h); + bool scaleChanged = _InterfaceScale != CViewRenderer::getInstance()->getInterfaceScale(); + if (scaleChanged) + { + _InterfaceScale = CViewRenderer::getInstance()->getInterfaceScale(); + notifyInterfaceScaleWatchers(); + } + // If all conditions are OK, move windows so they fit correctly with new screen size // Do this work only InGame when Config is loaded moveAllWindowsToNewScreenSize(w,h,true); @@ -1909,7 +1909,7 @@ namespace NLGUI { SMasterGroup &rMG = _MasterGroups[nMasterGroup]; - InvalidateTextVisitor inv( false, scaleChanged ); + InvalidateTextVisitor inv( false); rMG.Group->visitGroupAndChildren( &inv ); rMG.Group->invalidateCoords (); @@ -3697,6 +3697,42 @@ namespace NLGUI } + // ------------------------------------------------------------------------------------------------ + void CWidgetManager::notifyInterfaceScaleWatchers() + { + std::vector< IInterfaceScaleWatcher* >::iterator itr = scaleWatchers.begin(); + while( itr != scaleWatchers.end() ) + { + (*itr)->onInterfaceScaleChanged(); + ++itr; + } + } + + // ------------------------------------------------------------------------------------------------ + void CWidgetManager::registerInterfaceScaleWatcher( IInterfaceScaleWatcher *watcher ) + { + std::vector< IInterfaceScaleWatcher* >::const_iterator itr + = std::find( scaleWatchers.begin(), scaleWatchers.end(), watcher ); + + if( itr != scaleWatchers.end() ) + return; + + scaleWatchers.push_back( watcher ); + } + + // ------------------------------------------------------------------------------------------------ + void CWidgetManager::unregisterInterfaceScaleWatcher( IInterfaceScaleWatcher *watcher ) + { + std::vector< IInterfaceScaleWatcher* >::iterator itr + = std::find( scaleWatchers.begin(), scaleWatchers.end(), watcher ); + + if( itr == scaleWatchers.end() ) + return; + + scaleWatchers.erase( itr ); + } + + // ------------------------------------------------------------------------------------------------ CWidgetManager::CWidgetManager() { LinkHack(); From b5717de4fcc9657bc1f78bdb264cf6d2c4faf15a Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 14 Aug 2016 02:25:19 +0300 Subject: [PATCH 15/25] Added: Remove hardcoded text overflow indicator --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_text.h | 3 ++ code/nel/src/gui/view_text.cpp | 42 ++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index 95b8d2e4a..e0603895c 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -90,6 +90,7 @@ namespace NLGUI void setShadowOutline (bool bShadowOutline); void setShadowColor (const NLMISC::CRGBA &color); void setLineMaxW (sint nMaxW, bool invalidate=true); + void setOverflowText(const ucstring &text) { _OverflowText = text; } void setMultiLine (bool bMultiLine); void setMultiLineSpace (sint nMultiLineSpace); void setMultiLineMaxWOnly (bool state); @@ -114,6 +115,7 @@ namespace NLGUI bool getShadowOutline() { return _ShadowOutline; } NLMISC::CRGBA getShadowColor() { return _ShadowColor; } sint getLineMaxW() const { return _LineMaxW; } + ucstring getOverflowText() const { return _OverflowText; } bool getMultiLine() const { return _MultiLine; } sint getMultiLineSpace() const { return _MultiLineSpace; } bool getMultiLineMaxWOnly() const { return _MultiLineMaxWOnly; } @@ -259,6 +261,7 @@ namespace NLGUI sint32 _LineMaxW; /// For single line, true if the text is clamped (ie displayed with "...") bool _SingleLineTextClamped; + ucstring _OverflowText; /// Multiple lines handling bool _MultiLine; diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 3e649c1c3..02b2600b4 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -99,6 +99,7 @@ namespace NLGUI _AutoClamp = false; _ClampRight = true; // clamp on the right of the text + _OverflowText = "..."; _LetterColors = NULL; _Setuped= false; @@ -1880,12 +1881,15 @@ namespace NLGUI _Lines.back()->clear(*TextContext); _Lines.pop_back(); } - _Lines.pop_back(); - CViewText::CLine *endLine = new CViewText::CLine; - CViewText::CWord w; - w.build(string("..."), *TextContext, _Scale); - endLine->addWord(w, _FontWidth); - _Lines.push_back(TLineSPtr(endLine)); + if (_OverflowText.size() > 0) + { + _Lines.pop_back(); + CViewText::CLine *endLine = new CViewText::CLine; + CViewText::CWord w; + w.build(_OverflowText, *TextContext, _Scale); + endLine->addWord(w, _FontWidth); + _Lines.push_back(TLineSPtr(endLine)); + } } // Calculate size @@ -1947,10 +1951,20 @@ namespace NLGUI UTextContext::CStringInfo si; ucstring ucCurrentLine; ucCurrentLine.reserve(_Text.size()); + // Append ... to the end of line - si = TextContext->getStringInfo (ucstring("...")); - float dotWidth= si.StringWidth / _Scale; - float rWidthCurrentLine = 0, rWidthLetter; + float dotWidth; + if (_OverflowText.size() > 0) + { + si = TextContext->getStringInfo (ucstring(_OverflowText)); + dotWidth = si.StringWidth / _Scale; + } + else + { + dotWidth = 0.0f; + } + + float rWidthCurrentLine = 0, rWidthLetter; // for all the text if (_ClampRight) { @@ -1974,7 +1988,10 @@ namespace NLGUI } // Add the dots - ucCurrentLine+= "..."; + if (_OverflowText.size() > 0) + { + ucCurrentLine += _OverflowText; + } } else { @@ -1998,7 +2015,10 @@ namespace NLGUI } // Add the dots - ucCurrentLine = "..." + ucCurrentLine; + if (_OverflowText.size() > 0) + { + ucCurrentLine = _OverflowText + ucCurrentLine; + } } // And so setup this trunc text From a6b9da78fc4ec51c6a1009d8846f9454930646b1 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 14 Aug 2016 10:41:27 +0300 Subject: [PATCH 16/25] Changed: Replace icon bitmap text with a font --HG-- branch : experimental-ui-scaling --- .../client/src/interface_v3/dbctrl_sheet.cpp | 274 ++++++++++++------ .../client/src/interface_v3/dbctrl_sheet.h | 26 +- 2 files changed, 197 insertions(+), 103 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index abd85de83..2b9594db4 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -542,6 +542,15 @@ CCtrlDraggable(param) _ItemRMClassType= NULL; _ItemRMFaberStatType= NULL; _NotifyAnimEndTime = 0; + + _SheetText = NULL; + _QualityText = NULL; + _QuantityText = NULL; + _SapText = NULL; + + _QualityTextValue = -1; + _QuantityTextValue = -1; + _SapTextValue = -1; } // ---------------------------------------------------------------------------- @@ -562,6 +571,30 @@ CDBCtrlSheet::~CDBCtrlSheet() _GuildSymb = NULL; } + if (_SheetText) + { + delete _SheetText; + _SheetText = NULL; + } + + if (_QualityText) + { + delete _QualityText; + _QualityText = NULL; + } + + if (_QuantityText) + { + delete _QuantityText; + _QuantityText = NULL; + } + + if (_SapText) + { + delete _SapText; + _SapText = NULL; + } + // ensure erase static if(this==_CurrMenuSheet) _CurrMenuSheet = NULL; if(this == dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) ) @@ -1020,6 +1053,19 @@ void CDBCtrlSheet::updateCoords () } } CInterfaceElement::updateCoords(); + + if (getActive()) + { + // updateCoords() is called to apply possible UI scale change to font + if (_SheetText) + _SheetText->updateCoords(); + if (_QualityText) + _QualityText->updateCoords(); + if (_QuantityText) + _QuantityText->updateCoords(); + if (_SapText) + _SapText->updateCoords(); + } } // ---------------------------------------------------------------------------- @@ -1733,82 +1779,107 @@ sint32 CDBCtrlSheet::getSPhraseId() const // *************************************************************************** void CDBCtrlSheet::resetCharBitmaps() { - _CharBitmaps.clear(); + if (_SheetText) + _SheetText->setActive(false); + if (_QualityText) + _QualityText->setActive(false); + if (_QuantityText) + _QuantityText->setActive(false); + if (_SapText) + _SapText->setActive(false); +} + +CViewText* CDBCtrlSheet::createViewText(const std::string &id, sint fontSize) +{ + CViewText *text = new CViewText(CViewBase::TCtorParam()); + text->setActive(false); + text->setId(getId() + ":" + id); + // icon slot does not inherit from CInterfaceGroup and cannot be used as parent + text->setParent(_Parent); + text->setParentPos(_ParentPos); + text->setParentPosRef(_ParentPosRef); + text->setFontSize(fontSize); + text->setShadow(true); + text->setColor(CRGBA::White); + text->setOverflowText(ucstring("")); + text->setModulateGlobalColor(false); + text->setMultiLineSpace(0); + text->setMultiLineMaxWOnly(true); + text->setMultiLine(false); + + return text; } // *************************************************************************** void CDBCtrlSheet::setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar, bool topDown) { // Use the optString for the Macro name - _OptString = toLower(_OptString); CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = *CViewRenderer::getInstance(); - _CharBitmaps.clear(); - if(maxLine<=0) + { + if (_SheetText) + _SheetText->setActive(false); return; - - uint h = rVR.getTypoTextureH('a'); - sint lineNb = 0; - sint curLineSize = 0; - uint i; - uint xChar= 0; - for (i = 0; i < _OptString.size(); ++i) - { - char c = _OptString[i]; - sint32 w = rVR.getTypoTextureW(c); - if ((curLineSize + w) > maxW || (sint32)xChar>=maxWChar) - { - lineNb ++; - if (lineNb == maxLine) break; - curLineSize = 0; - xChar = 0; - } - sint32 id = rVR.getTypoTextureId(c); - if (id != -1) - { - CCharBitmap bmp; - bmp.X= curLineSize; - bmp.Y= lineNb; - bmp.Id= id; - _CharBitmaps.push_back(bmp); - } - curLineSize += w; - ++xChar; } - if (lineNb == maxLine) lineNb = maxLine-1; + if (!_SheetText) + _SheetText = createViewText("opt", 8); - for (i = 0; i < _CharBitmaps.size(); ++i) - { - _CharBitmaps[i].Y = (lineNb - _CharBitmaps[i].Y)*h; - } - - // if topDown, revert Y + _SheetText->setX(0); if (topDown) { - for (i = 0; i < _CharBitmaps.size(); ++i) - { - _CharBitmaps[i].Y = _IconH - _CharBitmaps[i].Y - h; - } + _SheetText->setY(_IconH); + _SheetText->setPosRef(Hotspot_TL); } + else + _SheetText->setPosRef(Hotspot_BL); + + _SheetText->setActive(true); + + ucstring txt; + txt.fromUtf8(_OptString); + _SheetText->setText(txt); + _SheetText->setLineMaxW(maxW); + _SheetText->setMultiLine(maxLine > 1); + + _SheetText->updateTextContext(); } // *************************************************************************** void CDBCtrlSheet::displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, CRGBA color) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = *CViewRenderer::getInstance(); - for (uint i = 0; i < _CharBitmaps.size(); ++i) + if (_SheetText) { - rVR.draw11RotFlipBitmap (rdrLayer, x+_CharBitmaps[i].X, y+_CharBitmaps[i].Y, 0, false, - _CharBitmaps[i].Id, color); + sint32 ClipX, ClipY, ClipW, ClipH; + rVR.getClipWindow (ClipX, ClipY, ClipW, ClipH); + + // clip region is bbox from parent + if (isIn(ClipX, ClipY, ClipW, ClipH)) + { + // position text over icon + sint32 sx = x + _SheetText->getX(); + sint32 sy = y + _SheetText->getY(); + if (_SheetText->getPosRef() & Hotspot_Tx) + sy -= _SheetText->getHReal(); + + _SheetText->setRenderLayer(rdrLayer); + _SheetText->setXReal(sx); + _SheetText->setYReal(sy); + + _SheetText->setColor(color); + + // set clip area over icon to hide oversize text + rVR.setClipWindow(sx, sy, _WReal-2, _HReal-2); + _SheetText->draw(); + rVR.setClipWindow (ClipX, ClipY, ClipW, ClipH); + } } } - // *************************************************************************** void CDBCtrlSheet::draw() { @@ -2128,7 +2199,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti if (_DispQuality != -1) { // For pact sheets, the quality gives the level of the sheet - drawNumber(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1); + drawQuality(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1); } break; case CCtrlSheetInfo::SheetType_Skill: @@ -2183,7 +2254,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Draw Quality. -1 for lookandfeel. Draw it with global color if (_DispQuality != -1) { - drawNumber(x-1,y+1,wSheet, hSheet, numberColor, _DispQuality); + drawQuality(x-1,y+1, wSheet, hSheet, numberColor, _DispQuality); } // Draw Quantity if (_UseQuantity && _DispQuantity>-1) @@ -2200,7 +2271,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti { quantity -= getLockValuePtr()->getValue32(); } - drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false); + drawQuantity(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity); } // Is the item enchanted ? sint32 enchant = _Enchant.getSInt32(); @@ -2209,7 +2280,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item) enchant--; rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor); - drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false); + drawSap(x+1, y+1, wSheet, hSheet, numberColor, enchant); } // if a raw material for example, must add special icon text. @@ -2472,7 +2543,10 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Draw Quality. -1 for lookandfeel. if( _ActualType == CCtrlSheetInfo::SheetType_SBrick ) { - if (_UseQuality && _MustDisplayLevel) drawNumber(px-1,py+1,BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel); + if (_UseQuality && _MustDisplayLevel) + { + drawQuality(px-1, py+1, BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel); + } } else { @@ -2540,51 +2614,63 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti } // ---------------------------------------------------------------------------- -sint32 CDBCtrlSheet::drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value, bool rightAlign) +sint32 CDBCtrlSheet::drawQuality(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CViewRenderer &rVR = *CViewRenderer::getInstance(); - sint32 wDigit= rVR.getFigurTextureW(); - sint32 hDigit= rVR.getFigurTextureH(); + if (!_QualityText) + _QualityText = createViewText("quality", 7); - sint32 totalWidth = 0; - - if (value > -1) + if (_QualityTextValue != value) { - // compute start pos - sint32 units = value; - sint32 pos; - if(rightAlign) - pos= wSheet-wDigit; - else - { - // compute number of digits to display - pos= 0; - uint numDigits= 0; - do - { - units = units / 10; - numDigits++; - } - while (units != 0); - // so pos is: - pos= numDigits*wDigit - wDigit; - } - // display digits - units = value; - do - { - sint32 unitsID = rVR.getFigurTextureId (units % 10); - // decal layer because must drawn after Items/Brick in DXTC - rVR.drawRotFlipBitmap (_RenderLayer+2, x+pos, y, wDigit, hDigit, 0, false, unitsID, color); - units = units / 10; - pos-= wDigit; - totalWidth += wDigit; - } - while (units != 0); - return totalWidth; + _QualityText->setText(toString(value)); + _QualityText->updateTextContext(); + _QualityTextValue = value; } - return -1; + _QualityText->setActive(true); + _QualityText->setRenderLayer(_RenderLayer + 2); + _QualityText->setXReal(x + wSheet - _QualityText->getW()); + _QualityText->setYReal(y); + _QualityText->setColor(color); + _QualityText->draw(); +} + +// ---------------------------------------------------------------------------- +sint32 CDBCtrlSheet::drawQuantity(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value) +{ + if (!_QuantityText) + _QuantityText = createViewText(getId() + ":quantity", 7); + + if (_QuantityTextValue != value) + { + _QuantityText->setText(toString(value)); + _QuantityText->updateTextContext(); + _QuantityTextValue = value; + } + _QuantityText->setActive(true); + _QuantityText->setRenderLayer(_RenderLayer + 2); + _QuantityText->setXReal(x); + _QuantityText->setYReal(y); + _QuantityText->setColor(color); + _QuantityText->draw(); +} + +// ---------------------------------------------------------------------------- +sint32 CDBCtrlSheet::drawSap(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, CRGBA color, sint32 value) +{ + if (!_SapText) + _SapText = createViewText(getId() + ":sap", 8); + + if (_SapTextValue != value) + { + _SapText->setText(toString(value)); + _SapText->updateTextContext(); + _SapTextValue = value; + } + _SapText->setActive(true); + _SapText->setRenderLayer(_RenderLayer + 2); + _SapText->setXReal(x); + _SapText->setYReal(y + hSheet - _SapText->getH()); + _SapText->setColor(color); + _SapText->draw(); } // ---------------------------------------------------------------------------- diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h index 8c697d660..880199188 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h @@ -27,6 +27,7 @@ #include "nel/gui/ctrl_draggable.h" #include "nel/gui/interface_expr.h" #include "nel/gui/action_handler.h" +#include "nel/gui/view_text.h" #include "sphrase_manager.h" // game share #include "game_share/brick_types.h" @@ -50,6 +51,7 @@ class COutpostBuildingSheet; namespace NLGUI { class CViewRenderer; + class CViewText; } @@ -589,8 +591,10 @@ protected: // setup icon from phrases void setupDisplayAsPhrase(const std::vector &bricks, const ucstring &phraseName); - // draw a number and returns the width of the drawn number - sint32 drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value, bool rightAlign=true); + // + sint32 drawQuality(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); + sint32 drawQuantity(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); + sint32 drawSap(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); protected: @@ -703,13 +707,15 @@ protected: NLMISC::CCDBNodeLeaf *_GrayedLink; - // Macro or sentence String compiled as texture Ids and positions, from the _OptString. - struct CCharBitmap - { - sint32 X,Y; - sint32 Id; - }; - std::vector _CharBitmaps; + // + CViewText *_SheetText; + CViewText *_QualityText; + CViewText *_QuantityText; + CViewText *_SapText; + // cached values for faster comparing + sint32 _QualityTextValue; + sint32 _QuantityTextValue; + sint32 _SapTextValue; // Macro Id sint32 _MacroID; @@ -753,6 +759,8 @@ private: void resetAllTexIDs(); void setupInit(); + CViewText *createViewText(const std::string &id, sint fontSize); + void setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar= 1000, bool topDown= false); void resetCharBitmaps(); void displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, NLMISC::CRGBA color); From edf755188484693f48b7d5ee7363feb7a18261e7 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 11 May 2017 11:47:30 +0300 Subject: [PATCH 17/25] Backed out changeset: 85c435fe41bb --HG-- branch : experimental-ui-scaling --- code/nel/tools/3d/build_interface/main.cpp | 30 ++++------------------ 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/code/nel/tools/3d/build_interface/main.cpp b/code/nel/tools/3d/build_interface/main.cpp index f2d3aa49c..1b13a0f71 100644 --- a/code/nel/tools/3d/build_interface/main.cpp +++ b/code/nel/tools/3d/build_interface/main.cpp @@ -201,13 +201,10 @@ int main(int nNbArg, char **ppArgs) outString ("ERROR : Wrong number of arguments\n"); outString ("USAGE : build_interface [-s] [path_maps2] [path_maps3] ....\n"); outString (" -s : build a subset of an existing interface definition while preserving the existing texture ids,"); - outString (" -b : border duplication to enable bi-linear filtering"); outString (" to support freeing up VRAM by switching to the subset without rebuilding the entire interface\n"); return -1; } - - uint borderSize = 0; - + // build as a subset of existing interface bool buildSubset = false; string existingUVfilename; @@ -218,10 +215,6 @@ int main(int nNbArg, char **ppArgs) { switch ( ppArgs[i][1] ) { - case 'B': - case 'b': - borderSize = 1; - break; case 'S': case 's': buildSubset = true; @@ -281,19 +274,6 @@ int main(int nNbArg, char **ppArgs) pBtmp->convertToType(CBitmap::RGBA); } - // duplicate bitmap border to enable bilinear filtering - { - NLMISC::CBitmap *tmp = new NLMISC::CBitmap; - tmp->resize(pBtmp->getWidth(), pBtmp->getHeight()); - tmp->blit(pBtmp, 0, 0); - // upscale image to get borders - tmp->resample(tmp->getWidth()+borderSize*2, tmp->getHeight()+borderSize*2); - // copy original - tmp->blit(pBtmp, borderSize, borderSize); - delete pBtmp; - pBtmp = tmp; - } - AllMaps[i] = pBtmp; } catch (const NLMISC::Exception &e) @@ -345,10 +325,10 @@ int main(int nNbArg, char **ppArgs) } putIn (AllMaps[i], &GlobalTexture, x, y); putIn (AllMaps[i], &GlobalMask, x, y, false); - UVMin[i].U = (float)x+borderSize; - UVMin[i].V = (float)y+borderSize; - UVMax[i].U = (float)x+borderSize+AllMaps[i]->getWidth()-borderSize*2; - UVMax[i].V = (float)y+borderSize+AllMaps[i]->getHeight()-borderSize*2; + UVMin[i].U = (float)x; + UVMin[i].V = (float)y; + UVMax[i].U = (float)x+AllMaps[i]->getWidth(); + UVMax[i].V = (float)y+AllMaps[i]->getHeight(); /* // Do not remove this is useful for debugging { From 4c605fcfe0618bd19771b67c3ef42fa73dd017cf Mon Sep 17 00:00:00 2001 From: Nimetu Date: Thu, 11 May 2017 11:48:05 +0300 Subject: [PATCH 18/25] Backed out changeset: da24b99ddf3d --HG-- branch : experimental-ui-scaling --- .../client/src/interface_v3/dbctrl_sheet.cpp | 274 ++++++------------ .../client/src/interface_v3/dbctrl_sheet.h | 26 +- 2 files changed, 103 insertions(+), 197 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 2b9594db4..abd85de83 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -542,15 +542,6 @@ CCtrlDraggable(param) _ItemRMClassType= NULL; _ItemRMFaberStatType= NULL; _NotifyAnimEndTime = 0; - - _SheetText = NULL; - _QualityText = NULL; - _QuantityText = NULL; - _SapText = NULL; - - _QualityTextValue = -1; - _QuantityTextValue = -1; - _SapTextValue = -1; } // ---------------------------------------------------------------------------- @@ -571,30 +562,6 @@ CDBCtrlSheet::~CDBCtrlSheet() _GuildSymb = NULL; } - if (_SheetText) - { - delete _SheetText; - _SheetText = NULL; - } - - if (_QualityText) - { - delete _QualityText; - _QualityText = NULL; - } - - if (_QuantityText) - { - delete _QuantityText; - _QuantityText = NULL; - } - - if (_SapText) - { - delete _SapText; - _SapText = NULL; - } - // ensure erase static if(this==_CurrMenuSheet) _CurrMenuSheet = NULL; if(this == dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) ) @@ -1053,19 +1020,6 @@ void CDBCtrlSheet::updateCoords () } } CInterfaceElement::updateCoords(); - - if (getActive()) - { - // updateCoords() is called to apply possible UI scale change to font - if (_SheetText) - _SheetText->updateCoords(); - if (_QualityText) - _QualityText->updateCoords(); - if (_QuantityText) - _QuantityText->updateCoords(); - if (_SapText) - _SapText->updateCoords(); - } } // ---------------------------------------------------------------------------- @@ -1779,107 +1733,82 @@ sint32 CDBCtrlSheet::getSPhraseId() const // *************************************************************************** void CDBCtrlSheet::resetCharBitmaps() { - if (_SheetText) - _SheetText->setActive(false); - if (_QualityText) - _QualityText->setActive(false); - if (_QuantityText) - _QuantityText->setActive(false); - if (_SapText) - _SapText->setActive(false); -} - -CViewText* CDBCtrlSheet::createViewText(const std::string &id, sint fontSize) -{ - CViewText *text = new CViewText(CViewBase::TCtorParam()); - text->setActive(false); - text->setId(getId() + ":" + id); - // icon slot does not inherit from CInterfaceGroup and cannot be used as parent - text->setParent(_Parent); - text->setParentPos(_ParentPos); - text->setParentPosRef(_ParentPosRef); - text->setFontSize(fontSize); - text->setShadow(true); - text->setColor(CRGBA::White); - text->setOverflowText(ucstring("")); - text->setModulateGlobalColor(false); - text->setMultiLineSpace(0); - text->setMultiLineMaxWOnly(true); - text->setMultiLine(false); - - return text; + _CharBitmaps.clear(); } // *************************************************************************** void CDBCtrlSheet::setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar, bool topDown) { // Use the optString for the Macro name + _OptString = toLower(_OptString); CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = *CViewRenderer::getInstance(); + _CharBitmaps.clear(); + if(maxLine<=0) - { - if (_SheetText) - _SheetText->setActive(false); return; + + uint h = rVR.getTypoTextureH('a'); + sint lineNb = 0; + sint curLineSize = 0; + uint i; + uint xChar= 0; + for (i = 0; i < _OptString.size(); ++i) + { + char c = _OptString[i]; + sint32 w = rVR.getTypoTextureW(c); + if ((curLineSize + w) > maxW || (sint32)xChar>=maxWChar) + { + lineNb ++; + if (lineNb == maxLine) break; + curLineSize = 0; + xChar = 0; + } + sint32 id = rVR.getTypoTextureId(c); + if (id != -1) + { + CCharBitmap bmp; + bmp.X= curLineSize; + bmp.Y= lineNb; + bmp.Id= id; + _CharBitmaps.push_back(bmp); + } + curLineSize += w; + ++xChar; } - if (!_SheetText) - _SheetText = createViewText("opt", 8); + if (lineNb == maxLine) lineNb = maxLine-1; - _SheetText->setX(0); + for (i = 0; i < _CharBitmaps.size(); ++i) + { + _CharBitmaps[i].Y = (lineNb - _CharBitmaps[i].Y)*h; + } + + // if topDown, revert Y if (topDown) { - _SheetText->setY(_IconH); - _SheetText->setPosRef(Hotspot_TL); + for (i = 0; i < _CharBitmaps.size(); ++i) + { + _CharBitmaps[i].Y = _IconH - _CharBitmaps[i].Y - h; + } } - else - _SheetText->setPosRef(Hotspot_BL); - - _SheetText->setActive(true); - - ucstring txt; - txt.fromUtf8(_OptString); - _SheetText->setText(txt); - _SheetText->setLineMaxW(maxW); - _SheetText->setMultiLine(maxLine > 1); - - _SheetText->updateTextContext(); } // *************************************************************************** void CDBCtrlSheet::displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, CRGBA color) { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = *CViewRenderer::getInstance(); - if (_SheetText) + for (uint i = 0; i < _CharBitmaps.size(); ++i) { - sint32 ClipX, ClipY, ClipW, ClipH; - rVR.getClipWindow (ClipX, ClipY, ClipW, ClipH); - - // clip region is bbox from parent - if (isIn(ClipX, ClipY, ClipW, ClipH)) - { - // position text over icon - sint32 sx = x + _SheetText->getX(); - sint32 sy = y + _SheetText->getY(); - if (_SheetText->getPosRef() & Hotspot_Tx) - sy -= _SheetText->getHReal(); - - _SheetText->setRenderLayer(rdrLayer); - _SheetText->setXReal(sx); - _SheetText->setYReal(sy); - - _SheetText->setColor(color); - - // set clip area over icon to hide oversize text - rVR.setClipWindow(sx, sy, _WReal-2, _HReal-2); - _SheetText->draw(); - rVR.setClipWindow (ClipX, ClipY, ClipW, ClipH); - } + rVR.draw11RotFlipBitmap (rdrLayer, x+_CharBitmaps[i].X, y+_CharBitmaps[i].Y, 0, false, + _CharBitmaps[i].Id, color); } } + // *************************************************************************** void CDBCtrlSheet::draw() { @@ -2199,7 +2128,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti if (_DispQuality != -1) { // For pact sheets, the quality gives the level of the sheet - drawQuality(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1); + drawNumber(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1); } break; case CCtrlSheetInfo::SheetType_Skill: @@ -2254,7 +2183,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Draw Quality. -1 for lookandfeel. Draw it with global color if (_DispQuality != -1) { - drawQuality(x-1,y+1, wSheet, hSheet, numberColor, _DispQuality); + drawNumber(x-1,y+1,wSheet, hSheet, numberColor, _DispQuality); } // Draw Quantity if (_UseQuantity && _DispQuantity>-1) @@ -2271,7 +2200,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti { quantity -= getLockValuePtr()->getValue32(); } - drawQuantity(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity); + drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false); } // Is the item enchanted ? sint32 enchant = _Enchant.getSInt32(); @@ -2280,7 +2209,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item) enchant--; rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor); - drawSap(x+1, y+1, wSheet, hSheet, numberColor, enchant); + drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false); } // if a raw material for example, must add special icon text. @@ -2543,10 +2472,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // Draw Quality. -1 for lookandfeel. if( _ActualType == CCtrlSheetInfo::SheetType_SBrick ) { - if (_UseQuality && _MustDisplayLevel) - { - drawQuality(px-1, py+1, BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel); - } + if (_UseQuality && _MustDisplayLevel) drawNumber(px-1,py+1,BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel); } else { @@ -2614,63 +2540,51 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti } // ---------------------------------------------------------------------------- -sint32 CDBCtrlSheet::drawQuality(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value) +sint32 CDBCtrlSheet::drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value, bool rightAlign) { - if (!_QualityText) - _QualityText = createViewText("quality", 7); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CViewRenderer &rVR = *CViewRenderer::getInstance(); + sint32 wDigit= rVR.getFigurTextureW(); + sint32 hDigit= rVR.getFigurTextureH(); - if (_QualityTextValue != value) + sint32 totalWidth = 0; + + if (value > -1) { - _QualityText->setText(toString(value)); - _QualityText->updateTextContext(); - _QualityTextValue = value; + // compute start pos + sint32 units = value; + sint32 pos; + if(rightAlign) + pos= wSheet-wDigit; + else + { + // compute number of digits to display + pos= 0; + uint numDigits= 0; + do + { + units = units / 10; + numDigits++; + } + while (units != 0); + // so pos is: + pos= numDigits*wDigit - wDigit; + } + // display digits + units = value; + do + { + sint32 unitsID = rVR.getFigurTextureId (units % 10); + // decal layer because must drawn after Items/Brick in DXTC + rVR.drawRotFlipBitmap (_RenderLayer+2, x+pos, y, wDigit, hDigit, 0, false, unitsID, color); + units = units / 10; + pos-= wDigit; + totalWidth += wDigit; + } + while (units != 0); + return totalWidth; } - _QualityText->setActive(true); - _QualityText->setRenderLayer(_RenderLayer + 2); - _QualityText->setXReal(x + wSheet - _QualityText->getW()); - _QualityText->setYReal(y); - _QualityText->setColor(color); - _QualityText->draw(); -} - -// ---------------------------------------------------------------------------- -sint32 CDBCtrlSheet::drawQuantity(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value) -{ - if (!_QuantityText) - _QuantityText = createViewText(getId() + ":quantity", 7); - - if (_QuantityTextValue != value) - { - _QuantityText->setText(toString(value)); - _QuantityText->updateTextContext(); - _QuantityTextValue = value; - } - _QuantityText->setActive(true); - _QuantityText->setRenderLayer(_RenderLayer + 2); - _QuantityText->setXReal(x); - _QuantityText->setYReal(y); - _QuantityText->setColor(color); - _QuantityText->draw(); -} - -// ---------------------------------------------------------------------------- -sint32 CDBCtrlSheet::drawSap(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, CRGBA color, sint32 value) -{ - if (!_SapText) - _SapText = createViewText(getId() + ":sap", 8); - - if (_SapTextValue != value) - { - _SapText->setText(toString(value)); - _SapText->updateTextContext(); - _SapTextValue = value; - } - _SapText->setActive(true); - _SapText->setRenderLayer(_RenderLayer + 2); - _SapText->setXReal(x); - _SapText->setYReal(y + hSheet - _SapText->getH()); - _SapText->setColor(color); - _SapText->draw(); + return -1; } // ---------------------------------------------------------------------------- diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h index 880199188..8c697d660 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h @@ -27,7 +27,6 @@ #include "nel/gui/ctrl_draggable.h" #include "nel/gui/interface_expr.h" #include "nel/gui/action_handler.h" -#include "nel/gui/view_text.h" #include "sphrase_manager.h" // game share #include "game_share/brick_types.h" @@ -51,7 +50,6 @@ class COutpostBuildingSheet; namespace NLGUI { class CViewRenderer; - class CViewText; } @@ -591,10 +589,8 @@ protected: // setup icon from phrases void setupDisplayAsPhrase(const std::vector &bricks, const ucstring &phraseName); - // - sint32 drawQuality(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); - sint32 drawQuantity(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); - sint32 drawSap(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value); + // draw a number and returns the width of the drawn number + sint32 drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 hSheet, NLMISC::CRGBA color, sint32 value, bool rightAlign=true); protected: @@ -707,15 +703,13 @@ protected: NLMISC::CCDBNodeLeaf *_GrayedLink; - // - CViewText *_SheetText; - CViewText *_QualityText; - CViewText *_QuantityText; - CViewText *_SapText; - // cached values for faster comparing - sint32 _QualityTextValue; - sint32 _QuantityTextValue; - sint32 _SapTextValue; + // Macro or sentence String compiled as texture Ids and positions, from the _OptString. + struct CCharBitmap + { + sint32 X,Y; + sint32 Id; + }; + std::vector _CharBitmaps; // Macro Id sint32 _MacroID; @@ -759,8 +753,6 @@ private: void resetAllTexIDs(); void setupInit(); - CViewText *createViewText(const std::string &id, sint fontSize); - void setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar= 1000, bool topDown= false); void resetCharBitmaps(); void displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, NLMISC::CRGBA color); From ddcdc8b8fb03c704ee7d6416b5ced4a7f1958373 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 16 Dec 2016 00:03:30 +0200 Subject: [PATCH 19/25] Added: Border duplication option to texture atlas builder. --HG-- branch : experimental-ui-scaling --- code/nel/tools/3d/build_interface/main.cpp | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/3d/build_interface/main.cpp b/code/nel/tools/3d/build_interface/main.cpp index a8f854721..58c97e513 100644 --- a/code/nel/tools/3d/build_interface/main.cpp +++ b/code/nel/tools/3d/build_interface/main.cpp @@ -214,6 +214,7 @@ int main(int argc, char **argv) args.addArg("x", "extract", "", "Extract all interface elements from to ."); args.addAdditionalArg("output_filename", "PNG or TGA file to generate", true); args.addAdditionalArg("input_path", "Path that containts interfaces elements", false); + args.addArg("b", "border", "", "Duplicate icon border to allow bilinear filtering"); if (!args.parse(argc, argv)) return 1; @@ -227,6 +228,13 @@ int main(int argc, char **argv) existingUVfilename = args.getArg("s").front(); } + // + uint borderSize = 0; + if (args.haveArg("b")) + { + borderSize = 1; + } + // extract all interface elements bool extractElements = args.haveArg("x"); @@ -407,6 +415,18 @@ int main(int argc, char **argv) pBtmp->convertToType(CBitmap::RGBA); } + // duplicate icon border + if (borderSize > 0) + { + NLMISC::CBitmap *tmp = new NLMISC::CBitmap; + tmp->resize(pBtmp->getWidth(), pBtmp->getHeight()); + tmp->blit(pBtmp, 0, 0); + tmp->resample(tmp->getWidth() + borderSize * 2, tmp->getHeight() + borderSize * 2); + tmp->blit(pBtmp, borderSize, borderSize); + delete pBtmp; + pBtmp = tmp; + } + AllMaps[i] = pBtmp; } catch (const NLMISC::Exception &e) @@ -461,10 +481,10 @@ int main(int argc, char **argv) putIn (AllMaps[i], &GlobalTexture, x, y); putIn (AllMaps[i], &GlobalMask, x, y, false); - UVMin[i].U = (float)x; - UVMin[i].V = (float)y; - UVMax[i].U = (float)x+AllMaps[i]->getWidth(); - UVMax[i].V = (float)y+AllMaps[i]->getHeight(); + UVMin[i].U = (float)x + borderSize; + UVMin[i].V = (float)y + borderSize; + UVMax[i].U = (float)x + AllMaps[i]->getWidth() - borderSize; + UVMax[i].V = (float)y + AllMaps[i]->getHeight() - borderSize; #if 0 // Do not remove this is useful for debugging From 4ba39732954b5c8a7cc941fb0c302e9ca4ecdfc1 Mon Sep 17 00:00:00 2001 From: "nimetu@gmail.com" Date: Fri, 16 Mar 2018 15:00:30 +0200 Subject: [PATCH 20/25] Changed: Remove ui scale option from ingame config --HG-- branch : experimental-ui-scaling --- .../data/gamedev/interfaces_v3/game_config.xml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml index c3b904f01..2728e7854 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/game_config.xml @@ -876,17 +876,10 @@ posparent="lum" x="0" y="-2" /> - @@ -3098,13 +3091,6 @@ realtime="true" widget="sbfloat" link="Gamma" /> - Date: Fri, 16 Mar 2018 15:01:22 +0200 Subject: [PATCH 21/25] Added: Allow to set UI scale with /setuiscale command --HG-- branch : experimental-ui-scaling --- .../data/gamedev/interfaces_v3/commands.xml | 2 ++ code/ryzom/client/src/client_cfg.cpp | 3 +- code/ryzom/client/src/client_cfg.h | 3 ++ .../src/interface_v3/action_handler_game.cpp | 28 +++++++++++++++++++ .../src/interface_v3/interface_manager.cpp | 4 +-- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml index 31a1a7099..6b45ec715 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml @@ -122,6 +122,8 @@ + + diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index c21797def..14741b7ad 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -839,8 +839,7 @@ void CClientConfig::setValues() READ_FLOAT_FV(Gamma) // UI scaling READ_FLOAT_FV(InterfaceScale); - // 50% smaller / 2x bigger - clamp(ClientCfg.InterfaceScale, 0.5f, 2.0f); + clamp(ClientCfg.InterfaceScale, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE); READ_BOOL_FV(BilinearUI); // 3D Driver varPtr = ClientCfg.ConfigFile.getVarPtr ("Driver3D"); diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index accc5ae1e..9b24f3058 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -46,6 +46,9 @@ using NLMISC::CVector; using NLMISC::CRGBA; using std::string; +// limits for UI scale +const float MIN_INTERFACE_SCALE = 0.8; +const float MAX_INTERFACE_SCALE = 2.0; //--------------------------------------------------- // CClientConfig : diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp index 196b0a45e..f1b27bb46 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp @@ -3732,6 +3732,34 @@ class CHandlerGameConfigChangeScreenRatioCustom : public IActionHandler }; REGISTER_ACTION_HANDLER (CHandlerGameConfigChangeScreenRatioCustom, "game_config_change_screen_ratio_custom"); +// *************************************************************************** +class CHandlerSetInterfaceScale : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const string &Params) + { + std::string s; + s = getParam(Params, "scale"); + if (!s.empty()) { + float scale; + if (fromString(s, scale)) + { + if (scale >= MIN_INTERFACE_SCALE && scale <= MAX_INTERFACE_SCALE) + { + ClientCfg.InterfaceScale = scale; + ClientCfg.writeDouble("InterfaceScale", ClientCfg.InterfaceScale); + + ClientCfg.IsInvalidated = true; + return; + } + } + } + + ucstring help("/setuiscale "+toString("%.1f .. %.1f", MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE)); + CInterfaceManager::getInstance()->displaySystemInfo(help); + } +}; +REGISTER_ACTION_HANDLER (CHandlerSetInterfaceScale, "set_ui_scale"); + // *************************************************************************** class CHandlerGameMissionAbandon : public IActionHandler diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 221ae0671..a63d4b5ac 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -2038,8 +2038,7 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera) _CurrentPlayerCharac[i] = node ? node->getValue32() : 0; } - // update value change from ingame config window - // must update it here, right before widget manager checks it + // scale must be updated right before widget manager checks it if (_InterfaceScaleChanged) { CViewRenderer::getInstance()->setInterfaceScale(_InterfaceScale); @@ -2916,7 +2915,6 @@ NLMISC_COMMAND(loadui, "Load an interface file", "") return result; } - // *************************************************************************** void CInterfaceManager::displayWebWindow(const string & name, const string & url) { From d7ee45021533c94ccb671e5655368201689699cb Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sat, 17 Mar 2018 13:59:42 +0200 Subject: [PATCH 22/25] Changed: Use user requested resolution for both char select and ingame --HG-- branch : experimental-ui-scaling --- code/ryzom/client/src/connection.cpp | 36 ++++------------------------ 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 20c424688..92fce64f8 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -256,41 +256,13 @@ REGISTER_ACTION_HANDLER (CAHOnReloadTestPage, "on_reload_test_page"); // ------------------------------------------------------------------------------------------------ void setOutGameFullScreen() { - // Setup full screen (special 1024x768 for outgame) if we have to. - // NB: don't setup fullscreen if player wants to play in window if (!ClientCfg.Local && ClientCfg.SelectCharacter == -1) { if (StereoDisplayAttached) StereoDisplay->detachFromDisplay(); StereoDisplayAttached = false; - UDriver::CMode currMode; - Driver->getCurrentScreenMode(currMode); - UDriver::CMode wantedMode; - wantedMode.Windowed = true; - wantedMode.Width = 1024; - wantedMode.Height = 768; - wantedMode.Depth = uint8(ClientCfg.Depth); - wantedMode.Frequency = ClientCfg.Frequency; - - // change mode only if necessary - if ((wantedMode.Windowed != currMode.Windowed) || - (wantedMode.Width != currMode.Width) || - (wantedMode.Height != currMode.Height)) - { - setVideoMode(wantedMode); - } - InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); - /* - InitMouseWithCursor (true); - Driver->showCursor(false); - Driver->showCursor(true); - Driver->clearBuffers(CRGBA::Black); - Driver->swapBuffers(); - Driver->showCursor(false); - Driver->showCursor(true); - */ } // Enable auto scaling in login window @@ -312,8 +284,8 @@ bool connection (const string &cookie, const string &fsaddr) game_exit = false; - // Setup full screen (special 1024x768 for outgame) if we have to. - setOutGameFullScreen(); + // set resolution from cfg after login + connectionRestoreVideoMode (); // Preload continents { @@ -347,13 +319,14 @@ bool connection (const string &cookie, const string &fsaddr) // init the string manager cache. STRING_MANAGER::CStringManagerClient::instance()->initCache("", ClientCfg.LanguageCode); // VOIR BORIS #endif - connectionRestoreVideoMode (); return true; } ProgressBar.setFontFactor(1.0f); // Init out game + setOutGameFullScreen(); + ucstring nmsg("Initializing outgame..."); ProgressBar.newMessage (ClientCfg.buildLoadingString(nmsg) ); pIM->initOutGame(); @@ -492,7 +465,6 @@ bool reconnection() game_exit = false; - // Setup full screen (special 1024x768 for outgame) if we have to. setOutGameFullScreen(); // Preload continents From 1c142ef968800e27d1577f730f681c0f1bbe42ad Mon Sep 17 00:00:00 2001 From: Nimetu Date: Fri, 22 Jun 2018 19:44:12 +0300 Subject: [PATCH 23/25] Fixed: Font size calculations for scaled text. --HG-- branch : experimental-ui-scaling --- code/nel/include/nel/gui/view_text.h | 12 +- code/nel/src/gui/group_editbox.cpp | 12 +- code/nel/src/gui/view_text.cpp | 265 ++++++++++-------- .../src/interface_v3/action_handler_edit.cpp | 18 +- 4 files changed, 166 insertions(+), 141 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index e5c5d7e10..ad5a30f2a 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -129,6 +129,8 @@ namespace NLGUI uint getFontHeight() const; // get current font leg height, in pixels uint getFontLegHeight() const; + // get current line height, in pixels + float getLineHeight() const; // Set the display mode (supported with multiline only for now) void setTextMode(TTextMode mode); TTextMode getTextMode() const { return _TextMode; } @@ -149,11 +151,11 @@ namespace NLGUI * When looking at standard edit box, we see that if a line is split accross to line with no * This also returns the height of the line */ - void getCharacterPositionFromIndex(sint index, bool lineEnd, sint &x, sint &y, sint &height) const; + void getCharacterPositionFromIndex(sint index, bool lineEnd, float &x, float &y, float &height) const; /** From a coordinate relative to the BR BR corner of the text, return the index of a character. * If no character is found at the given position, the closest character is returned (first or last character, for the line or the whole text) */ - void getCharacterIndexFromPosition(sint x, sint y, uint &index, bool &lineEnd) const; + void getCharacterIndexFromPosition(float x, float y, uint &index, bool &lineEnd) const; /** From a character index, get the index of the line it belongs to, or -1 if the index is invalid * \param cursorDisplayedAtEndOfPreviousLine true if the cursor is displayed at the end of the previous line that match its index */ @@ -330,7 +332,7 @@ namespace NLGUI CFormatInfo Format; public: // build from a string, using the current text context - void build(const ucstring &text, NL3D::UTextContext &textContext, float scale, uint numSpaces= 0); + void build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces= 0); }; typedef std::vector TWordVect; @@ -343,7 +345,7 @@ namespace NLGUI // Clear the line & remove text contexts 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, float fontWidth, NL3D::UTextContext &textContext, float scale); + void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext); void addWord(const CWord &word, float fontWidth); uint getNumWords() const { return (uint)_Words.size(); } CWord &getWord(uint index) { return _Words[index]; } @@ -404,7 +406,7 @@ namespace NLGUI uint _TextSelectionEnd; // First line X coordinate - sint _FirstLineX; + float _FirstLineX; /// Dynamic tooltips std::vector _Tooltips; diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index 13979f4aa..1a800b23a 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -702,9 +702,9 @@ namespace NLGUI sint32 maxPos= max(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length(); // get its position on screen - sint cxMinPos, cyMinPos; - sint cxMaxPos, cyMaxPos; - sint height; + float cxMinPos, cyMinPos; + float cxMaxPos, cyMaxPos; + float height; _ViewText->getCharacterPositionFromIndex(minPos, false, cxMinPos, cyMinPos, height); _ViewText->getCharacterPositionFromIndex(maxPos, false, cxMaxPos, cyMaxPos, height); @@ -755,8 +755,8 @@ namespace NLGUI if (_BlinkState) // is the cursor shown ? { // get its position on screen - sint cx, cy; - sint height; + float cx, cy; + float height; _ViewText->getCharacterPositionFromIndex(_CursorPos + (sint)_Prompt.length(), _CursorAtPreviousLineEnd, cx, cy, height); // display the cursor // get the texture for the cursor @@ -1482,7 +1482,7 @@ namespace NLGUI if (_ViewText->getWReal() > _WReal) { // Check if cursor visible - sint xCursVT, xCurs, yTmp, hTmp; + float xCursVT, xCurs, yTmp, hTmp; // Get the cursor pos from the BL of the viewtext _ViewText->getCharacterPositionFromIndex(_CursorPos+(sint)_Prompt.size(), false, xCursVT, yTmp, hTmp); // Get the cursor pos from the BL of the edit box diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 881b4fa5d..f9403014e 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -957,8 +957,31 @@ namespace NLGUI CViewRenderer &rVR = *CViewRenderer::getInstance(); +#if 0 //rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(64,64,64,255)); + // debug text with mouse hover + if(CWidgetManager::getInstance()->getPointer()) + { + // but must check first if mouse is over + sint32 x = CWidgetManager::getInstance()->getPointer()->getX(); + sint32 y = CWidgetManager::getInstance()->getPointer()->getY(); + bool mouseIn; + // use parent clip or self clip? + if(_OverExtendViewTextUseParentRect) + mouseIn= _Parent && _Parent->isIn(x,y); + else + mouseIn= isIn(x,y); + // if the mouse cursor is in the clip area + if(mouseIn) { + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255)); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_HReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255)); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255)); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255)); + } + } +#endif + // *** Out Of Clip? sint32 ClipX, ClipY, ClipW, ClipH; rVR.getClipWindow (ClipX, ClipY, ClipW, ClipH); @@ -1003,19 +1026,12 @@ namespace NLGUI TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); - float y = _YReal; - //y += _LinesInfos[_LinesInfos.size()-1].StringLine / h; - // Y is the base line of the string, so it must be grown up. - y += _FontLegHeight; - - sint y_line = _YReal+_FontLegHeight-2.0f*_Scale; + float y = _YReal * _Scale + _FontLegHeight; if (_MultiMinLine > _Lines.size()) { - uint dy = getMultiMinOffsetY(); - y += dy; - y_line += dy; + y += getMultiMinOffsetY() * _Scale; } // special selection code @@ -1056,7 +1072,7 @@ namespace NLGUI { CLine &currLine = *_Lines[i]; // current x position - float px = (float) (_XReal + ((i==0) ? (sint)_FirstLineX : 0)); + float px = (float) (_XReal * _Scale + ((i==0) ? (sint)_FirstLineX : 0)); // draw each words of the line for(uint k = 0; k < currLine.getNumWords(); ++k) { @@ -1083,24 +1099,25 @@ namespace NLGUI px += firstSpace; // skip tabulation before current word if(currWord.Format.TabX) - px= max(px, (float)(_XReal + currWord.Format.TabX*_FontWidth)); + px= max(px, (float)(_XReal * _Scale + currWord.Format.TabX*_FontWidth)); // draw. We take floorf px to avoid filtering of letters that are not located on a pixel boundary - rVR.drawText (_RenderLayer, px, y, currWord.Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); + float fx = px / _Scale; + float fy = y / _Scale; + rVR.drawText (_RenderLayer, fx, fy, currWord.Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, fx, fy - _FontLegHeight*0.3f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); if (_StrikeThrough) - rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, fx, fy + _FontHeight*0.2f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); // skip word px += currWord.Info.StringWidth; } // go one line up - y += (_FontHeight + _MultiLineSpace); - y_line += _FontHeight+_MultiLineSpace; + y += (_FontHeight + _MultiLineSpace * _Scale); } // reset selection @@ -1134,10 +1151,8 @@ namespace NLGUI TextContext->setLetterColors(_LetterColors, _Index); } - float y = _YReal; - // Y is the base line of the string, so it must be grown up. - y += _FontLegHeight; + float y = _YReal * _Scale + _FontLegHeight; // special selection code if(_TextSelection) @@ -1148,14 +1163,14 @@ namespace NLGUI TextContext->setStringColor(_Index, col); // draw - rVR.drawText (_RenderLayer, _XReal, y, _Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); + rVR.drawText (_RenderLayer, _XReal, y / _Scale, _Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext); // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2.0f*_Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal - _FontLegHeight*0.3f/_Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); if (_StrikeThrough) - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+(_FontLegHeight/2), _WReal, 1, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal + _FontHeight*0.2f / _Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col); // reset selection if(_TextSelection) @@ -1204,7 +1219,6 @@ namespace NLGUI } } } - } // *************************************************************************** @@ -1344,6 +1358,7 @@ namespace NLGUI // *************************************************************************** void CViewText::setLineMaxW (sint nMaxW, bool invalidate) { + nMaxW *= _Scale; if(_LineMaxW!=nMaxW) { _LineMaxW = nMaxW; @@ -1395,19 +1410,25 @@ namespace NLGUI // *************************************************************************** uint CViewText::getFontWidth() const { - return _FontWidth; + return _FontWidth / _Scale; } // *************************************************************************** uint CViewText::getFontHeight() const { - return _FontHeight; + return _FontHeight / _Scale; } // *************************************************************************** uint CViewText::getFontLegHeight() const { - return _FontLegHeight; + return _FontLegHeight / _Scale; + } + + // *************************************************************************** + float CViewText::getLineHeight() const + { + return _FontHeight / _Scale + _MultiLineSpace; } // *************************************************************************** @@ -1418,7 +1439,7 @@ namespace NLGUI { // first line is always present even if _Lines is empty uint nbLines = _MultiMinLine - std::max((sint)1, (sint)_Lines.size()); - dy = nbLines * _FontHeight + (nbLines - 1) * _MultiLineSpace; + dy = (nbLines * _FontHeight + (nbLines - 1) * _MultiLineSpace * _Scale) / _Scale; } return dy; } @@ -1434,7 +1455,7 @@ namespace NLGUI linePushed= true; } // Append to the last line - _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth, *TextContext, _Scale); + _Lines.back()->addWord(ucCurrentWord, 0, wordFormat, _FontWidth, *TextContext); // reset the word ucCurrentWord.clear(); } @@ -1450,11 +1471,12 @@ namespace NLGUI ucstring ucCurrentWord; CFormatInfo wordFormat; // line state - float rWidthCurrentLine = 0, rWidthLetter; + float rWidthCurrentLine = 0; bool linePushed= false; // for all the text uint textSize= (uint)_Text.size(); uint formatTagIndex= 0; + nMaxWidth *= _Scale; for (i = 0; i < textSize; ++i) { if(isFormatTagChange(i, formatTagIndex)) @@ -1487,21 +1509,20 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth / _Scale); - if ((rWidthCurrentLine + rWidthLetter) > nMaxWidth) + if ((rWidthCurrentLine + si.StringWidth) > nMaxWidth) { flushWordInLine(ucCurrentWord, linePushed, wordFormat); // reset line state, and begin with the cut letter linePushed= false; - rWidthCurrentLine = rWidthLetter; + rWidthCurrentLine = si.StringWidth; ucCurrentWord = ucLetter; } else { // Grow the current word ucCurrentWord += ucLetter; - rWidthCurrentLine += rWidthLetter; + rWidthCurrentLine += si.StringWidth; } } } @@ -1531,7 +1552,7 @@ namespace NLGUI if(currLine[i].Format!=lineWordFormat) { // add the current lineWord to the line. - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext, _Scale); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); // get new lineWordFormat lineWordFormat= currLine[i].Format; // and clear @@ -1546,7 +1567,7 @@ namespace NLGUI } if(!lineWord.empty()) - _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext, _Scale); + _Lines.back()->addWord(lineWord, 0, lineWordFormat, _FontWidth, *TextContext); // clear currLine.clear(); @@ -1564,7 +1585,7 @@ namespace NLGUI static const ucstring spaceStr(" "); // precLineWidth valid only id precedent line is part of same paragraph. float precLineWidth= 0; - float lineWidth = (float)_FirstLineX * _Scale; // width of the current line + float lineWidth = (float)_FirstLineX; // width of the current line uint numWordsInLine = 0; // number of words in the current line bool isParagraphStart = true; // A paragraph is a group of characters between 2 \n bool lineFeed; @@ -1575,6 +1596,7 @@ namespace NLGUI CFormatInfo wordFormat; uint formatTagIndex= 0; // + nMaxWidth *= _Scale; while (currPos != _Text.length()) { TCharPos spaceEnd; @@ -1655,7 +1677,7 @@ namespace NLGUI // compute size of spaces/Tab + word newLineWidth = lineWidth + numSpaces * _SpaceWidth; newLineWidth = max(newLineWidth, (float)wordFormat.TabX*_FontWidth); - newLineWidth+= si.StringWidth / _Scale; + newLineWidth+= si.StringWidth; } // // Does the word go beyond the end of line ? @@ -1707,7 +1729,7 @@ namespace NLGUI { uint maxNumSpaces = std::max(1U, (uint) (nMaxWidth / _SpaceWidth)); CWord spaceWord; // a word with only spaces in it - spaceWord.build (ucstring (""), *TextContext, _Scale, maxNumSpaces); + spaceWord.build (ucstring (""), *TextContext, maxNumSpaces); spaceWord.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); _Lines.back()->addWord(spaceWord, _FontWidth); @@ -1730,13 +1752,13 @@ namespace NLGUI { oneChar = wordValue[currChar]; si = TextContext->getStringInfo(oneChar); - if ((uint) (px + si.StringWidth / _Scale) > nMaxWidth) break; - px += si.StringWidth / _Scale; + 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, *TextContext, _Scale, numSpaces); + word.build(wordValue, *TextContext, numSpaces); word.Format= wordFormat; _Lines.push_back(TLineSPtr(new CLine)); float roomForSpaces = (float) nMaxWidth - word.Info.StringWidth; @@ -1771,7 +1793,7 @@ namespace NLGUI if (!wordValue.empty() || numSpaces != 0) { CWord word; - word.build(wordValue, *TextContext, _Scale, numSpaces); + word.build(wordValue, *TextContext, numSpaces); word.Format= wordFormat; // update line width _Lines.back()->addWord(word, _FontWidth); @@ -1890,24 +1912,25 @@ namespace NLGUI _Lines.pop_back(); CViewText::CLine *endLine = new CViewText::CLine; CViewText::CWord w; - w.build(_OverflowText, *TextContext, _Scale); + w.build(_OverflowText, *TextContext); endLine->addWord(w, _FontWidth); _Lines.push_back(TLineSPtr(endLine)); } } // Calculate size + float rMultiLineSpace = _MultiLineSpace * _Scale; float rTotalW = 0; for (uint i = 0; i < _Lines.size(); ++i) { rTotalW = std::max(_Lines[i]->getWidth() + ((i==0)?_FirstLineX:0), rTotalW); } - _W = (sint)ceilf(rTotalW); - _H = std::max(_FontHeight, ceilf(_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * _MultiLineSpace)); + _W = (sint)ceilf(rTotalW / _Scale); + _H = std::max(_FontHeight / _Scale, ceilf((_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * rMultiLineSpace) / _Scale)); // See if we should pretend to have at least X lines if (_MultiMinLine > 1) - _H = std::max(_H, sint(_FontHeight * _MultiMinLine + (_MultiMinLine - 1) * _MultiLineSpace)); + _H = std::max(_H, sint((_FontHeight * _MultiMinLine + (_MultiMinLine - 1) * rMultiLineSpace)/_Scale)); // Compute tooltips size if (!_Tooltips.empty()) @@ -1916,7 +1939,6 @@ namespace NLGUI for (uint j=0 ; j<_Lines[i]->getNumWords() ; ++j) { CWord word = _Lines[i]->getWord(j); - // float w = _Lines[i]->getWidth(); if (word.Format.IndexTt != -1) { @@ -1924,7 +1946,7 @@ namespace NLGUI { CCtrlToolTip *pTooltip = _Tooltips[word.Format.IndexTt]; - sint y = (sint) ceilf((_FontHeight + _MultiLineSpace) * (_Lines.size() - i - 1)); + sint y = (sint) ceilf(((_FontHeight + rMultiLineSpace) * (_Lines.size() - i - 1))/_Scale); pTooltip->setX(0); pTooltip->setY(y); @@ -1943,11 +1965,10 @@ namespace NLGUI // Common case: no W clamp _Index = TextContext->textPush (_Text); _Info = TextContext->getStringInfo (_Index); - _Info.StringWidth /= _Scale; - _W = (sint)ceilf(_Info.StringWidth); + _W = (sint)ceilf(_Info.StringWidth / _Scale); // Rare case: clamp W => recompute slowly, cut letters - if(_W>_LineMaxW) + if(_Info.StringWidth > _LineMaxW) { TextContext->erase (_Index); @@ -1957,18 +1978,14 @@ namespace NLGUI ucCurrentLine.reserve(_Text.size()); // Append ... to the end of line - float dotWidth; + float dotWidth = 0.f; if (_OverflowText.size() > 0) { si = TextContext->getStringInfo (ucstring(_OverflowText)); - dotWidth = si.StringWidth / _Scale; - } - else - { - dotWidth = 0.0f; + dotWidth = si.StringWidth; } - float rWidthCurrentLine = 0, rWidthLetter; + float rWidthCurrentLine = 0; // for all the text if (_ClampRight) { @@ -1978,8 +1995,7 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth / _Scale); - if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW) + if ((rWidthCurrentLine + si.StringWidth + dotWidth) > _LineMaxW) { break; } @@ -1987,7 +2003,7 @@ namespace NLGUI { // Grow the current line ucCurrentLine += ucLetter; - rWidthCurrentLine += rWidthLetter; + rWidthCurrentLine += si.StringWidth; } } @@ -2005,8 +2021,7 @@ namespace NLGUI ucstring ucStrLetter; ucStrLetter= ucLetter; si = TextContext->getStringInfo (ucStrLetter); - rWidthLetter = (si.StringWidth / _Scale); - if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW) + if ((rWidthCurrentLine + si.StringWidth + dotWidth) > _LineMaxW) { break; } @@ -2014,7 +2029,7 @@ namespace NLGUI { // Grow the current line ucCurrentLine = ucLetter + ucCurrentLine; - rWidthCurrentLine += rWidthLetter; + rWidthCurrentLine += si.StringWidth; } } @@ -2028,14 +2043,13 @@ namespace NLGUI // And so setup this trunc text _Index = TextContext->textPush (ucCurrentLine); _Info = TextContext->getStringInfo (_Index); - _Info.StringWidth /= _Scale; - _W = (sint)ceilf(_Info.StringWidth); + _W = (sint)ceilf(_Info.StringWidth / _Scale); _SingleLineTextClamped= true; } // same height always - _H = (sint)ceilf(_FontHeight); + _H = (sint)ceilf(_FontHeight / _Scale); } _InvalidTextContext= false; @@ -2072,12 +2086,12 @@ namespace NLGUI if (_ClampRight) { sint32 parentRight = parent->getXReal() + parent->getWReal() - (sint32) _AutoClampOffset; - setLineMaxW(ceilf(std::max((sint32) 0, parentRight - _XReal) / _Scale)); + setLineMaxW(std::max((sint32) 0, parentRight - _XReal)); } else { sint32 parentLeft = parent->getXReal() + (sint32) _AutoClampOffset; - setLineMaxW(ceilf(std::max((sint32) 0, _XReal + _WReal - parentLeft) / _Scale)); + setLineMaxW(std::max((sint32) 0, _XReal + _WReal - parentLeft)); } } } @@ -2194,7 +2208,7 @@ namespace NLGUI } // *************************************************************************** - void CViewText::getCharacterPositionFromIndex(sint index, bool cursorAtPreviousLineEnd, sint &x, sint &y, sint &height) const + void CViewText::getCharacterPositionFromIndex(sint index, bool cursorAtPreviousLineEnd, float &x, float &y, float &height) const { NLMISC::clamp(index, 0, (sint) _Text.length()); NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); @@ -2204,18 +2218,19 @@ namespace NLGUI TextContext->setFontSize (_FontSize*_Scale); TextContext->setEmbolden (_Embolden); TextContext->setOblique (_Oblique); - // CViewRenderer &rVR = *CViewRenderer::getInstance(); - height = getFontHeight(); + height = getLineHeight(); // if (_MultiLine) { - uint dy = getMultiMinOffsetY(); + float fx, fy; + float dy = getMultiMinOffsetY() * _Scale; + float nMaxWidth = getCurrentMultiLineMaxW() * _Scale; uint charIndex = 0; // special case for end of text if (index == (sint) _Text.length()) { - y = dy; + fy = dy; if (_Lines.empty()) { x = 0; @@ -2223,10 +2238,12 @@ namespace NLGUI else { CLine &lastLine = *_Lines.back(); - x = (sint) (lastLine.getWidth() + lastLine.getEndSpaces() * lastLine.getSpaceWidth()); - sint nMaxWidth = getCurrentMultiLineMaxW(); - x = std::min(x, nMaxWidth); + fx = lastLine.getWidth() + lastLine.getEndSpaces() * lastLine.getSpaceWidth(); + fx = std::min(fx, nMaxWidth); } + + x = fx / _Scale; + y = fy / _Scale; return; } for(sint i = 0; i < (sint) _Lines.size(); ++i) @@ -2235,10 +2252,12 @@ namespace NLGUI { // should display the character at the end of previous line CLine &currLine = *_Lines[i - 1]; - y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i) + dy); - x = (sint) (currLine.getWidth() + currLine.getEndSpaces() * currLine.getSpaceWidth()); - sint nMaxWidth = getCurrentMultiLineMaxW(); - x = std::min(x, nMaxWidth); + fy = (_FontHeight + _MultiLineSpace * _Scale) * (_Lines.size() - i) + dy; + fx = currLine.getWidth() + currLine.getEndSpaces() * currLine.getSpaceWidth(); + fx = std::min(fx, nMaxWidth); + + x = fx / _Scale; + y = fy / _Scale; return; } CLine &currLine = *_Lines[i]; @@ -2246,14 +2265,16 @@ namespace NLGUI if ((sint) newCharIndex > index) { // ok, this line contains the character, now, see which word contains it. - y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - 1 - i) + dy); + fy = (_FontHeight + _MultiLineSpace * _Scale) * (_Lines.size() - 1 - i) + dy; // see if the index is in the spaces at the end of line if (index - charIndex >= currLine.getNumChars()) { uint numSpaces = index - charIndex - currLine.getNumChars(); - x = (sint) (currLine.getWidth() + numSpaces * _SpaceWidth); - sint nMaxWidth = getCurrentMultiLineMaxW(); - x = std::min(x, nMaxWidth); + fx = currLine.getWidth() + numSpaces * _SpaceWidth; + fx = std::min(fx, nMaxWidth); + + x = fx / _Scale; + y = fy / _Scale; return; } // now, search containing word in current line @@ -2271,15 +2292,19 @@ namespace NLGUI ucstring subStr = currWord.Text.substr(0, index - charIndex - currWord.NumSpaces); // compute the size UTextContext::CStringInfo si = TextContext->getStringInfo(subStr); - x = (sint) ceilf(px + si.StringWidth / _Scale + currWord.NumSpaces * currLine.getSpaceWidth()); - height = getFontHeight(); + fx = px + si.StringWidth + currWord.NumSpaces * currLine.getSpaceWidth(); + + x = fx / _Scale; + y = fy / _Scale; return; } else { // character is in the spaces preceding the word - x = (sint) ceilf(px + currLine.getSpaceWidth() * (index - charIndex)); - height = getFontHeight(); + fx = px + currLine.getSpaceWidth() * (index - charIndex); + + x = fx / _Scale; + y = fy / _Scale; return; } } @@ -2303,11 +2328,11 @@ namespace NLGUI } // *************************************************************************** - // Tool fct : From a word and a x coordinate, give the matching character index - static uint getCharacterIndex(const ucstring &textValue, float x, NL3D::UTextContext &textContext, float scale) + // Tool fct : From a word and a x coordinate (font scale), give the matching character index + static uint getCharacterIndex(const ucstring &textValue, float x, NL3D::UTextContext &textContext) { float px = 0.f; - float sw; + UTextContext::CStringInfo si; ucstring singleChar(" "); uint i; @@ -2316,13 +2341,12 @@ namespace NLGUI // get character width singleChar[0] = textValue[i]; si = textContext.getStringInfo(singleChar); - sw = si.StringWidth / scale; - px += sw; + px += si.StringWidth; // the character is at the i - 1 position if (px > x) { // if the half of the character is after the cursor, then prefer select the next one (like in Word) - if(px-sw/2 < x) + if(px-si.StringWidth/2.f < x) i++; break; } @@ -2331,10 +2355,13 @@ namespace NLGUI } // *************************************************************************** - void CViewText::getCharacterIndexFromPosition(sint x, sint y, uint &index, bool &cursorAtPreviousLineEnd) const + void CViewText::getCharacterIndexFromPosition(float x, float y, uint &index, bool &cursorAtPreviousLineEnd) const { NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName); + x *= _Scale; + y = roundf(y * _Scale); + // setup the text context TextContext->setHotSpot (UTextContext::BottomLeft); TextContext->setShaded (_Shadow); @@ -2347,7 +2374,7 @@ namespace NLGUI uint charPos = 0; if (_MultiLine) { - y -= getMultiMinOffsetY(); + y -= getMultiMinOffsetY() * _Scale; // seek the line float py = 0.f; if (py > y) @@ -2359,7 +2386,7 @@ namespace NLGUI sint line; for (line = (uint)_Lines.size() - 1; line >= 0; --line) { - float newPy = py + _FontHeight + _MultiLineSpace; + float newPy = py + _FontHeight + _MultiLineSpace * _Scale; if (newPy > y) { break; @@ -2392,6 +2419,7 @@ namespace NLGUI return; } + cursorAtPreviousLineEnd = false; float px = (float)_FirstLineX; for(uint k = 0; k < currLine.getNumWords(); ++k) { @@ -2408,14 +2436,12 @@ namespace NLGUI : 0; clamp(numSpaces, 0, (sint)currWord.NumSpaces); index = numSpaces + charPos; - cursorAtPreviousLineEnd = false; return; } else { // the coord is in the word itself - index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth), *TextContext, _Scale); - cursorAtPreviousLineEnd = false; + index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, x - (px + spacesWidth), *TextContext); return; } } @@ -2423,7 +2449,6 @@ namespace NLGUI charPos += (uint)currWord.Text.length() + currWord.NumSpaces; } index = charPos; - cursorAtPreviousLineEnd = false; return; } else @@ -2439,7 +2464,7 @@ namespace NLGUI index = 0; return; } - index = getCharacterIndex(_Text, (float) x, *TextContext, _Scale); + index = getCharacterIndex(_Text, x, *TextContext); return; } } @@ -2507,21 +2532,21 @@ namespace NLGUI // *************************************************************************** uint CViewText::getFirstLineX() const { - return _FirstLineX; + return _FirstLineX / _Scale; } // *************************************************************************** uint CViewText::getLastLineW () const { if (!_Lines.empty()) - return (uint)_Lines.back()->getWidth(); + return (uint)_Lines.back()->getWidth() / _Scale; return 0; } // *************************************************************************** void CViewText::setFirstLineX(sint firstLineX) { - _FirstLineX = firstLineX; + _FirstLineX = firstLineX * _Scale; } ///////////////////////////////////// @@ -2540,10 +2565,10 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext, float scale) + void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext) { CWord word; - word.build(text, textContext, scale, numSpaces); + word.build(text, textContext, numSpaces); word.Format= wordFormat; addWord(word, fontWidth); } @@ -2587,13 +2612,12 @@ namespace NLGUI } // *************************************************************************** - void CViewText::CWord::build(const ucstring &text, NL3D::UTextContext &textContext, float scale, uint numSpaces) + void CViewText::CWord::build(const ucstring &text, NL3D::UTextContext &textContext, uint numSpaces) { Text = text; NumSpaces = numSpaces; Index = textContext.textPush(text); Info = textContext.getStringInfo(Index); - Info.StringWidth /= scale; } // *************************************************************************** @@ -2667,7 +2691,7 @@ namespace NLGUI si = TextContext->getStringInfo(wordValue); // compute size of spaces + word - lineWidth += numSpaces * _SpaceWidth + si.StringWidth / _Scale; + lineWidth += numSpaces * _SpaceWidth + si.StringWidth; currPos = wordEnd; } @@ -2679,7 +2703,7 @@ namespace NLGUI linePos = lineEnd+1; } - return (sint32)ceilf(maxWidth); + return (sint32)ceilf(maxWidth / _Scale); } // *************************************************************************** @@ -2696,7 +2720,7 @@ namespace NLGUI if (_TextMode == ClipWord) { // No largest font parameter, return the font height - return (sint32)ceilf(_FontHeight); + return (sint32)ceilf(_FontHeight / _Scale); } // If we can't clip the words, return the size of the largest word else if ((_TextMode == DontClipWord) || (_TextMode == Justified)) @@ -2733,16 +2757,15 @@ namespace NLGUI si = TextContext->getStringInfo(wordValue); // Larger ? - float stringWidth = (si.StringWidth / _Scale); - if (stringWidth>maxWidth) - maxWidth = stringWidth; + if (maxWidth < si.StringWidth) + maxWidth = si.StringWidth; // Next word currPos = wordEnd; } } - return ceilf(maxWidth); + return ceilf(maxWidth / _Scale); } // *************************************************************************** @@ -2796,16 +2819,16 @@ namespace NLGUI si = TextContext->getStringInfo(chars); } // add a padding of 1 pixel else the top will be truncated - _FontHeight = (si.StringHeight / _Scale) + 1; - _FontLegHeight = si.StringLine / _Scale; + _FontHeight = si.StringHeight + 1; + _FontLegHeight = si.StringLine; // Space width si = TextContext->getStringInfo(ucstring(" ")); - _SpaceWidth = si.StringWidth / _Scale; + _SpaceWidth = si.StringWidth; // Font Width si = TextContext->getStringInfo(ucstring("_")); - _FontWidth = si.StringWidth / _Scale; + _FontWidth = si.StringWidth; } diff --git a/code/ryzom/client/src/interface_v3/action_handler_edit.cpp b/code/ryzom/client/src/interface_v3/action_handler_edit.cpp index 2b3bb7c5e..9c44fa492 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_edit.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_edit.cpp @@ -383,10 +383,10 @@ class CAHEditPreviousLine : public CAHEdit // .. so do nothing return; } - sint cx, cy; - sint height; + float cx, cy; + float height; _GroupEdit->getViewText()->getCharacterPositionFromIndex(cursorPosInText, _GroupEdit->isCursorAtPreviousLineEnd(), cx, cy, height); - cy += height + _GroupEdit->getViewText()->getMultiLineSpace(); + cy += _GroupEdit->getViewText()->getLineHeight(); uint newCharIndex; bool newLineEnd; _GroupEdit->getViewText()->getCharacterIndexFromPosition(cx, cy, newCharIndex, newLineEnd); @@ -401,8 +401,8 @@ class CAHEditPreviousLine : public CAHEdit } _GroupEdit->setCursorAtPreviousLineEnd(false); // takes character whose X is closer to the current X - sint cx0, cx1; - sint cy0, cy1; + float cx0, cx1; + float cy0, cy1; _GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex, _GroupEdit->isCursorAtPreviousLineEnd(), cx0, cy0, height); _GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex + 1, _GroupEdit->isCursorAtPreviousLineEnd(), cx1, cy1, height); if (abs(cx0 - cx) < abs(cx1 - cx) || cy0 != cy1) @@ -446,8 +446,8 @@ class CAHEditNextLine : public CAHEdit } else if (_GroupEdit->getViewText()->getMultiLine()) { - sint cx, cy; - sint height; + float cx, cy; + float height; _GroupEdit->getViewText()->getCharacterPositionFromIndex(_GroupEdit->getCursorPos() + (sint)_GroupEdit->getPrompt().length(), _GroupEdit->isCursorAtPreviousLineEnd(), cx, cy, height); if (cy != 0) { @@ -466,8 +466,8 @@ class CAHEditNextLine : public CAHEdit } _GroupEdit->setCursorAtPreviousLineEnd(false); // takes character whose X is closer to the current X - sint cx0, cx1; - sint cy0, cy1; + float cx0, cx1; + float cy0, cy1; _GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex, _GroupEdit->isCursorAtPreviousLineEnd(), cx0, cy0, height); _GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex + 1, _GroupEdit->isCursorAtPreviousLineEnd(), cx1, cy1, height); if (abs(cx0 - cx) < abs(cx1 - cx) || cy0 != cy1) From 7eb63bfb3f16771e5e37b2a992f7defbb087ae8a Mon Sep 17 00:00:00 2001 From: Nimetu Date: Mon, 25 Jun 2018 11:16:59 +0300 Subject: [PATCH 24/25] Fixed: Font underline position --HG-- branch : experimental-ui-scaling --- code/nel/src/gui/view_text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index f9403014e..1a175e224 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1108,7 +1108,7 @@ namespace NLGUI // Draw a line if (_Underlined) - rVR.drawRotFlipBitmap (_RenderLayer, fx, fy - _FontLegHeight*0.3f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); + rVR.drawRotFlipBitmap (_RenderLayer, fx, fy - _FontLegHeight*0.6f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); if (_StrikeThrough) rVR.drawRotFlipBitmap (_RenderLayer, fx, fy + _FontHeight*0.2f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col); From 06ab5b5f16edf05a52f9c84c745391bb1ec54922 Mon Sep 17 00:00:00 2001 From: Nimetu Date: Sun, 18 Nov 2018 17:17:56 +0200 Subject: [PATCH 25/25] Fixed: Invalid LineMaxW with scaling --HG-- branch : experimental-ui-scaling --- code/nel/src/gui/view_text.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 4355eb647..7ac1bf8a4 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1412,7 +1412,6 @@ namespace NLGUI // *************************************************************************** void CViewText::setLineMaxW (sint nMaxW, bool invalidate) { - nMaxW *= _Scale; if(_LineMaxW!=nMaxW) { _LineMaxW = nMaxW;