Merge pull request #5843 from Dhilan007/develop_label

closed #4428: fixed display incorrect of multi-line label if invoking 'getLetter'.
This commit is contained in:
James Chen 2014-03-19 09:52:14 +08:00
commit a5e9630db1
5 changed files with 97 additions and 41 deletions

View File

@ -446,7 +446,7 @@ bool Label::setBMFontFilePath(const std::string& bmfontFilePath, const Point& im
reset();
return false;
}
_bmFontPath = bmfontFilePath;
setFontAtlas(newAtlas);
_currentLabelType = LabelType::BMFONT;
@ -624,17 +624,7 @@ void Label::alignText()
}
}
int index;
for (int ctr = 0; ctr < _limitShowCount; ++ctr)
{
if (_lettersInfo[ctr].def.validDefinition)
{
updateSpriteWithLetterDefinition(_lettersInfo[ctr].def,textures[_lettersInfo[ctr].def.textureID]);
_reusedLetter->setPosition(_lettersInfo[ctr].position);
index = _batchNodes[_lettersInfo[ctr].def.textureID]->getTextureAtlas()->getTotalQuads();
_batchNodes[_lettersInfo[ctr].def.textureID]->insertQuadFromSprite(_reusedLetter,index);
}
}
updateQuads();
updateColor();
}
@ -691,16 +681,30 @@ bool Label::setCurrentString(unsigned short *stringToSet)
return true;
}
void Label::updateSpriteWithLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture)
void Label::updateQuads()
{
_reusedRect.size.height = theDefinition.height;
_reusedRect.size.width = theDefinition.width;
_reusedRect.origin.x = theDefinition.U;
_reusedRect.origin.y = theDefinition.V;
int index;
for (int ctr = 0; ctr < _limitShowCount; ++ctr)
{
auto &letterDef = _lettersInfo[ctr].def;
if(_reusedLetter->getBatchNode() != _batchNodes[theDefinition.textureID])
_reusedLetter->setBatchNode(_batchNodes[theDefinition.textureID]);
_reusedLetter->setTextureRect(_reusedRect,false,_reusedRect.size);
if (letterDef.validDefinition)
{
_reusedRect.size.height = letterDef.height;
_reusedRect.size.width = letterDef.width;
_reusedRect.origin.x = letterDef.U;
_reusedRect.origin.y = letterDef.V;
if(_reusedLetter->getBatchNode() != _batchNodes[letterDef.textureID])
_reusedLetter->setBatchNode(_batchNodes[letterDef.textureID]);
_reusedLetter->setTextureRect(_reusedRect,false,_reusedRect.size);
_reusedLetter->setPosition(_lettersInfo[ctr].position);
index = _batchNodes[letterDef.textureID]->getTextureAtlas()->getTotalQuads();
_lettersInfo[ctr].atlasIndex = index;
_batchNodes[letterDef.textureID]->insertQuadFromSprite(_reusedLetter,index);
}
}
}
bool Label::recordLetterInfo(const cocos2d::Point& point,const FontLetterDefinition& letterDef, int spriteIndex)
@ -1054,35 +1058,41 @@ int Label::getFontSize() const
}
///// PROTOCOL STUFF
Sprite * Label::getLetter(int lettetIndex)
Sprite * Label::getLetter(int letterIndex)
{
if (_fontDirty)
{
updateFont();
}
if (_contentDirty)
{
updateContent();
}
if (! _textSprite && lettetIndex < _limitShowCount)
if (! _textSprite && letterIndex < _limitShowCount)
{
if(! _lettersInfo[lettetIndex].def.validDefinition)
const auto &letter = _lettersInfo[letterIndex];
if(! letter.def.validDefinition)
return nullptr;
Sprite* sp = static_cast<Sprite*>(this->getChildByTag(lettetIndex));
Sprite* sp = static_cast<Sprite*>(this->getChildByTag(letterIndex));
if (!sp)
{
Rect uvRect;
uvRect.size.height = _lettersInfo[lettetIndex].def.height;
uvRect.size.width = _lettersInfo[lettetIndex].def.width;
uvRect.origin.x = _lettersInfo[lettetIndex].def.U;
uvRect.origin.y = _lettersInfo[lettetIndex].def.V;
uvRect.size.height = letter.def.height;
uvRect.size.width = letter.def.width;
uvRect.origin.x = letter.def.U;
uvRect.origin.y = letter.def.V;
sp = Sprite::createWithTexture(_fontAtlas->getTexture(_lettersInfo[lettetIndex].def.textureID),uvRect);
sp->setBatchNode(this);
sp->setAnchorPoint(Point::ANCHOR_MIDDLE);
sp->setPosition(Point(_lettersInfo[lettetIndex].position.x+uvRect.size.width/2,_lettersInfo[lettetIndex].position.y-uvRect.size.height/2));
sp = Sprite::createWithTexture(_fontAtlas->getTexture(letter.def.textureID),uvRect);
sp->setBatchNode(_batchNodes[letter.def.textureID]);
sp->setPosition(Point(letter.position.x + uvRect.size.width / 2,
letter.position.y - uvRect.size.height / 2));
sp->setOpacity(_realOpacity);
this->addSpriteWithoutQuad(sp, lettetIndex, lettetIndex);
_batchNodes[letter.def.textureID]->addSpriteWithoutQuad(sp, letter.atlasIndex, letterIndex);
}
return sp;
}
@ -1120,7 +1130,7 @@ void Label::computeStringNumLines()
int Label::getStringLength() const
{
return _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0;
return _currentUTF16String ? cc_wcslen(_currentUTF16String) : _originalUTF8String.length();
}
// RGBA protocol

View File

@ -116,6 +116,7 @@ public:
virtual bool setTTFConfig(const TTFConfig& ttfConfig);
virtual bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
const std::string& getBMFontFilePath() const { return _bmFontPath;}
virtual bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
virtual bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
@ -248,6 +249,7 @@ protected:
Point position;
Size contentSize;
int atlasIndex;
};
enum class LabelType {
@ -282,7 +284,7 @@ protected:
bool setOriginalString(unsigned short *stringToSet);
void computeStringNumLines();
void updateSpriteWithLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture);
void updateQuads();
virtual void updateColor() override;
@ -295,6 +297,8 @@ protected:
void updateFont();
void reset();
std::string _bmFontPath;
bool _isOpacityModifyRGB;
bool _contentDirty;
bool _fontDirty;

