@@ -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