diff --git a/src/libslic3r/TextConfigurationSerialization.cpp b/src/libslic3r/TextConfigurationSerialization.cpp index e508bbf9d..ad6518bfc 100644 --- a/src/libslic3r/TextConfigurationSerialization.cpp +++ b/src/libslic3r/TextConfigurationSerialization.cpp @@ -1,68 +1,101 @@ #include "TextConfigurationSerialization.hpp" - -#include -#include +#include "utils.hpp" using namespace Slic3r; +// Convert map +const std::map TextConfigurationSerialization::to_string = { + {FontItem::Type::file_path, "file_path"}, + {FontItem::Type::wx_font_descr, "wx_font_descriptor"} +}; -const std::string TextConfigurationSerialization::font_item = "FontItem"; -const std::string TextConfigurationSerialization::font_prop = "FontProp"; -const std::string TextConfigurationSerialization::text = "Text"; +const char TextConfigurationSerialization::separator = '|'; -namespace cereal { -template -void serialize(Archive &archive, FontItem &font_item) +const std::map TextConfigurationSerialization::to_type = + TextConfigurationSerialization::create_oposit_map(TextConfigurationSerialization::to_string); + +std::string TextConfigurationSerialization::serialize(const TextConfiguration &text_configuration) { - archive( - CEREAL_NVP(font_item.name), - CEREAL_NVP(font_item.path) - //,CEREAL_NVP(font_item.type) - ); + auto twice_separator = [](const std::string& data) { + if (data.empty()) return std::string(" "); + std::string::size_type pos = data.find(separator); + if (pos == data.npos) return data; + // twice all separator inside data + std::string copy = data; + do { + copy.insert(pos, 1, separator); + pos += 2; + } while (copy.npos != (pos = copy.find(separator, pos))); + return copy; + }; + + const FontItem &font_item = text_configuration.font_item; + const FontProp &font_prop = text_configuration.font_prop; + return twice_separator(text_configuration.text) + separator + + twice_separator(font_item.name) + separator + + twice_separator(font_item.path) + separator + + to_string.at(font_item.type) + separator + + std::to_string(font_prop.emboss) + separator + + std::to_string(font_prop.flatness) + separator + + std::to_string(font_prop.size_in_mm) + separator + + std::to_string(font_prop.char_gap) + separator + + std::to_string(font_prop.line_gap); } -template -void serialize(Archive &archive, FontProp &font_prop) +void TextConfigurationSerialization::to_xml( + const TextConfiguration &text_configuration, + unsigned count_indent, + std::stringstream & stream) { - archive( - CEREAL_NVP(font_prop.char_gap), - CEREAL_NVP(font_prop.line_gap), - CEREAL_NVP(font_prop.flatness), - CEREAL_NVP(font_prop.size_in_mm), - CEREAL_NVP(font_prop.emboss) - ); -} + // Because of back compatibility must be main tag metadata (source: 3mf.cpp) + const std::string_view main_tag = "metadata"; + const std::string_view main_name_attr = "name"; + const std::string_view main_name_value= "TextConfiguration"; -template -void serialize(Archive &archive, TextConfiguration &text_configuration) -{ - archive(CEREAL_NVP(text_configuration.font_item), - CEREAL_NVP(text_configuration.font_prop), - CEREAL_NVP(text_configuration.text)); -} -} // namespace cereal + const std::string_view font_item_tag = "fontItem"; + const std::string_view name_attr = "name"; + const std::string_view path_attr = "path"; + const std::string_view type_attr = "type"; -std::string TextConfigurationSerialization::to_string( - const TextConfiguration &text_configuration) -{ - std::strstream ss; - { - cereal::XMLOutputArchive archive(ss); - // CEREAL_NVP - Names the output the same as the variable name - archive(CEREAL_NVP(text_configuration)); - } - std::string result = ss.str(); - static size_t start = std::string("\n\n\t").size(); - size_t end = result.find("\n", start); - result = result.substr(start, end - start); - return result; + const std::string_view font_prop_tag = "fontProp"; + const std::string_view char_gap_attr = "charGap"; + const std::string_view line_gap_attr = "lineGap"; + const std::string_view flatness_attr = "flatness"; + const std::string_view height_attr = "height"; + const std::string_view depth_attr = "depth"; + + const std::string_view text_tag = "text"; + + auto get_path = [&text_configuration]() { + const std::string &path = text_configuration.font_item.path; + return xml_escape( + (text_configuration.font_item.type == FontItem::Type::file_path) ? + path.substr(path.find_last_of("/\\") + 1) : path); + }; + + std::string indent = std::string(count_indent, ' '); + std::string indent2 = std::string(count_indent+1, ' '); + + stream << indent << "<" << main_tag << " " << main_name_attr << "=\"" << main_name_value << "\">\n"; + stream << indent2 << "<" << font_item_tag + << ' ' << name_attr << "=\"" << xml_escape(text_configuration.font_item.name) << '"' + << ' ' << path_attr << "=\"" << get_path() << '"' + << ' ' << type_attr << "=\"" << to_string.at(text_configuration.font_item.type) << '"' + << "/>\n"; + stream << indent2 << "<" << font_prop_tag + << ' ' << char_gap_attr << "=\"" << text_configuration.font_prop.char_gap << '"' + << ' ' << line_gap_attr << "=\"" << text_configuration.font_prop.line_gap << '"' + << ' ' << flatness_attr << "=\"" << text_configuration.font_prop.flatness << '"' + << ' ' << height_attr << "=\"" << text_configuration.font_prop.size_in_mm << '"' + << ' ' << depth_attr << "=\"" << text_configuration.font_prop.emboss << '"' + << "/>\n"; + stream << indent2 << "<" << text_tag << ">"; + stream << xml_escape(text_configuration.text); + stream << indent2 << "\n"; + stream << indent << "\n"; } std::optional TextConfigurationSerialization::from_string(const std::string &data) { - std::strstream ss; - ss << data; - cereal::XMLInputArchive archive(ss); - TextConfiguration tc; - archive(tc); + TextConfiguration tc; return tc; } \ No newline at end of file diff --git a/src/libslic3r/TextConfigurationSerialization.hpp b/src/libslic3r/TextConfigurationSerialization.hpp index 38eb60495..bdc65c2fc 100644 --- a/src/libslic3r/TextConfigurationSerialization.hpp +++ b/src/libslic3r/TextConfigurationSerialization.hpp @@ -3,6 +3,9 @@ #include "TextConfiguration.hpp" #include +#include +#include +#include namespace Slic3r { @@ -11,13 +14,26 @@ class TextConfigurationSerialization { public: TextConfigurationSerialization() = delete; // only static functions - static std::string to_string(const TextConfiguration &text_configuration); + static std::string serialize(const TextConfiguration &text_configuration); + + static void to_xml(const TextConfiguration &text_configuration, unsigned count_indent, std::stringstream& stream); static std::optional from_string(const std::string &data); -private: - static const std::string font_item; - static const std::string font_prop; - static const std::string text; + // convert type to string and vice versa + static const std::map to_type; + static const std::map to_string; + + static const char separator; + + // Move to map utility + template + static std::map create_oposit_map( + const std::map &map) + { + std::map result; + for (const auto &it : map) result[it.second] = it.first; + return result; + } }; } // namespace Slic3r