Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 45 additions & 35 deletions cocos/2d/CCLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ bool Label::setBMFontFilePath(const std::string& bmfontFilePath, const Point& im
reset();
return false;
}

_bmFontPath = bmfontFilePath;
setFontAtlas(newAtlas);
_currentLabelType = LabelType::BMFONT;

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

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));
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(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;
}
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion cocos/2d/CCLabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
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);
Expand Down Expand Up @@ -248,6 +249,7 @@ class CC_DLL Label : public SpriteBatchNode, public LabelProtocol

Point position;
Size contentSize;
int atlasIndex;
};
enum class LabelType {

Expand Down Expand Up @@ -282,7 +284,7 @@ class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
bool setOriginalString(unsigned short *stringToSet);
void computeStringNumLines();

void updateSpriteWithLetterDefinition(const FontLetterDefinition &theDefinition, Texture2D *theTexture);
void updateQuads();

virtual void updateColor() override;

Expand All @@ -295,6 +297,8 @@ class CC_DLL Label : public SpriteBatchNode, public LabelProtocol
void updateFont();
void reset();

std::string _bmFontPath;

bool _isOpacityModifyRGB;
bool _contentDirty;
bool _fontDirty;
Expand Down
10 changes: 5 additions & 5 deletions cocos/2d/CCSpriteBatchNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,16 @@ class CC_DLL SpriteBatchNode : public Node, public TextureProtocol
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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to make this method public?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I saw Label::getLetter needs it.

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);
Expand Down
33 changes: 32 additions & 1 deletion tests/cpp-tests/Classes/LabelTest/LabelTestNew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
Expand Down Expand Up @@ -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.";
}
11 changes: 11 additions & 0 deletions tests/cpp-tests/Classes/LabelTest/LabelTestNew.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,17 @@ class LabelAlignmentTest : public AtlasDemoNew
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