Skip to content

Commit 8c23d32

Browse files
authored
RichText enhancements (#1683)
* Add paragraph tag support Add HTML header tags support Add multi-new line rich text element Add support for end of tag action General code clean up * Remove redundant additions * Fix compilation issue on platforms other than Windows * Remove redundant constructors and destructors. Initialize member variables. Remove explicit inline specifier since all member class functions are implicitly inlined.
1 parent 2ca2c41 commit 8c23d32

File tree

4 files changed

+254
-75
lines changed

4 files changed

+254
-75
lines changed

core/ui/UIRichText.cpp

Lines changed: 111 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,18 @@ RichElementNewLine* RichElementNewLine::create(int tag, const Color3B& color, ui
288288
return nullptr;
289289
}
290290

291+
RichElementNewLine* RichElementNewLine::create(int tag, int quantity, const Color3B& color, uint8_t opacity)
292+
{
293+
RichElementNewLine* element = new RichElementNewLine(quantity);
294+
if (element->init(tag, color, opacity))
295+
{
296+
element->autorelease();
297+
return element;
298+
}
299+
AX_SAFE_DELETE(element);
300+
return nullptr;
301+
}
302+
291303
/** @brief parse a XML. */
292304
class MyXMLVisitor : public SAXDelegator
293305
{
@@ -340,6 +352,8 @@ class MyXMLVisitor : public SAXDelegator
340352
, italics(false)
341353
, line(StyleLine::NONE)
342354
, effect(StyleEffect::NONE)
355+
, outlineSize(0)
356+
, shadowBlurRadius(0)
343357
{}
344358
};
345359

@@ -352,14 +366,15 @@ class MyXMLVisitor : public SAXDelegator
352366
{
353367
bool isFontElement;
354368
RichText::VisitEnterHandler handleVisitEnter;
369+
RichText::VisitExitHandler handleVisitExit;
355370
};
356371
typedef hlookup::string_map<TagBehavior> TagTables;
357372

358373
static TagTables _tagTables;
359374

360375
public:
361376
explicit MyXMLVisitor(RichText* richText);
362-
virtual ~MyXMLVisitor();
377+
~MyXMLVisitor() override;
363378

364379
Color3B getColor() const;
365380

@@ -397,7 +412,8 @@ class MyXMLVisitor : public SAXDelegator
397412

398413
static void setTagDescription(std::string_view tag,
399414
bool isFontElement,
400-
RichText::VisitEnterHandler&& handleVisitEnter);
415+
RichText::VisitEnterHandler&& handleVisitEnter,
416+
RichText::VisitExitHandler&& handleVisitExit = nullptr);
401417

402418
static void removeTagDescription(std::string_view tag);
403419

@@ -573,6 +589,66 @@ MyXMLVisitor::MyXMLVisitor(RichText* richText) : _fontElements(20), _richText(ri
573589
return make_pair(ValueMap(), richElement);
574590
});
575591

592+
MyXMLVisitor::setTagDescription("p", false, nullptr,
593+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
594+
595+
constexpr auto headerTagEnterHandler = [](const ValueMap& tagAttrValueMap,
596+
float defaultFontSize) -> std::pair<ValueMap, RichElement*> {
597+
ValueMap attrValueMap;
598+
if (tagAttrValueMap.find("size") != tagAttrValueMap.end())
599+
{
600+
attrValueMap[RichText::KEY_FONT_SIZE] = tagAttrValueMap.at("size").asString();
601+
}
602+
else
603+
{
604+
attrValueMap[RichText::KEY_FONT_SIZE] = defaultFontSize;
605+
}
606+
607+
if (tagAttrValueMap.find("color") != tagAttrValueMap.end())
608+
{
609+
attrValueMap[RichText::KEY_FONT_COLOR_STRING] = tagAttrValueMap.at("color").asString();
610+
}
611+
612+
if (tagAttrValueMap.find("face") != tagAttrValueMap.end())
613+
{
614+
attrValueMap[RichText::KEY_FONT_FACE] = tagAttrValueMap.at("face").asString();
615+
}
616+
617+
attrValueMap[RichText::KEY_TEXT_BOLD] = true;
618+
619+
return make_pair(attrValueMap, nullptr);
620+
};
621+
622+
MyXMLVisitor::setTagDescription(
623+
"h1", true,
624+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 34); },
625+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
626+
627+
MyXMLVisitor::setTagDescription(
628+
"h2", true,
629+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 30); },
630+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
631+
632+
MyXMLVisitor::setTagDescription(
633+
"h3", true,
634+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 24); },
635+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
636+
637+
MyXMLVisitor::setTagDescription(
638+
"h4", true,
639+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 20); },
640+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
641+
642+
MyXMLVisitor::setTagDescription(
643+
"h5", true,
644+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 18); },
645+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
646+
647+
MyXMLVisitor::setTagDescription(
648+
"h6", true,
649+
[headerTagEnterHandler](const ValueMap& tagAttrValueMap) { return headerTagEnterHandler(tagAttrValueMap, 16); },
650+
[] { return RichElementNewLine::create(0, 2, Color3B::WHITE, 255); });
651+
576652
MyXMLVisitor::setTagDescription("outline", true, [](const ValueMap& tagAttrValueMap) {
577653
// supported attributes:
578654
// color, size
@@ -915,6 +991,15 @@ void MyXMLVisitor::endElement(void* /*ctx*/, const char* elementName)
915991
{
916992
popBackFontElement();
917993
}
994+
995+
if (tagBehavior.handleVisitExit != nullptr)
996+
{
997+
auto* richElement = tagBehavior.handleVisitExit();
998+
if (richElement)
999+
{
1000+
pushBackElement(richElement);
1001+
}
1002+
}
9181003
}
9191004
}
9201005

