@@ -27,6 +27,7 @@ CChat::CChat(CGUI* pManager, const CVector2D& vecPosition)
2727 // Calculate relative position (assuming a 800x600 native resolution for our defined CCHAT_* values)
2828 CVector2D vecResolution = m_pManager->GetResolution ();
2929 m_vecScale = CVector2D (vecResolution.fX / 800 .0f , vecResolution.fY / 600 .0f );
30+ m_previousScale = m_vecScale;
3031 m_vecBackgroundPosition = vecPosition * vecResolution;
3132
3233 // Initialize variables
@@ -914,6 +915,13 @@ void CChat::SetDxFont(LPD3DXFONT pDXFont)
914915
915916void CChat::UpdateGUI ()
916917{
918+ // Check if scale has changed and invalidate cached widths if so
919+ if (m_vecScale != m_previousScale)
920+ {
921+ InvalidateAllCachedWidths ();
922+ m_previousScale = m_vecScale;
923+ }
924+
917925 m_vecBackgroundSize = CVector2D (m_fNativeWidth * m_vecScale.fX , CChat::GetFontHeight (m_vecScale.fY ) * (float (m_uiNumLines) + 0 .5f ));
918926 m_vecBackgroundSize.fX = Round (m_vecBackgroundSize.fX );
919927 m_vecBackgroundSize.fY = Round (m_vecBackgroundSize.fY );
@@ -935,6 +943,15 @@ void CChat::UpdateGUI()
935943 UpdatePosition ();
936944}
937945
946+ void CChat::InvalidateAllCachedWidths ()
947+ {
948+ for (int i = 0 ; i < CHAT_MAX_LINES; i++)
949+ {
950+ m_Lines[i].InvalidateCache ();
951+ }
952+ m_InputLine.InvalidateCache ();
953+ }
954+
938955void CChat::UpdatePosition ()
939956{
940957 CVector2D vecResolution = m_pManager->GetResolution ();
@@ -1166,78 +1183,78 @@ const char* CalcAnsiPtr(const char* szStringAnsi, const wchar_t* szPosition)
11661183 return szStringAnsi + iOffset;
11671184}
11681185
1169- const char * CChatLine::Format (const char * szStringAnsi , float fWidth , CColor& color, bool bColorCoded )
1186+ const char * CChatLine::Format (const char * text , float width , CColor& color, bool colorCoded )
11701187{
1171- std::wstring wString = MbUTF8ToUTF16 (szStringAnsi );
1188+ std::wstring wString = MbUTF8ToUTF16 (text );
11721189 const wchar_t * szString = wString.c_str ();
11731190
1174- float fPrevSectionsWidth = 0 .0f ;
1191+ float prevSectionsWidth = 0 .0f ;
11751192 m_Sections.clear ();
11761193
1177- const wchar_t * szSectionStart = szString;
1178- const wchar_t * szSectionEnd = szString;
1179- const wchar_t * szLastWrapPoint = szString;
1180- bool bLastSection = false ;
1181- while (!bLastSection ) // iterate over sections
1194+ const wchar_t * sectionStart = szString;
1195+ const wchar_t * sectionEnd = szString;
1196+ const wchar_t * lastWrapPoint = szString;
1197+ bool lastSection = false ;
1198+ while (!lastSection ) // iterate over sections
11821199 {
11831200 m_Sections.resize (m_Sections.size () + 1 );
11841201 CChatLineSection& section = *(m_Sections.end () - 1 );
11851202 section.SetColor (color);
11861203
1187- if (m_Sections.size () > 1 && bColorCoded ) // If we've processed sections before
1188- szSectionEnd += 7 ; // skip the color code
1204+ if (m_Sections.size () > 1 && colorCoded ) // If we've processed sections before
1205+ sectionEnd += 7 ; // skip the color code
11891206
1190- szSectionStart = szSectionEnd ;
1191- szLastWrapPoint = szSectionStart ;
1192- unsigned int uiSeekPos = 0 ;
1193- std::wstring strSectionStart = szSectionStart ;
1207+ sectionStart = sectionEnd ;
1208+ lastWrapPoint = sectionStart ;
1209+ unsigned int seekPos = 0 ;
1210+ std::wstring strSectionStart = sectionStart ;
11941211
11951212 while (true ) // find end of this section
11961213 {
1197- float fSectionWidth = CChat::GetTextExtent (UTF16ToMbUTF8 (strSectionStart.substr (0 , uiSeekPos )).c_str (), g_pChat->m_vecScale .fX );
1214+ float sectionWidth = CChat::GetTextExtent (UTF16ToMbUTF8 (strSectionStart.substr (0 , seekPos )).c_str (), g_pChat->m_vecScale .fX );
11981215
1199- if (*szSectionEnd == ' \0 ' || *szSectionEnd == ' \n ' || std::ceil (fPrevSectionsWidth + fSectionWidth ) > fWidth )
1216+ if (*sectionEnd == ' \0 ' || *sectionEnd == ' \n ' || std::ceil (prevSectionsWidth + sectionWidth ) > width )
12001217 {
1201- bLastSection = true ;
1218+ lastSection = true ;
12021219 break ;
12031220 }
1204- if (bColorCoded && IsColorCode (UTF16ToMbUTF8 (szSectionEnd ).c_str ()))
1221+ if (colorCoded && IsColorCode (UTF16ToMbUTF8 (sectionEnd ).c_str ()))
12051222 {
1206- unsigned long ulColor = 0 ;
1207- sscanf (UTF16ToMbUTF8 (szSectionEnd ).c_str () + 1 , " %06x" , &ulColor );
1208- color = ulColor ;
1209- fPrevSectionsWidth += fSectionWidth ;
1223+ unsigned long colorValue = 0 ;
1224+ sscanf (UTF16ToMbUTF8 (sectionEnd ).c_str () + 1 , " %06x" , &colorValue );
1225+ color = colorValue ;
1226+ prevSectionsWidth += sectionWidth ;
12101227 break ;
12111228 }
1212- if (isspace ((unsigned char )*szSectionEnd ) || ispunct ((unsigned char )*szSectionEnd ))
1229+ if (isspace ((unsigned char )*sectionEnd ) || ispunct ((unsigned char )*sectionEnd ))
12131230 {
1214- szLastWrapPoint = szSectionEnd ;
1231+ lastWrapPoint = sectionEnd ;
12151232 }
1216- szSectionEnd ++;
1217- uiSeekPos ++;
1233+ sectionEnd ++;
1234+ seekPos ++;
12181235 }
1219- section.m_strText = UTF16ToMbUTF8 (strSectionStart.substr (0 , uiSeekPos ));
1236+ section.m_text = UTF16ToMbUTF8 (strSectionStart.substr (0 , seekPos ));
12201237 }
12211238
1222- if (*szSectionEnd == ' \0 ' )
1239+ if (*sectionEnd == ' \0 ' )
12231240 {
1224- return NULL ;
1241+ return nullptr ;
12251242 }
1226- else if (*szSectionEnd == ' \n ' )
1243+ else if (*sectionEnd == ' \n ' )
12271244 {
1228- return CalcAnsiPtr (szStringAnsi, szSectionEnd + 1 );
1245+ return CalcAnsiPtr (text, sectionEnd + 1 );
12291246 }
12301247 else
12311248 {
12321249 // Do word wrap
1233- if (szLastWrapPoint == szSectionStart )
1250+ if (lastWrapPoint == sectionStart )
12341251 {
12351252 // Wrapping point coincides with the start of a section.
1236- if (szLastWrapPoint == szString)
1253+ if (lastWrapPoint == szString)
12371254 {
12381255 // The line consists of one huge word. Leave the one section we created as it
1239- // is (with the huge word cut off) and return szRemaining as the rest of the word
1240- return CalcAnsiPtr (szStringAnsi, szSectionEnd );
1256+ // is (with the huge word cut off) and return remaining as the rest of the word
1257+ return CalcAnsiPtr (text, sectionEnd );
12411258 }
12421259 else
12431260 {
@@ -1249,56 +1266,61 @@ const char* CChatLine::Format(const char* szStringAnsi, float fWidth, CColor& co
12491266 {
12501267 // Wrapping point is in the middle of a section, truncate
12511268 CChatLineSection& last = *(m_Sections.end () - 1 );
1252- std::wstring wstrTemp = MbUTF8ToUTF16 (last.m_strText );
1253- wstrTemp.resize (szLastWrapPoint - szSectionStart );
1254- last.m_strText = UTF16ToMbUTF8 (wstrTemp);
1269+ std::wstring wstrTemp = MbUTF8ToUTF16 (last.m_text );
1270+ wstrTemp.resize (lastWrapPoint - sectionStart );
1271+ last.m_text = UTF16ToMbUTF8 (wstrTemp);
12551272 }
1256- return CalcAnsiPtr (szStringAnsi, szLastWrapPoint);
1273+ return CalcAnsiPtr (text, lastWrapPoint);
1274+ }
1275+ }
1276+
1277+ void CChatLine::Draw (const CVector2D& position, unsigned char alpha, bool shadow, bool outline, const CRect2D& renderBounds)
1278+ {
1279+ float currentX = position.fX ;
1280+ for (auto & section : m_Sections)
1281+ {
1282+ section.Draw (CVector2D (currentX, position.fY ), alpha, shadow, outline, renderBounds);
1283+ currentX += section.GetWidth ();
12571284 }
12581285}
12591286
1260- void CChatLine::Draw ( const CVector2D& vecPosition, unsigned char ucAlpha, bool bShadow, bool bOutline, const CRect2D& RenderBounds)
1287+ float CChatLine::GetWidth () const
12611288{
1262- float fCurrentX = vecPosition.fX ;
1263- std::vector<CChatLineSection>::iterator iter = m_Sections.begin ();
1264- for (; iter != m_Sections.end (); iter++)
1289+ float width = 0 .0f ;
1290+ for (const auto & section : m_Sections)
12651291 {
1266- (*iter).Draw (CVector2D (fCurrentX , vecPosition.fY ), ucAlpha, bShadow, bOutline, RenderBounds);
1267- fCurrentX += (*iter).GetWidth ();
1292+ width += section.GetWidth ();
12681293 }
1294+ return width;
12691295}
12701296
1271- float CChatLine::GetWidth ()
1297+ void CChatLine::InvalidateCache ()
12721298{
1273- float fWidth = 0 .0f ;
1274- std::vector<CChatLineSection>::iterator it;
1275- for (it = m_Sections.begin (); it != m_Sections.end (); it++)
1299+ for (auto & section : m_Sections)
12761300 {
1277- fWidth += (*it). GetWidth ();
1301+ section. InvalidateCache ();
12781302 }
1279- return fWidth ;
12801303}
12811304
1282- void CChatInputLine::Draw (CVector2D& vecPosition , unsigned char ucAlpha , bool bShadow , bool bOutline )
1305+ void CChatInputLine::Draw (CVector2D& position , unsigned char alpha , bool shadow , bool outline )
12831306{
1284- CRect2D RenderBounds (0 , 0 , 9999 , 9999 );
1307+ CRect2D renderBounds (0 , 0 , 9999 , 9999 );
12851308
1286- CColor colPrefix ;
1287- m_Prefix.GetColor (colPrefix );
1288- if (colPrefix .A > 0 )
1289- m_Prefix.Draw (vecPosition, colPrefix .A , bShadow, bOutline, RenderBounds );
1309+ CColor prefixColor ;
1310+ m_Prefix.GetColor (prefixColor );
1311+ if (prefixColor .A > 0 )
1312+ m_Prefix.Draw (position, prefixColor .A , shadow, outline, renderBounds );
12901313
12911314 if (g_pChat->m_InputTextColor .A > 0 && m_Sections.size () > 0 )
12921315 {
1293- m_Sections[0 ].Draw (CVector2D (vecPosition .fX + m_Prefix.GetWidth (), vecPosition .fY ), g_pChat->m_InputTextColor .A , bShadow, bOutline, RenderBounds );
1316+ m_Sections[0 ].Draw (CVector2D (position .fX + m_Prefix.GetWidth (), position .fY ), g_pChat->m_InputTextColor .A , shadow, outline, renderBounds );
12941317
1295- float fLineDifference = CChat::GetFontHeight (g_pChat->m_vecScale .fY );
1318+ float lineDifference = CChat::GetFontHeight (g_pChat->m_vecScale .fY );
12961319
1297- vector<CChatLine>::iterator iter = m_ExtraLines.begin ();
1298- for (; iter != m_ExtraLines.end (); iter++)
1320+ for (auto & line : m_ExtraLines)
12991321 {
1300- vecPosition .fY += fLineDifference ;
1301- (*iter) .Draw (vecPosition , g_pChat->m_InputTextColor .A , bShadow, bOutline, RenderBounds );
1322+ position .fY += lineDifference ;
1323+ line .Draw (position , g_pChat->m_InputTextColor .A , shadow, outline, renderBounds );
13021324 }
13031325 }
13041326}
@@ -1309,10 +1331,20 @@ void CChatInputLine::Clear()
13091331 m_ExtraLines.clear ();
13101332}
13111333
1334+ void CChatInputLine::InvalidateCache ()
1335+ {
1336+ CChatLine::InvalidateCache ();
1337+ m_Prefix.InvalidateCache ();
1338+ for (auto & line : m_ExtraLines)
1339+ {
1340+ line.InvalidateCache ();
1341+ }
1342+ }
1343+
13121344CChatLineSection::CChatLineSection ()
13131345{
1314- m_fCachedWidth = -1 .0f ;
1315- m_uiCachedLength = 0 ;
1346+ m_cachedWidth = -1 .0f ;
1347+ m_cachedLength = 0 ;
13161348}
13171349
13181350CChatLineSection::CChatLineSection (const CChatLineSection& other)
@@ -1322,35 +1354,41 @@ CChatLineSection::CChatLineSection(const CChatLineSection& other)
13221354
13231355CChatLineSection& CChatLineSection::operator =(const CChatLineSection& other)
13241356{
1325- m_strText = other.m_strText ;
1326- m_Color = other.m_Color ;
1327- m_fCachedWidth = other.m_fCachedWidth ;
1328- m_uiCachedLength = other.m_uiCachedLength ;
1357+ m_text = other.m_text ;
1358+ m_color = other.m_color ;
1359+ m_cachedWidth = other.m_cachedWidth ;
1360+ m_cachedLength = other.m_cachedLength ;
13291361 return *this ;
13301362}
13311363
1332- void CChatLineSection::Draw (const CVector2D& vecPosition , unsigned char ucAlpha , bool bShadow , bool bOutline , const CRect2D& RenderBounds )
1364+ void CChatLineSection::Draw (const CVector2D& position , unsigned char alpha , bool shadow , bool outline , const CRect2D& renderBounds )
13331365{
1334- if (!m_strText .empty () && ucAlpha > 0 )
1366+ if (!m_text .empty () && alpha > 0 )
13351367 {
1336- if (bShadow )
1368+ if (shadow )
13371369 {
1338- CRect2D drawShadowAt (vecPosition .fX + 1 .0f , vecPosition .fY + 1 .0f , vecPosition .fX + 1000 .0f , vecPosition .fY + 1000 .0f );
1339- CChat::DrawTextString (m_strText .c_str (), drawShadowAt, 0 .0f , drawShadowAt, 0 , COLOR_ARGB (ucAlpha , 0 , 0 , 0 ), g_pChat->m_vecScale .fX ,
1340- g_pChat->m_vecScale .fY , bOutline, RenderBounds );
1370+ CRect2D drawShadowAt (position .fX + 1 .0f , position .fY + 1 .0f , position .fX + 1000 .0f , position .fY + 1000 .0f );
1371+ CChat::DrawTextString (m_text .c_str (), drawShadowAt, 0 .0f , drawShadowAt, 0 , COLOR_ARGB (alpha , 0 , 0 , 0 ), g_pChat->m_vecScale .fX ,
1372+ g_pChat->m_vecScale .fY , outline, renderBounds );
13411373 }
1342- CRect2D drawAt (vecPosition .fX , vecPosition .fY , vecPosition .fX + 1000 .0f , vecPosition .fY + 1000 .0f );
1343- CChat::DrawTextString (m_strText .c_str (), drawAt, 0 .0f , drawAt, 0 , COLOR_ARGB (ucAlpha, m_Color .R , m_Color .G , m_Color .B ), g_pChat->m_vecScale .fX ,
1344- g_pChat->m_vecScale .fY , bOutline, RenderBounds );
1374+ CRect2D drawAt (position .fX , position .fY , position .fX + 1000 .0f , position .fY + 1000 .0f );
1375+ CChat::DrawTextString (m_text .c_str (), drawAt, 0 .0f , drawAt, 0 , COLOR_ARGB (alpha, m_color .R , m_color .G , m_color .B ), g_pChat->m_vecScale .fX ,
1376+ g_pChat->m_vecScale .fY , outline, renderBounds );
13451377 }
13461378}
13471379
1348- float CChatLineSection::GetWidth ()
1380+ float CChatLineSection::GetWidth () const
13491381{
1350- if (m_fCachedWidth < 0 .0f || m_strText .size () != m_uiCachedLength )
1382+ if (m_cachedWidth < 0 .0f || m_text .size () != m_cachedLength )
13511383 {
1352- m_fCachedWidth = std::ceil (CChat::GetTextExtent (m_strText .c_str (), g_pChat->m_vecScale .fX ) / std::max (0 .01f , g_pChat->m_vecScale .fX ));
1353- m_uiCachedLength = m_strText .size ();
1384+ m_cachedWidth = std::ceil (CChat::GetTextExtent (m_text .c_str (), g_pChat->m_vecScale .fX ) / std::max (0 .01f , g_pChat->m_vecScale .fX ));
1385+ m_cachedLength = m_text .size ();
13541386 }
1355- return m_fCachedWidth * g_pChat->m_vecScale .fX ;
1387+ return m_cachedWidth * g_pChat->m_vecScale .fX ;
1388+ }
1389+
1390+ void CChatLineSection::InvalidateCache ()
1391+ {
1392+ m_cachedWidth = -1 .0f ;
1393+ m_cachedLength = 0 ;
13561394}
0 commit comments