Created
July 7, 2019 17:06
-
-
Save Fuyutsubaki/c35765811a94586aa3364924760de277 to your computer and use it in GitHub Desktop.
リッチテキスト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace cfn { | |
struct RichText { | |
std::unique_ptr<XMLElementNode> root_; | |
struct Context { | |
std::int32_t size; | |
}; | |
struct PosState { | |
s3d::Vec2 pos{ 0,0 }; | |
s3d::Vec2 newline_pos{ 0,0 }; | |
}; | |
s3d::Font get_font(Context const& ctx) { | |
s3d::String fontname = s3d::Format(U"s", ctx.size); | |
if (!s3d::FontAsset::IsRegistered(fontname)) { | |
s3d::FontAsset::Register(fontname, ctx.size); | |
} | |
return s3d::FontAsset(fontname); | |
} | |
s3d::Font default_font{ 10 }; | |
RichText(s3d::String const& code) | |
:root_(xml_root_node(U"<default>" + code + U"</default>")) | |
{} | |
void draw(PosState& pos, Context const& ctx, XMLTextNode const& text) { | |
auto font = get_font(ctx); | |
for (s3d::StringView s{ text.text }; s;) { | |
// tokenize(/\n|[^\n]+/) | |
if (s[0] == U'\n') { | |
pos.pos = pos.newline_pos; | |
pos.newline_pos.y = 0; | |
s.remove_prefix(1); | |
} | |
else { | |
auto substr = s.substr(0, s.indexOf(U'\n')); // nposでも期待通り動く | |
auto rect = font(substr).draw(pos.pos); | |
pos.pos = rect.tr(); | |
pos.newline_pos.y = std::max(pos.newline_pos.y, rect.br().y); | |
s.remove_prefix(substr.size()); | |
} | |
} | |
} | |
void draw(PosState&, Context const&, XMLCommentNode const&) { } | |
void draw(PosState&, Context const&, XMLUnknownNode const&) { } | |
void draw(PosState& pos, Context const& ctx_old, XMLElementNode const& elem) { | |
Context ctx = ctx_old; | |
if (elem.name == U"font") { | |
for (auto& [k, v] : elem.attributes) { | |
if (k == U"size") { | |
ctx.size = s3d::ParseInt<std::int32_t>(v); | |
} | |
} | |
} | |
for (auto& node : elem.children) { | |
std::visit([&](auto const& e) { | |
draw(pos, ctx, e); | |
}, *node); | |
} | |
} | |
void draw() { | |
s3d::Vec2{ 0,0 }; | |
PosState pos{ s3d::Vec2{ 0,0 }, s3d::Vec2{ 0,0 } }; | |
Context ctx{ 10 }; | |
draw(pos, ctx, *root_); | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// siv3dの.cppに書いてたやつ | |
// includeとか足りないかも | |
# include <tinyxml/tinyxml2.h> | |
namespace cfn { | |
XMLElementNode buildXML(tinyxml2::XMLElement const*elem) { | |
s3d::Array<std::unique_ptr<XMLNode>> children; | |
for (const tinyxml2::XMLNode* node = elem->FirstChild(); node; node = node->NextSibling()) { | |
if (auto e = node->ToElement()) { | |
children.push_back(std::make_unique<XMLNode>(buildXML(e))); | |
} | |
else if (auto txt = node->ToText()) { | |
children.push_back(std::make_unique<XMLNode>(XMLTextNode{ s3d::Unicode::FromUTF8(txt->Value()) })); | |
} | |
else if (node->ToComment()) { | |
children.push_back(std::make_unique<XMLNode>(XMLCommentNode{})); | |
} | |
else { | |
children.push_back(std::make_unique<XMLNode>(XMLUnknownNode{})); | |
} | |
} | |
s3d::Array<std::pair<s3d::String, s3d::String>> attr_list; | |
for (auto a = elem->FirstAttribute(); a; a = a->Next()) | |
{ | |
attr_list.emplace_back(s3d::Unicode::FromUTF8(a->Name()), s3d::Unicode::FromUTF8(a->Value())); | |
} | |
return XMLElementNode{ s3d::Unicode::FromUTF8(elem->Name()), std::move(attr_list), std::move(children) }; | |
} | |
std::unique_ptr<XMLElementNode> xml_root_node(s3d::String const&code) { | |
std::shared_ptr<tinyxml2::XMLDocument> document = std::make_shared<tinyxml2::XMLDocument>(true, tinyxml2::PRESERVE_WHITESPACE); | |
std::string text = code.toUTF8(); | |
auto err = document->Parse(text.c_str(), text.size()); | |
assert(err == tinyxml2::XML_SUCCESS); | |
auto root = document->FirstChildElement(); | |
return std::make_unique<XMLElementNode>(buildXML(root)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<variant> | |
namespace cfn { | |
struct XMLTextNode; | |
struct XMLElementNode; | |
struct XMLCommentNode; | |
struct XMLUnknownNode; | |
using XMLNode = std::variant<XMLTextNode, XMLElementNode, XMLCommentNode, XMLUnknownNode>; | |
struct XMLTextNode { | |
s3d::String text; | |
}; | |
struct XMLElementNode { | |
s3d::String name; | |
s3d::Array<std::pair<s3d::String, s3d::String>> attributes; | |
s3d::Array<std::unique_ptr<XMLNode>> children; | |
}; | |
struct XMLCommentNode {}; | |
struct XMLUnknownNode {/*no impl*/ }; | |
std::unique_ptr<XMLElementNode> xml_root_node(s3d::String const& code); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment