Skip to content

Commit c49373d

Browse files
authored
Fix Label SDF rendering issues with font resizing and other bugs (#2625)
Fixed a bug in Label SDF rendering where font resizing had no effect. Also addressed additional minor issues.
1 parent a340874 commit c49373d

3 files changed

Lines changed: 302 additions & 18 deletions

File tree

core/2d/Label.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ bool Label::updateTTFConfigInternal()
12931293
reset();
12941294
return false;
12951295
}
1296-
1296+
_contentDirty = true;
12971297
_currentLabelType = LabelType::TTF;
12981298
setFontAtlas(newAtlas, _fontConfig.distanceFieldEnabled, true);
12991299

@@ -1305,10 +1305,12 @@ bool Label::updateTTFConfigInternal()
13051305
}
13061306
else
13071307
{
1308-
_currLabelEffect = LabelEffect::NORMAL;
1309-
updateShaderProgram();
1308+
if(_currLabelEffect != LabelEffect::GLOW){
1309+
_currLabelEffect = LabelEffect::NORMAL;
1310+
updateShaderProgram();
1311+
}
13101312
}
1311-
1313+
13121314
if (_fontConfig.italics)
13131315
this->enableItalics();
13141316
if (_fontConfig.bold)
@@ -1370,13 +1372,23 @@ void Label::enableGlow(const Color4B& glowColor)
13701372
{
13711373
if (_currentLabelType == LabelType::TTF)
13721374
{
1373-
if (_fontConfig.distanceFieldEnabled == false)
1375+
auto config = _fontConfig;
1376+
int mods = 0;
1377+
if (config.outlineSize > 0)
1378+
{
1379+
config.outlineSize = 0;
1380+
++mods;
1381+
}
1382+
if (!_fontConfig.distanceFieldEnabled)
13741383
{
1375-
auto config = _fontConfig;
1376-
config.outlineSize = 0;
13771384
config.distanceFieldEnabled = true;
1385+
++mods;
1386+
}
1387+
if (mods)
1388+
{
13781389
setTTFConfig(config);
13791390
_contentDirty = true;
1391+
updateShaderProgram();
13801392
}
13811393
_currLabelEffect = LabelEffect::GLOW;
13821394
_effectColorF.r = glowColor.r / 255.0f;
@@ -1401,18 +1413,15 @@ void Label::enableOutline(const Color4B& outlineColor, int outlineSize /* = -1 *
14011413
_effectColorF.b = outlineColor.b / 255.0f;
14021414
_effectColorF.a = outlineColor.a / 255.0f;
14031415

1404-
if (!_useDistanceField)
1405-
{ // not SDF, request font atlas from feetype
1406-
if (outlineSize > 0 && _fontConfig.outlineSize != outlineSize)
1407-
{
1408-
_fontConfig.outlineSize = outlineSize;
1409-
setTTFConfig(_fontConfig);
1410-
}
1416+
if (outlineSize > 0 && _fontConfig.outlineSize != outlineSize)
1417+
{
1418+
1419+
_fontConfig.outlineSize = outlineSize;
1420+
setTTFConfig(_fontConfig);
14111421
}
1412-
else
1422+
if (_useDistanceField && outlineSize > 0)
14131423
{
1414-
if (outlineSize > 0)
1415-
_currLabelEffect = LabelEffect::OUTLINE;
1424+
_currLabelEffect = LabelEffect::OUTLINE;
14161425
updateShaderProgram();
14171426
}
14181427
}
@@ -1578,7 +1587,7 @@ void Label::disableEffect(LabelEffect effect)
15781587
if (_boldEnabled)
15791588
{
15801589
_boldEnabled = false;
1581-
_additionalKerning -= 1;
1590+
setAdditionalKerning(_additionalKerning - 1);
15821591
disableEffect(LabelEffect::SHADOW);
15831592
}
15841593
break;

tests/cpp-tests/Source/LabelTest/LabelTestNew.cpp

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ NewLabelTests::NewLabelTests()
8585
{
8686
ADD_TEST_CASE(LabelOutlineAndGlowTest);
8787
ADD_TEST_CASE(LabelTTFDistanceField);
88+
ADD_TEST_CASE(LabelTitleButtonTTFDistanceField);
89+
ADD_TEST_CASE(LabelTTFSDF);
8890
ADD_TEST_CASE(LabelIssue1336);
8991
ADD_TEST_CASE(LabelIssue20523);
9092
ADD_TEST_CASE(LabelFNTGlyphDesigner);
@@ -1329,6 +1331,251 @@ std::string LabelTTFDistanceField::subtitle() const
13291331
{
13301332
return "Testing rendering base on DistanceField";
13311333
}
1334+
LabelTitleButtonTTFDistanceField::LabelTitleButtonTTFDistanceField()
1335+
{
1336+
auto size = Director::getInstance()->getWinSize();
1337+
1338+
FontFreeType::setShareDistanceFieldEnabled(false);
1339+
auto button = ax::ui::Button::create();
1340+
button->setTitleText("Should be the same size");
1341+
button->setTitleFontName("fonts/Marker Felt.ttf");
1342+
button->setTitleFontSize(20);
1343+
this->addChild(button);
1344+
button->setPosition(Vec2(size.width / 2, size.height * 0.7f));
1345+
1346+
FontFreeType::setShareDistanceFieldEnabled(true);
1347+
button = ax::ui::Button::create();
1348+
button->setTitleText("Should be the same size");
1349+
button->setTitleFontName("fonts/Marker Felt.ttf");
1350+
button->setTitleFontSize(20);
1351+
this->addChild(button);
1352+
button->setPosition(Vec2(size.width / 2, size.height * 0.55f));
1353+
1354+
FontFreeType::setShareDistanceFieldEnabled(false);
1355+
button = ax::ui::Button::create();
1356+
button->setTitleText("Should be the same size");
1357+
button->setTitleColor(Color3B::RED);
1358+
button->setTitleFontName("fonts/Marker Felt.ttf");
1359+
button->setTitleFontSize(20);
1360+
this->addChild(button);
1361+
button->setPosition(Vec2(size.width / 2, size.height * 0.4f));
1362+
1363+
FontFreeType::setShareDistanceFieldEnabled(true);
1364+
button = ax::ui::Button::create();
1365+
button->setTitleText("Should be the same size");
1366+
button->setTitleColor(Color3B::RED);
1367+
button->setTitleFontName("fonts/Marker Felt.ttf");
1368+
button->setTitleFontSize(20);
1369+
this->addChild(button);
1370+
button->setPosition(Vec2(size.width / 2, size.height * 0.25f));
1371+
}
1372+
1373+
std::string LabelTitleButtonTTFDistanceField::title() const
1374+
{
1375+
return "Title Button + SDF + .TTF (#2623)";
1376+
}
1377+
1378+
std::string LabelTitleButtonTTFDistanceField::subtitle() const
1379+
{
1380+
return "Testing rendering Title of Button on DistanceField";
1381+
}
1382+
LabelTTFSDF::LabelTTFSDF()
1383+
{
1384+
auto size = Director::getInstance()->getWinSize();
1385+
1386+
FontFreeType::setShareDistanceFieldEnabled(false);
1387+
Label* title = Label::createWithTTF("Normal", "fonts/Marker Felt.ttf", 20);
1388+
this->addChild(title);
1389+
title->setPosition(Vec2(size.width*3/4, size.height*0.75));
1390+
_labelNormal = Label::createWithTTF("Should be the same", "fonts/Marker Felt.ttf", 20);;
1391+
this->addChild(_labelNormal);
1392+
_labelNormal->setPosition(Vec2(size.width*3/4, size.height*0.65));
1393+
1394+
FontFreeType::setShareDistanceFieldEnabled(true);
1395+
title = Label::createWithTTF("SDF", "fonts/Marker Felt.ttf", 20);
1396+
this->addChild(title);
1397+
title->setPosition(Vec2(size.width/4, size.height*0.75));
1398+
_labelSDF= Label::createWithTTF("Should be the same", "fonts/Marker Felt.ttf", 20);
1399+
this->addChild(_labelSDF);
1400+
_labelSDF->setPosition(Vec2(size.width/4, size.height*0.65));
1401+
auto config = _labelSDF->getTTFConfig();
1402+
config.distanceFieldEnabled = true;
1403+
_labelSDF->setTTFConfig(config);
1404+
1405+
initToggleLabel("enableItalics", Vec2(size.width*0.15, size.height*0.25), [=, this](Object*obj, ax::ui::CheckBox::EventType type){
1406+
if(type == ax::ui::CheckBox::EventType::SELECTED){
1407+
_labelSDF->enableItalics();
1408+
_labelNormal->enableItalics();
1409+
}else{
1410+
_labelSDF->disableEffect(ax::LabelEffect::ITALICS);
1411+
_labelNormal->disableEffect(ax::LabelEffect::ITALICS);
1412+
}
1413+
});
1414+
initToggleLabel("enableShadow", Vec2(size.width*0.15, size.height*0.35), [=, this](Object*obj, ax::ui::CheckBox::EventType type){
1415+
if(type == ax::ui::CheckBox::EventType::SELECTED){
1416+
_labelSDF->enableShadow(Color4B::YELLOW,Vec2(-1,-1));
1417+
_labelNormal->enableShadow(Color4B::YELLOW,Vec2(-1,-1));
1418+
}else{
1419+
_labelSDF->disableEffect(ax::LabelEffect::SHADOW);
1420+
_labelNormal->disableEffect(ax::LabelEffect::SHADOW);
1421+
}
1422+
});
1423+
initToggleLabel("enableBold", Vec2(size.width*0.15, size.height*0.45), [=, this](Object*obj, ax::ui::CheckBox::EventType type){
1424+
if(type == ax::ui::CheckBox::EventType::SELECTED){
1425+
_labelSDF->enableBold();
1426+
_labelNormal->enableBold();
1427+
}else{
1428+
_labelSDF->disableEffect(ax::LabelEffect::BOLD);
1429+
_labelNormal->disableEffect(ax::LabelEffect::BOLD);
1430+
}
1431+
});
1432+
1433+
initSlider("Size", Vec2(size.width*0.5, size.height*0.20), [=, this](Object*obj, ax::ui::Slider::EventType type){
1434+
Slider* slider = (Slider*)obj;
1435+
float size = 20 + slider->getPercent()/5.f;
1436+
TTFConfig config = _labelSDF->getTTFConfig();
1437+
config.fontSize = size;
1438+
_labelSDF->setTTFConfig(config);
1439+
config = _labelNormal->getTTFConfig();
1440+
config.fontSize = size;
1441+
_labelNormal->setTTFConfig(config);
1442+
1443+
});
1444+
initSlider("Scale", Vec2(size.width*0.5, size.height*0.25), [=, this](Object*obj, ax::ui::Slider::EventType type){
1445+
Slider* slider = (Slider*)obj;
1446+
float scale = 1 + slider->getPercent()/50.f;
1447+
_labelSDF->setScale(scale);
1448+
_labelNormal->setScale(scale);
1449+
});
1450+
_sliderOutline = initSlider("Outline", Vec2(size.width*0.5, size.height*0.30),[=, this](Object*obj, ui::Slider::EventType type){
1451+
Slider* slider = (Slider*)obj;
1452+
float size = 1 + slider->getPercent()/10;
1453+
if(!slider->isEnabled()) return;
1454+
_labelSDF->enableOutline(Color4B::GREEN,size);
1455+
_labelNormal->enableOutline(Color4B::GREEN,size);
1456+
1457+
});
1458+
initToggleCheckboxes();
1459+
_sliderOutline->setEnabled(false);
1460+
_sliderOutline->setOpacity(100);
1461+
}
1462+
ui::Slider* LabelTTFSDF::initSlider(std::string content,Vec2 pos,std::function<void(Object*, ui::Slider::EventType)> callback){
1463+
1464+
auto slider2 = ui::Slider::create();
1465+
slider2->setTag(2);
1466+
slider2->setTouchEnabled(true);
1467+
slider2->loadBarTexture("cocosui/sliderTrack.png");
1468+
slider2->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", "");
1469+
slider2->loadProgressBarTexture("cocosui/sliderProgress.png");
1470+
slider2->setPosition(pos);
1471+
slider2->setPercent(0);
1472+
slider2->setScale(0.6);
1473+
slider2->addEventListener(callback);
1474+
addChild(slider2, 999);
1475+
1476+
auto label = Label::createWithSystemFont(content +": ","Arial",10);
1477+
label->setColor(Color3B::WHITE);
1478+
label->setPosition(pos - Vec2(slider2->getContentSize().width*0.3,0));
1479+
label->setAnchorPoint(Vec2(1,0.5));
1480+
this->addChild(label);
1481+
1482+
return slider2;
1483+
}
1484+
void LabelTTFSDF::initToggleCheckboxes()
1485+
{
1486+
float startPosY = 0;
1487+
Size winSize = Director::getInstance()->getVisibleSize();
1488+
1489+
// Create a radio button group
1490+
auto radioButtonGroup = RadioButtonGroup::create();
1491+
this->addChild(radioButtonGroup);
1492+
1493+
// Create the radio buttons
1494+
static const int NUMBER_OF_BUTTONS = 3;
1495+
startPosY = winSize.height*0.25;
1496+
std::vector<std::string> labelTypes = {"Normal", "Glow", "OutLine"};
1497+
1498+
for (int i = 0; i < NUMBER_OF_BUTTONS; ++i)
1499+
{
1500+
1501+
RadioButton* radioButton = RadioButton::create("cocosui/radio_button_off.png", "cocosui/radio_button_on.png");
1502+
float posY = startPosY + (radioButton->getContentSize().height +5) * i;
1503+
radioButton->setPosition(Vec2(winSize.width*0.8, posY));
1504+
radioButton->addEventListener(AX_CALLBACK_2(LabelTTFSDF::onChangedRadioButtonSelect, this));
1505+
radioButton->setTag(i);
1506+
radioButtonGroup->addRadioButton(radioButton);
1507+
this->addChild(radioButton);
1508+
1509+
auto label = Label::createWithSystemFont(labelTypes.at(i), "Arial", 15);
1510+
label->setPosition(radioButton->getPosition() + Vec2(radioButton->getContentSize().width + 1, 0.0f));
1511+
label->setAnchorPoint(Vec2(0,0.5));
1512+
this->addChild(label);
1513+
}
1514+
}
1515+
void LabelTTFSDF::onChangedRadioButtonSelect(RadioButton* radioButton, RadioButton::EventType type){
1516+
if (radioButton == nullptr)
1517+
{
1518+
return;
1519+
}
1520+
1521+
if (type != RadioButton::EventType::SELECTED)
1522+
return;
1523+
_labelNormal->disableEffect(LabelEffect::OUTLINE);
1524+
_labelNormal->disableEffect(LabelEffect::GLOW);
1525+
_labelSDF->disableEffect(LabelEffect::OUTLINE);
1526+
_labelSDF->disableEffect(LabelEffect::GLOW);
1527+
_sliderOutline->setEnabled(false);
1528+
_sliderOutline->setOpacity(100);
1529+
_sliderOutline->setPercent(0);
1530+
switch (radioButton->getTag())
1531+
{
1532+
case 0:
1533+
break;
1534+
case 1:
1535+
_labelNormal->enableGlow(Color4B::RED);
1536+
_labelSDF->enableGlow(Color4B::RED);
1537+
break;
1538+
case 2:
1539+
_labelSDF->enableOutline(Color4B::GREEN,1);
1540+
_labelNormal->enableOutline(Color4B::GREEN,1);
1541+
_sliderOutline->setEnabled(true);
1542+
_sliderOutline->setOpacity(255);
1543+
break;
1544+
default:
1545+
break;
1546+
}
1547+
1548+
}
1549+
void LabelTTFSDF::initToggleLabel(std::string content, ax::Vec2 pos, std::function<void(Object*, ax::ui::CheckBox::EventType)> callback)
1550+
{
1551+
auto label = Label::createWithSystemFont(content + ":", "Arial", 10);
1552+
label->setColor(Color3B::WHITE);
1553+
label->setPosition(pos);
1554+
label->setAnchorPoint(Vec2(1,0.5));
1555+
this->addChild(label);
1556+
1557+
CheckBox* checkBox = CheckBox::create("cocosui/check_box_normal.png", "cocosui/check_box_normal_press.png",
1558+
"cocosui/check_box_active.png", "cocosui/check_box_normal_disable.png",
1559+
"cocosui/check_box_active_disable.png");
1560+
checkBox->setPosition(pos);
1561+
checkBox->setScale(0.5);
1562+
checkBox->setName("toggleType");
1563+
checkBox->setSelected(true);
1564+
checkBox->addEventListener(callback);
1565+
checkBox->setAnchorPoint(Vec2(0,0.5));
1566+
checkBox->setSelected(false);
1567+
this->addChild(checkBox);
1568+
}
1569+
std::string LabelTTFSDF::title() const
1570+
{
1571+
return "Label + SDF + .TTF (#2623)";
1572+
}
1573+
1574+
std::string LabelTTFSDF::subtitle() const
1575+
{
1576+
return "Testing rendering Label on DistanceField";
1577+
}
1578+
13321579

13331580
LabelOutlineAndGlowTest::LabelOutlineAndGlowTest()
13341581
{

tests/cpp-tests/Source/LabelTest/LabelTestNew.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,34 @@ class LabelTTFDistanceField : public AtlasDemoNew
351351
virtual std::string title() const override;
352352
virtual std::string subtitle() const override;
353353
};
354+
class LabelTitleButtonTTFDistanceField : public AtlasDemoNew
355+
{
356+
public:
357+
CREATE_FUNC(LabelTitleButtonTTFDistanceField);
358+
359+
LabelTitleButtonTTFDistanceField();
360+
361+
virtual std::string title() const override;
362+
virtual std::string subtitle() const override;
363+
};
364+
365+
class LabelTTFSDF : public AtlasDemoNew
366+
{
367+
public:
368+
CREATE_FUNC(LabelTTFSDF);
369+
370+
LabelTTFSDF();
371+
void initLabel(ax::Vec2 pos);
372+
virtual std::string title() const override;
373+
virtual std::string subtitle() const override;
374+
ax::Label* _labelNormal;
375+
ax::Label* _labelSDF;
376+
ax::ui::Slider *_sliderOutline;
377+
void initToggleLabel(std::string content, ax::Vec2 pos, std::function<void(Object*, ax::ui::CheckBox::EventType)> callback);
378+
ax::ui::Slider* initSlider(std::string content,ax::Vec2 pos,std::function<void(Object*, ax::ui::Slider::EventType)> callback);
379+
void initToggleCheckboxes();
380+
void onChangedRadioButtonSelect(ax::ui::RadioButton* radioButton, ax::ui::RadioButton::EventType type);
381+
};
354382

355383
class LabelOutlineAndGlowTest : public AtlasDemoNew
356384
{

0 commit comments

Comments
 (0)