View File

@ -172,16 +172,16 @@ public:
For example: a tile map (TMXMap) or a label with lots of characters (LabelBMFont)
*/
void insertQuadFromSprite(Sprite *sprite, ssize_t index);
/* This is the opposite of "addQuadFromSprite.
It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
*/
SpriteBatchNode * addSpriteWithoutQuad(Sprite *child, int z, int aTag);
protected:
/** Updates a quad at a certain index into the texture atlas. The Sprite won't be added into the children array.
This method should be called only when you are dealing with very big AtlasSrite and when most of the Sprite won't be updated.
For example: a tile map (TMXMap) or a label with lots of characters (LabelBMFont)
*/
void updateQuadFromSprite(Sprite *sprite, ssize_t index);
/* This is the opposite of "addQuadFromSprite.
It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
*/
SpriteBatchNode * addSpriteWithoutQuad(Sprite *child, int z, int aTag);
void updateQuadFromSprite(Sprite *sprite, ssize_t index);
void updateAtlasIndex(Sprite* sprite, ssize_t* curIndex);
void swap(ssize_t oldIndex, ssize_t newIndex);

View File

@ -77,7 +77,8 @@ static std::function<Layer*()> createFunctions[] =
CL(LabelCrashTest),
CL(LabelTTFOldNew),
CL(LabelFontNameTest),
CL(LabelAlignmentTest)
CL(LabelAlignmentTest),
CL(LabelIssue4428Test)
};
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -1779,3 +1780,33 @@ std::string LabelAlignmentTest::subtitle() const
{
return "Select the buttons on the sides to change alignment";
}
LabelIssue4428Test::LabelIssue4428Test()
{
auto size = Director::getInstance()->getWinSize();
auto label = Label::createWithBMFont( "fonts/bitmapFontTest3.fnt", "123\n456");
label->setPosition(Point(size.width /2.0f, size.height / 2.0f));
label->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
addChild(label);
int len = label->getStringLength();
for (int i = 0; i < len; ++i)
{
auto sprite = label->getLetter(i);
if (sprite != nullptr)
{
sprite->setFlippedY(true);
}
}
}
std::string LabelIssue4428Test::title() const
{
return "New Label Bugs Test";
}
std::string LabelIssue4428Test::subtitle() const
{
return "Reorder issue #4428.The label should be flipped vertically.";
}

View File

@ -484,6 +484,17 @@ private:
TextVAlignment _vertAlign;
};
class LabelIssue4428Test : public AtlasDemoNew
{
public:
CREATE_FUNC(LabelIssue4428Test);
LabelIssue4428Test();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
// we don't support linebreak mode
#endif