Merge pull request #2218 from dumganhar/bmfont-logic-error

fix a logic error and a memory leak in CCLabelBMFont. This PR could fix wrong display of Score in WatermelonWithMe.
This commit is contained in:
minggo 2013-03-19 23:06:48 -07:00
commit aa5adc185a
2 changed files with 59 additions and 29 deletions

View File

@ -47,6 +47,19 @@ using namespace std;
NS_CC_BEGIN NS_CC_BEGIN
// The return value needs to be deleted by CC_SAFE_DELETE_ARRAY.
static unsigned short* copyUTF16StringN(unsigned short* str)
{
int length = str ? cc_wcslen(str) : 0;
unsigned short* ret = new unsigned short[length+1];
for (int i = 0; i < length; ++i) {
ret[i] = str[i];
}
ret[length] = 0;
return ret;
}
// //
//FNTConfig Cache - free functions //FNTConfig Cache - free functions
// //
@ -518,10 +531,14 @@ bool CCLabelBMFont::initWithString(const char *theString, const char *fntFile, f
} }
CCLabelBMFont::CCLabelBMFont() CCLabelBMFont::CCLabelBMFont()
: m_sString(NULL) : m_sString(NULL)
, m_sInitialString(NULL)
, m_pAlignment(kCCTextAlignmentCenter)
, m_fWidth(-1.0f)
, m_pConfiguration(NULL) , m_pConfiguration(NULL)
, m_bLineBreakWithoutSpaces(false) , m_bLineBreakWithoutSpaces(false)
, m_tImageOffset(CCPointZero) , m_tImageOffset(CCPointZero)
, m_pReusedChar(NULL)
, m_cDisplayedOpacity(255) , m_cDisplayedOpacity(255)
, m_cRealOpacity(255) , m_cRealOpacity(255)
, m_tDisplayedColor(ccWHITE) , m_tDisplayedColor(ccWHITE)
@ -536,7 +553,8 @@ CCLabelBMFont::CCLabelBMFont()
CCLabelBMFont::~CCLabelBMFont() CCLabelBMFont::~CCLabelBMFont()
{ {
CC_SAFE_RELEASE(m_pReusedChar); CC_SAFE_RELEASE(m_pReusedChar);
CC_SAFE_DELETE(m_sString); CC_SAFE_DELETE_ARRAY(m_sString);
CC_SAFE_DELETE_ARRAY(m_sInitialString);
CC_SAFE_RELEASE(m_pConfiguration); CC_SAFE_RELEASE(m_pConfiguration);
} }
@ -710,29 +728,37 @@ void CCLabelBMFont::createFontChars()
//LabelBMFont - CCLabelProtocol protocol //LabelBMFont - CCLabelProtocol protocol
void CCLabelBMFont::setString(const char *newString) void CCLabelBMFont::setString(const char *newString)
{ {
this->setString(newString, false); this->setString(newString, true);
} }
void CCLabelBMFont::setString(const char *newString, bool fromUpdate) void CCLabelBMFont::setString(const char *newString, bool needUpdateLabel)
{ {
if (! fromUpdate) if (newString == NULL) {
newString = "";
}
if (needUpdateLabel) {
m_sInitialStringUTF8 = newString;
}
unsigned short* utf16String = cc_utf8_to_utf16(newString);
setString(utf16String, needUpdateLabel);
CC_SAFE_DELETE_ARRAY(utf16String);
}
void CCLabelBMFont::setString(unsigned short *newString, bool needUpdateLabel)
{
if (!needUpdateLabel)
{ {
CC_SAFE_DELETE_ARRAY(m_sString); unsigned short* tmp = m_sString;
m_sString = cc_utf8_to_utf16(newString); m_sString = copyUTF16StringN(newString);
CC_SAFE_DELETE_ARRAY(tmp);
} }
else else
{ {
if (strcmp(m_sInitialString.c_str(), newString)) unsigned short* tmp = m_sInitialString;
{ m_sInitialString = copyUTF16StringN(newString);
m_sInitialString = newString; CC_SAFE_DELETE_ARRAY(tmp);
}
} }
updateString(fromUpdate);
}
void CCLabelBMFont::updateString(bool fromUpdate)
{
if (m_pChildren && m_pChildren->count() != 0) if (m_pChildren && m_pChildren->count() != 0)
{ {
CCObject* child; CCObject* child;
@ -747,13 +773,14 @@ void CCLabelBMFont::updateString(bool fromUpdate)
} }
this->createFontChars(); this->createFontChars();
if (fromUpdate) if (needUpdateLabel) {
updateLabel(); updateLabel();
}
} }
const char* CCLabelBMFont::getString(void) const char* CCLabelBMFont::getString(void)
{ {
return m_sInitialString.c_str(); return m_sInitialStringUTF8.c_str();
} }
void CCLabelBMFont::setCString(const char *label) void CCLabelBMFont::setCString(const char *label)
@ -897,7 +924,7 @@ void CCLabelBMFont::setAnchorPoint(const CCPoint& point)
// LabelBMFont - Alignment // LabelBMFont - Alignment
void CCLabelBMFont::updateLabel() void CCLabelBMFont::updateLabel()
{ {
this->setString(m_sInitialString.c_str(), false); this->setString(m_sInitialString, false);
if (m_fWidth > 0) if (m_fWidth > 0)
{ {
@ -1062,11 +1089,11 @@ void CCLabelBMFont::updateLabel()
str_new[i] = multiline_string[i]; str_new[i] = multiline_string[i];
} }
str_new[size] = 0; str_new[size] = '\0';
CC_SAFE_DELETE_ARRAY(m_sString); this->setString(str_new, false);
m_sString = str_new;
updateString(false); CC_SAFE_DELETE_ARRAY(str_new);
} }
// Step 2: Make alignment // Step 2: Make alignment

View File

@ -211,9 +211,9 @@ public:
/** updates the font chars based on the string to render */ /** updates the font chars based on the string to render */
void createFontChars(); void createFontChars();
// super method // super method
virtual void setString(const char *label); virtual void setString(const char *newString);
virtual void setString(const char *label, bool fromUpdate); virtual void setString(const char *newString, bool needUpdateLabel);
virtual void updateString(bool fromUpdate);
virtual const char* getString(void); virtual const char* getString(void);
virtual void setCString(const char *label); virtual void setCString(const char *label);
virtual void setAnchorPoint(const CCPoint& var); virtual void setAnchorPoint(const CCPoint& var);
@ -252,6 +252,7 @@ private:
float getLetterPosXRight( CCSprite* characterSprite ); float getLetterPosXRight( CCSprite* characterSprite );
protected: protected:
virtual void setString(unsigned short *newString, bool needUpdateLabel);
// string to render // string to render
unsigned short* m_sString; unsigned short* m_sString;
@ -259,7 +260,9 @@ protected:
std::string m_sFntFile; std::string m_sFntFile;
// initial string without line breaks // initial string without line breaks
std::string m_sInitialString; unsigned short* m_sInitialString;
std::string m_sInitialStringUTF8;
// alignment of all lines // alignment of all lines
CCTextAlignment m_pAlignment; CCTextAlignment m_pAlignment;
// max width until a line break is added // max width until a line break is added