@@ -974,14 +1059,12 @@ void MyXMLVisitor::pushBackElement(RichElement* element)
9741059

9751060
void MyXMLVisitor::setTagDescription(std::string_view tag,
9761061
bool isFontElement,
977-
RichText::VisitEnterHandler&& handleVisitEnter)
1062+
RichText::VisitEnterHandler&& handleVisitEnter,
1063+
RichText::VisitExitHandler&& handleVisitExit)
9781064
{
979-
hlookup::set_item(
980-
MyXMLVisitor::_tagTables, tag,
981-
TagBehavior{
982-
isFontElement,
983-
std::move(
984-
handleVisitEnter)}); // MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter)};
1065+
// MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)};
1066+
hlookup::set_item(MyXMLVisitor::_tagTables, tag,
1067+
TagBehavior{isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)});
9851068
}
9861069

9871070
void MyXMLVisitor::removeTagDescription(std::string_view tag)
@@ -1536,9 +1619,11 @@ std::string RichText::stringWithColor4B(const ax::Color4B& color4b)
15361619
return std::string(buf, 9);
15371620
}
15381621

1539-
void RichText::setTagDescription(std::string_view tag, bool isFontElement, VisitEnterHandler handleVisitEnter)
1622+
void RichText::setTagDescription(std::string_view tag,
1623+
bool isFontElement,
1624+
VisitEnterHandler handleVisitEnter, VisitExitHandler handleVisitExit)
15401625
{
1541-
MyXMLVisitor::setTagDescription(tag, isFontElement, std::move(handleVisitEnter));
1626+
MyXMLVisitor::setTagDescription(tag, isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit));
15421627
}
15431628

15441629
void RichText::removeTagDescription(std::string_view tag)
@@ -1659,7 +1744,9 @@ void RichText::formatText(bool force)
16591744
}
16601745
case RichElement::Type::NEWLINE:
16611746
{
1662-
addNewLine();
1747+
auto* newLineMulti = static_cast<RichElementNewLine*>(element);
1748+
1749+
addNewLine(newLineMulti->_quantity);
16631750
break;
16641751
}
16651752
default:
@@ -1678,7 +1765,7 @@ void RichText::formatText(bool force)
16781765
addNewLine();
16791766
for (ssize_t i = 0, size = _richElements.size(); i < size; ++i)
16801767
{
1681-
RichElement* element = static_cast<RichElement*>(_richElements.at(i));
1768+
RichElement* element = _richElements.at(i);
16821769
switch (element->_type)
16831770
{
16841771
case RichElement::Type::TEXT:
@@ -1706,7 +1793,9 @@ void RichText::formatText(bool force)
17061793
}
17071794
case RichElement::Type::NEWLINE:
17081795
{
1709-
addNewLine();
1796+
auto* newLineMulti = static_cast<RichElementNewLine*>(element);
1797+
1798+
addNewLine(newLineMulti->_quantity);
17101799
break;
17111800
}
17121801
default:
@@ -2049,11 +2138,15 @@ void RichText::handleCustomRenderer(ax::Node* renderer)
20492138
}
20502139
}
20512140

2052-
void RichText::addNewLine()
2141+
void RichText::addNewLine(int quantity)
20532142
{
2054-
_leftSpaceWidth = _customSize.width;
2055-
_elementRenders.emplace_back();
2056-
_lineHeights.emplace_back();
2143+
do
2144+
{
2145+
_leftSpaceWidth = _customSize.width;
2146+
_elementRenders.emplace_back();
2147+
_lineHeights.emplace_back();
2148+
}
2149+
while (--quantity > 0);
20572150
}
20582151

20592152
void RichText::formatRenderers()

0 commit comments

Comments
 (0)