From fc196b0965952372fe0b546b5c03bcdc66f16eec Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 19 Apr 2023 13:55:15 +0900 Subject: [PATCH] tools svg2tvg: ++Windows port Complete the Windows port build that is currently missing. @Issue: https://github.com/thorvg/thorvg/issues/882 --- src/bin/svg2tvg/svg2tvg.cpp | 273 +++++++++++++++++++++--------------- 1 file changed, 163 insertions(+), 110 deletions(-) diff --git a/src/bin/svg2tvg/svg2tvg.cpp b/src/bin/svg2tvg/svg2tvg.cpp index 1c00561d..6bad5bd3 100644 --- a/src/bin/svg2tvg/svg2tvg.cpp +++ b/src/bin/svg2tvg/svg2tvg.cpp @@ -23,145 +23,198 @@ #include #include #include -#include +#ifdef _WIN32 + #include + #ifndef PATH_MAX + #define PATH_MAX MAX_PATH + #endif +#else + #include + #include + #include + #include +#endif using namespace std; using namespace tvg; -void helpMsg() +struct App { - cout<<"Usage: \n svg2tvg [SVG file] or [SVG folder]\n\nExamples: \n $ svg2tvg input.svg\n $ svg2tvg svgfolder\n\n"; -} +private: + char full[PATH_MAX]; //full path + void helpMsg() + { + cout << "Usage: \n svg2tvg [SVG file] or [SVG folder]\n\nExamples: \n $ svg2tvg input.svg\n $ svg2tvg svgfolder\n\n"; + } -bool convert(string& in, string& out) -{ - if (Initializer::init(CanvasEngine::Sw, 0) != Result::Success) return false; + bool validate(string& svgName) + { + string extn = ".svg"; - auto picture = Picture::gen(); - if (picture->load(in) != Result::Success) return false; + if (svgName.size() <= extn.size() || svgName.substr(svgName.size() - extn.size()) != extn) { + cout << "Error: \"" << svgName << "\" is invalid." << endl; + return false; + } + return true; + } - auto saver = Saver::gen(); - if (saver->save(move(picture), out) != Result::Success) return false; - if (saver->sync() != Result::Success) return false; + bool convert(string& in, string& out) + { + if (Initializer::init(CanvasEngine::Sw, 0) != Result::Success) return false; - if (Initializer::term(CanvasEngine::Sw) != Result::Success) return false; + auto picture = Picture::gen(); + if (picture->load(in) != Result::Success) return false; - return true; -} + auto saver = Saver::gen(); + if (saver->save(move(picture), out) != Result::Success) return false; + if (saver->sync() != Result::Success) return false; + if (Initializer::term(CanvasEngine::Sw) != Result::Success) return false; -void convert(string& svgName) -{ - //Get tvg file - auto tvgName = svgName; - tvgName.replace(tvgName.length() - 3, 3, "tvg"); + return true; + } - if (convert(svgName, tvgName)) { - cout<<"Generated TVG file : "<< tvgName << endl; - } else { - cout<<"Failed Converting TVG file : "<< svgName << endl; - } -} + void convert(string& svgName) + { + //Get tvg file + auto tvgName = svgName; + tvgName.replace(tvgName.length() - 3, 3, "tvg"); + if (convert(svgName, tvgName)) { + cout << "Generated TVG file : " << tvgName << endl; + } + else { + cout << "Failed Converting TVG file : " << svgName << endl; + } + } -char* getpath(const char* input) -{ - static char buf[PATH_MAX]; + const char* realPath(const char* path) + { #ifdef _WIN32 - return _fullpath(buf, input, PATH_MAX); + return _fullpath(full, path, PATH_MAX); #else - return realpath(input, buf); + return realpath(path, full); #endif -} + } - -bool validate(string& svgName) -{ - string extn = ".svg"; - - if (svgName.size() <= extn.size() || svgName.substr(svgName.size() - extn.size()) != extn) { - cout << "Error: \"" << svgName << "\" is invalid." << endl; - return false; - } - return true; -} - - -void directory(const string& path, DIR* dir) -{ - //List directories - while (auto entry = readdir(dir)) { - if (*entry->d_name == '.' || *entry->d_name == '$') continue; - if (entry->d_type == DT_DIR) { - string subpath = string(path); + bool isDirectory(const char* path) + { #ifdef _WIN32 - subpath += '\\'; + DWORD attr = GetFileAttributes(path); + if (attr == INVALID_FILE_ATTRIBUTES) return false; + return attr & FILE_ATTRIBUTE_DIRECTORY; #else - subpath += '/'; + struct stat buf; + if (stat(path, &buf) != 0) return false; + return S_ISDIR(buf.st_mode); #endif - subpath += entry->d_name; + } - //open directory - if (auto subdir = opendir(subpath.c_str())) { - cout << "Sub Directory: \"" << subpath << "\"" << endl; - directory(subpath, subdir); - closedir(dir); - } - - } else { - string svgName(entry->d_name); - if (!validate(svgName)) continue; - svgName = string(path); + bool handleDirectory(const string& path) + { #ifdef _WIN32 - svgName += '\\'; -#else - svgName += '/'; -#endif - svgName += entry->d_name; - - convert(svgName); + //open directory + WIN32_FIND_DATA fd; + HANDLE h = FindFirstFileEx((path + "\\*").c_str(), FindExInfoBasic, &fd, FindExSearchNameMatch, NULL, 0); + if (h == INVALID_HANDLE_VALUE) { + cout << "Couldn't open directory \"" << path.c_str() << "\"." << endl; + return false; } - } -} + //List directories + do { + if (*fd.cFileName == '.' || *fd.cFileName == '$') continue; + //sub directory + if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + string subpath = string(path); + subpath += '\\'; + subpath += fd.cFileName; + if (!handleDirectory(subpath)) continue; + //file + } else { + string svgName(fd.cFileName); + if (!validate(svgName)) continue; + svgName = string(path); + svgName += '\\'; + svgName += fd.cFileName; + convert(svgName); + } + } while (FindNextFile(h, &fd)); + FindClose(h); +#else + //open directory + auto dir = opendir(path.c_str()); + if (!dir) { + cout << "Couldn't open directory \"" << path.c_str() << "\"." << endl; + return false; + } + //List directories + while (auto entry = readdir(dir)) { + if (*entry->d_name == '.' || *entry->d_name == '$') continue; + //sub directory + if (entry->d_type == DT_DIR) { + string subpath = string(path); + subpath += '/'; + subpath += entry->d_name; + if (!handleDirectory(subpath)) continue; + //file + } else { + string svgName(entry->d_name); + if (!validate(svgName)) continue; + svgName = string(path); + svgName += '/'; + svgName += entry->d_name; + convert(svgName); + } + } +#endif + return true; + } + +public: + int setup(int argc, char** argv) + { + //Collect input files + vector inputs; + + for (int i = 1; i < argc; ++i) { + inputs.push_back(argv[i]); + } + + //No Input SVG + if (inputs.empty()) { + helpMsg(); + return 0; + } + + for (auto input : inputs) { + + auto path = realPath(input); + if (!path) { + cout << "Invalid file or path name: \"" << input << "\"" << endl; + continue; + } + + if (isDirectory(path)) { + //load from directory + cout << "Directory: \"" << path << "\"" << endl; + if (!handleDirectory(path)) break; + } + else { + string svgName(input); + if (!validate(svgName)) continue; + convert(svgName); + } + } + return 0; + } +}; int main(int argc, char **argv) { - //Collect input files - vector inputs; - - for (int i = 1; i < argc; ++i) { - inputs.push_back(argv[i]); - } - - //No Input SVG - if (inputs.empty()) { - helpMsg(); - return 0; - } - - for (auto input : inputs) { - - auto path = getpath(input); - if (!path) { - cout << "Invalid file or path name: \"" << input << "\"" << endl; - continue; - } - - if (auto dir = opendir(path)) { - //load from directory - cout << "Directory: \"" << path << "\"" << endl; - directory(path, dir); - closedir(dir); - } else { - string svgName(input); - if (!validate(svgName)) continue; - convert(svgName); - } - } - - return 0; -} + App app; + return app.setup(argc, argv); +} \ No newline at end of file