如上图所示,根据xml的结构,2349
应该是相同的字号,而cocos2dx的渲染结果却是不同的size
解决办法:
- 在解析xml的时候,font空attribute自动删除
- engine支持空font标签,空属性的font标签也需要push,我采用的是这个方式解决的
我使用的是cocos2dx 3.17,但是这个bug应该在4.x中同样存在
如果删除empty的判断,是解决了空tag的问题,但是又产生了其他问题,下面的xml渲染出来的文字是黄色的
<font color="#ffff00"> <br/> </font> <font> white </font>
导致这个问题的本质上还是无法正确区分标签空属性
和非字体属性标签
MyXMLVisitor::setTagDescription("br", false, [](const ValueMap& /*tagAttrValueMap*/) { RichElementNewLine* richElement = RichElementNewLine::create(0, Color3B::WHITE, 255); return make_pair(ValueMap(), richElement); });
std::pair
主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型,它的定义形式如下:
template <class T1, class T2> struct pair;
这里的make_pair第一个参数,预期返回nullptr
会好点,因为强数据类型的原因,无法返回nullptr
typedef std::unordered_map<std::string, Value> ValueMap; // 无序列表 typedef std::function<std::pair<ValueMap, RichElement*>(const ValueMap& tagAttrValueMap)> VisitEnterHandler; void setTagDescription(const std::string& tag, bool isFontElement, RichText::VisitEnterHandler handleVisitEnter);
void MyXMLVisitor::startElement(void* /*ctx*/, const char* elementName, const char** atts){ auto result = tagBehavior.handleVisitEnter(tagAttrValueMap); ValueMap& attrValueMap = result.first; RichElement* richElement = result.second; }
我们发现凡是返回ValueMap()
的都不是fontElement
,正好和setTagDescription
的第二个参数isFontElement
呼应,也和endElement
逻辑是对应的
void MyXMLVisitor::endElement(void* /*ctx*/, const char* elementName) { auto it = _tagTables.find(elementName); if (it != _tagTables.end()) { auto tagBehavior = it->second; if (tagBehavior.isFontElement) { popBackFontElement(); } } }
具体的修复pr我提交到了官方仓库,虽然现在cocos2dx也很少有人维护了。