cocos2d / cocos2d-x

Cocos2d-x is a suite of open-source, cross-platform, game-development tools utilized by millions of developers across the globe. Its core has evolved to serve as the foundation for Cocos Creator 1.x & 2.x.
https://www.cocos.com/en/cocos2d-x
18.16k stars 7.05k forks source link

CCLabel overflow shrink bug #20711

Open DelinWorks opened 2 years ago

DelinWorks commented 2 years ago

There is a bug in cocos2d::Label that can be fixed easily, when making a Label overflow shrink the size of the label after being shrinked from a big text doesn't go back to it's original font size after setting the text to something smaller

In another wording if shrink shrinks the text the label stays small forever even if you put smaller text in it

I'm kind of noob at making GitHub pull requests but ill try, if you can help I'll appreciate it :D

Steps to Reproduce:

  1. make a new cocos2dx windows project
  2. create a new label this way and add it to the scene
    loadingText = Label::createWithTTF("Validating Resources...", "fonts/SourceCodePro-Regular.ttf", 22, Size(600, 40), TextHAlignment::CENTER);
    loadingText->setAnchorPoint(Vec2(.5f, 1));
    loadingText->setOverflow(Label::Overflow::SHRINK);

Keep manipulating the text when some keys are pressed and you'll notice the bug right off the bat

I fixed it by going to CCLabel.cpp in the engine's source and modifying setString() function and adding restoreFontSize() function when the text changes so that it becomes normal again and for shrink function to modify it however it wants without "locking" it to a small font size

void Label::setString(const std::string& text)
{
    if (text.compare(_utf8Text))
    {
        restoreFontSize();

        _utf8Text = text;
        _contentDirty = true;

        std::u32string utf32String;
        if (StringUtils::UTF8ToUTF32(_utf8Text, utf32String))
        {
            _utf32Text  = utf32String;
        }
    }
}
TyelorD commented 2 years ago

We fixed this issue as well on our own projects by creating a child of the Label class, and giving it an optional bool (_rescaleWhenStringSet) that when true, inside our Label::setString override function, calls Label::rescaleWithOriginalFontSize(); after calling the base class Label::setString function.

This also makes the text automatically resize after setting a string, and makes more sense than forcing Label to do so every time a string is set. The reason for this is occasionally you want a label that doesn't keep changing sizes every time a string is set, e.g. when you are using a Label to display a timer you don't want the timer text to keep growing bigger and smaller, so it's best to leave it at the size it was originally scaled to and let it scale down still if the timer is counting upwards (and thus getting longer).