diff --git a/src/libslic3r/EmbossShape.hpp b/src/libslic3r/EmbossShape.hpp index 3c35bf2b64..72693c6675 100644 --- a/src/libslic3r/EmbossShape.hpp +++ b/src/libslic3r/EmbossShape.hpp @@ -100,7 +100,7 @@ struct EmbossShape std::shared_ptr image = nullptr; // Loaded string data from file - std::shared_ptr file_data = nullptr; + std::shared_ptr file_data = nullptr; }; SvgFile svg_file; diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 89f76bd52d..311e441e5c 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -474,7 +474,7 @@ namespace Slic3r { typedef std::map IdToCutObjectInfoMap; typedef std::map> IdToSlaSupportPointsMap; typedef std::map> IdToSlaDrainHolesMap; - using PathToEmbossShapeFileMap = std::map>; + using PathToEmbossShapeFileMap = std::map>; // Version of the 3mf file unsigned int m_version; bool m_check_version; @@ -1387,25 +1387,18 @@ namespace Slic3r { void _3MF_Importer::_extract_embossed_svg_shape_file(const std::string &filename, mz_zip_archive &archive, const mz_zip_archive_file_stat &stat){ assert(m_path_to_emboss_shape_files.find(filename) == m_path_to_emboss_shape_files.end()); - - std::unique_ptr file{new char[stat.m_uncomp_size + 1]}; - if (file == nullptr){ - add_error("Cannot alocate space for SVG file."); - return; - } - - mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void *) file.get(), (size_t) stat.m_uncomp_size, 0); + auto file = std::make_unique(stat.m_uncomp_size, '\0'); + mz_bool res = mz_zip_reader_extract_to_mem(&archive, stat.m_file_index, (void *) file->data(), stat.m_uncomp_size, 0); if (res == 0) { add_error("Error while reading svg shape for emboss"); return; } - file.get()[stat.m_uncomp_size] = '\0'; // Must be null terminated. // store for case svg is loaded before volume m_path_to_emboss_shape_files[filename] = std::move(file); // find embossed volume, for case svg is loaded after volume - for (ModelObject* object : m_model->objects) + for (const ModelObject* object : m_model->objects) for (ModelVolume *volume : object->volumes) { std::optional &es = volume->emboss_shape; if (!es.has_value()) @@ -3752,15 +3745,8 @@ bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const Mo stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path) << "\" "; stream << SVG_FILE_PATH_IN_3MF_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path_in_3mf) << "\" "; - char *data = svg.file_data.get(); - assert(data != nullptr); - if (data == nullptr) - return false; - - // NOTE: file data must be null terminated - size_t size = 0; - for (char *c = data; *c != '\0'; ++c) ++size; - if (!mz_zip_writer_add_mem(&archive, svg.path_in_3mf.c_str(), (const void *) data, size, MZ_DEFAULT_COMPRESSION)) + const std::string &file_data = *svg.file_data; + if (!mz_zip_writer_add_mem(&archive, svg.path_in_3mf.c_str(), (const void *) file_data.c_str(), file_data.size(), MZ_DEFAULT_COMPRESSION)) return false; return true; } diff --git a/src/libslic3r/NSVGUtils.cpp b/src/libslic3r/NSVGUtils.cpp index 5ef3177341..7a8683e18f 100644 --- a/src/libslic3r/NSVGUtils.cpp +++ b/src/libslic3r/NSVGUtils.cpp @@ -98,41 +98,28 @@ void bounds(const NSVGimage &image, Vec2f& min, Vec2f &max) NSVGimage_ptr nsvgParseFromFile(const std::string &filename, const char *units, float dpi) { NSVGimage *image = ::nsvgParseFromFile(filename.c_str(), units, dpi); - return {image, ::nsvgDelete}; + return {image, &nsvgDelete}; } -std::unique_ptr read_from_disk(const std::string& path) +std::unique_ptr read_from_disk(const std::string &path) { - FILE *fp = boost::nowide::fopen(path.c_str(), "rb"); - if (!fp) + std::ifstream fs{path}; + if (!fs.is_open()) return nullptr; - - fseek(fp, 0, SEEK_END); - size_t size = ftell(fp); - fseek(fp, 0, SEEK_SET); - - std::unique_ptr result{new char[size + 1]}; - if (result == nullptr) - return nullptr; - - if (fread(result.get(), 1, size, fp) != size) - return nullptr; - - result.get()[size] = '\0'; // Must be null terminated. - fclose(fp); - return result; + std::stringstream ss; + ss << fs.rdbuf(); + return std::make_unique(ss.str()); } -NSVGimage_ptr nsvgParse(const std::shared_ptr file_data, const char *units, float dpi){ - size_t size = 0; - for (char *c = file_data.get(); *c != '\0'; ++c) - ++size; - - // NOTE: nsvg parser consume data from pointer - std::unique_ptr data_copy(new char[size]); - memcpy(data_copy.get(), file_data.get(), size); +NSVGimage_ptr nsvgParse(const std::string& file_data, const char *units, float dpi){ + // NOTE: nsvg parser consume data from input(char *) + size_t size = file_data.size(); + // file data could be big, so it is allocated on heap + std::unique_ptr data_copy(new char[size+1]); + memcpy(data_copy.get(), file_data.c_str(), size); + data_copy[size] = '\0'; // data for nsvg must be null terminated NSVGimage *image = ::nsvgParse(data_copy.get(), units, dpi); - return {image, ::nsvgDelete}; + return {image, &nsvgDelete}; } size_t get_shapes_count(const NSVGimage &image) diff --git a/src/libslic3r/NSVGUtils.hpp b/src/libslic3r/NSVGUtils.hpp index a15472f64e..62ad3deb27 100644 --- a/src/libslic3r/NSVGUtils.hpp +++ b/src/libslic3r/NSVGUtils.hpp @@ -66,11 +66,11 @@ Polygons to_polygons(const NSVGimage &image, const NSVGLineParams ¶m); void bounds(const NSVGimage &image, Vec2f &min, Vec2f &max); // read text data from file -std::unique_ptr read_from_disk(const std::string &path); +std::unique_ptr read_from_disk(const std::string &path); using NSVGimage_ptr = std::unique_ptr; NSVGimage_ptr nsvgParseFromFile(const std::string &svg_file_path, const char *units = "mm", float dpi = 96.0f); -NSVGimage_ptr nsvgParse(const std::shared_ptr file_data, const char *units = "mm", float dpi = 96.0f); +NSVGimage_ptr nsvgParse(const std::string& file_data, const char *units = "mm", float dpi = 96.0f); /// /// Iterate over shapes and calculate count diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index dc6f4d535c..36d3c4e54b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -570,7 +570,7 @@ NSVGimage* init_image(EmbossShape::SvgFile &svg_file) { } // init svg image - svg_file.image = nsvgParse(svg_file.file_data); + svg_file.image = nsvgParse(*svg_file.file_data); if (svg_file.image.get() == NULL) return nullptr; @@ -1375,20 +1375,13 @@ void GLGizmoSVG::draw_filename(){ EmbossShape::SvgFile &svg = m_volume_shape.svg_file; std::stringstream ss; Slic3r::save(*svg.image, ss); - ss << '\0'; // Must be null terminated. - std::string str = ss.str(); - std::unique_ptr new_data{new char[str.size() + 1]}; - assert(new_data != nullptr); - if (new_data != nullptr) { - std::copy(str.begin(), str.end(), new_data.get()); - svg.file_data = std::move(new_data); - svg.image = nsvgParse(svg.file_data); - assert(svg.image.get() != NULL); - if (svg.image.get() != NULL) { - m_volume->emboss_shape->svg_file = svg; // copy - write changes into volume - } else { - svg = m_volume->emboss_shape->svg_file; // revert changes - } + svg.file_data = std::make_unique(ss.str()); + svg.image = nsvgParse(*svg.file_data); + assert(svg.image.get() != NULL); + if (svg.image.get() != NULL) { + m_volume->emboss_shape->svg_file = svg; // copy - write changes into volume + } else { + svg = m_volume->emboss_shape->svg_file; // revert changes } } else if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", _u8L("Use only paths from svg - recreate svg").c_str()); @@ -2000,8 +1993,7 @@ EmbossShape select_shape(std::string_view filepath, double tesselation_tolerance return {}; } - init_image(shape.svg_file); - if (shape.svg_file.image.get() == NULL) { + if(init_image(shape.svg_file) == nullptr) { show_error(nullptr, GUI::format(_u8L("Nano SVG parser can't load from file(%1%)."), shape.svg_file.path)); return {}; }