#include "TextConfigurationSerialization.hpp" #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"}, {FontItem::Type::undefined, "unknown"} }; const std::map TextConfigurationSerialization::to_type = TextConfigurationSerialization::create_oposit_map(TextConfigurationSerialization::to_string); const char TextConfigurationSerialization::separator = '|'; std::string TextConfigurationSerialization::serialize(const TextConfiguration &text_configuration) { size_t size = 1 + 3 + 5; std::vector columns; columns.reserve(size); columns.emplace_back(text_configuration.text); to_columns(text_configuration.font_item, columns); to_columns(text_configuration.font_prop, columns); assert(columns.size() == size); return serialize(columns, separator); } std::optional TextConfigurationSerialization::deserialize(const std::string &data) { size_t size = 1 + 3 + 5; std::vector columns; columns.reserve(size); deserialize(data, separator, columns); assert(columns.size() == size); const std::string& text = columns[0]; std::optional font_item = get_font_item(columns, 1); if (!font_item.has_value()) return {}; std::optional font_prop = get_font_prop(columns, 4); if (!font_prop.has_value()) return {}; return TextConfiguration(*font_item, *font_prop, text); } std::string TextConfigurationSerialization::serialize(const FontList &font_list) { std::vector columns; columns.reserve(3 * font_list.size()); for (const FontItem &fi : font_list) to_columns(fi, columns); return serialize(columns, separator); } FontList TextConfigurationSerialization::deserialize_font_list(const std::string &data) { std::vector columns; deserialize(data, separator, columns); if ((columns.size() % 3) != 0) return {}; size_t count = columns.size() / 3; FontList fl; fl.reserve(count); for (size_t i = 0; i < count; i++) { std::optional fi = get_font_item(columns, i * 3); if (!fi.has_value()) return {}; fl.emplace_back(*fi); } return fl; } std::string TextConfigurationSerialization::serialize(const std::vector &columns, char separator) { std::string result; const std::string separator_str = std::string(" ") + separator + ' '; bool is_first = true; for (const std::string& column : columns) { if (is_first) is_first = false; else result += separator_str; result += twice(column, separator); } return result; } void TextConfigurationSerialization::deserialize(const std::string &data, char separator, std::vector &columns) { if (data.empty()) return; size_t position = 0; while (position < data.size()) { size_t start = position; position = find_odd(data, position+1, separator); size_t size = position - start; // is not last column if (position != data.size()) { assert(size != 0); --size; } // is not first column if (start != 0) { // previous separator + space = 2 start+=2; assert(size >=2); size-=2; } std::string column = data.substr(start, size); // heal column columns.emplace_back(reduce(column, separator)); } } std::string TextConfigurationSerialization::serialize(const FontItem::Type &type) { auto it = to_string.find(type); assert(it != to_string.end()); if (it == to_string.end()) return serialize(FontItem::Type::undefined); return it->second; } FontItem::Type TextConfigurationSerialization::deserialize_type(const std::string &type) { auto it = to_type.find(type); assert(it != to_type.end()); if (it == to_type.end()) return FontItem::Type::undefined; return it->second; } void TextConfigurationSerialization::to_columns( const FontItem &font_item, std::vector &columns) { columns.emplace_back(font_item.name); columns.emplace_back(font_item.path); columns.emplace_back(serialize(font_item.type)); } std::optional TextConfigurationSerialization::get_font_item( const std::vector &columns, size_t offset) { if (columns.size() <= (offset + 2)) return {}; // no enough columns FontItem::Type type = deserialize_type(columns[offset + 2]); return FontItem(columns[offset], columns[offset + 1], type); } void TextConfigurationSerialization::to_columns( const FontProp& font_prop, std::vector &columns) { columns.emplace_back(std::to_string(font_prop.emboss)); columns.emplace_back(std::to_string(font_prop.flatness)); columns.emplace_back(std::to_string(font_prop.size_in_mm)); columns.emplace_back(std::to_string(font_prop.char_gap)); columns.emplace_back(std::to_string(font_prop.line_gap)); } std::optional TextConfigurationSerialization::get_font_prop( const std::vector &columns, size_t offset) { if (columns.size() <= (offset + 4)) return {}; // no enough columns FontProp font_prop; font_prop.emboss = static_cast(std::atof(columns[offset].c_str())); font_prop.flatness = static_cast(std::atof(columns[offset+1].c_str())); font_prop.size_in_mm = static_cast(std::atof(columns[offset+2].c_str())); font_prop.char_gap = static_cast(std::atof(columns[offset+3].c_str())); font_prop.line_gap = std::atoi(columns[offset+4].c_str()); return font_prop; }