From 4943f35d918643bb397e782e1ad694a8413b85fe Mon Sep 17 00:00:00 2001 From: TennesseeTrash Date: Tue, 10 Jun 2025 22:40:46 +0200 Subject: [PATCH 1/2] Add separate functions for removing stroke numbers --- .../Kanimaji/Include/Kanimaji/Kanimaji.hpp | 9 +- Libraries/Kanimaji/Source/Kanimaji.cpp | 83 +++++++++++++++---- 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/Libraries/Kanimaji/Include/Kanimaji/Kanimaji.hpp b/Libraries/Kanimaji/Include/Kanimaji/Kanimaji.hpp index 79c6bd0..79d3d9b 100644 --- a/Libraries/Kanimaji/Include/Kanimaji/Kanimaji.hpp +++ b/Libraries/Kanimaji/Include/Kanimaji/Kanimaji.hpp @@ -3,18 +3,19 @@ #include "Settings.hpp" -#include #include namespace Kanimaji { - using Path = std::filesystem::path; - - void AnimateFile(const Path& source, const Path& destination, + void AnimateFile(const std::string& source, const std::string& destination, const AnimationSettings& settings = AnimationSettings::Default()); std::string Animate(const std::string& source, const AnimationSettings& settings = AnimationSettings::Default()); + + void RemoveStrokeNumbers(const std::string& source, const std::string& destination); + + std::string RemoveStrokeNumbers(const std::string& source); } #endif // KANIMAJI_KANIMAJI_HPP diff --git a/Libraries/Kanimaji/Source/Kanimaji.cpp b/Libraries/Kanimaji/Source/Kanimaji.cpp index 27cdadd..3bf8034 100644 --- a/Libraries/Kanimaji/Source/Kanimaji.cpp +++ b/Libraries/Kanimaji/Source/Kanimaji.cpp @@ -53,6 +53,13 @@ namespace Kanimaji return std::max(0.0, duration.count()); } + void RemoveStrokeNumbers(pugi::xml_node& svg) + { + svg.remove_child(svg.find_child([](pugi::xml_node& node) { + return std::string_view(node.attribute("id").as_string()).contains("StrokeNumbers"); + })); + } + pugi::xml_node AppendGroup(pugi::xml_node& svg, std::string_view name, StrokeStyle config) { pugi::xml_node newGroup = svg.append_child("g"); @@ -92,17 +99,8 @@ namespace Kanimaji } } - void Animate(pugi::xml_document& doc, const AnimationSettings& settings) + void Animate(pugi::xml_node& svg, const AnimationSettings& settings) { - pugi::xml_node svg = doc.child("svg"); - if (!svg) { - throw Error("Unexpected document format: Expected to find a SVG element"); - } - - svg.remove_child(svg.find_child([](pugi::xml_node& node) { - return std::string_view(node.attribute("id").as_string()).contains("StrokeNumbers"); - })); - pugi::xml_node pathsGroup = svg.find_child([](pugi::xml_node& node) { return std::string_view(node.attribute("id").as_string()).contains("StrokePaths"); }); @@ -225,20 +223,27 @@ namespace Kanimaji } } - void AnimateFile(const Path& source, const Path& destination, const AnimationSettings& settings) + void AnimateFile(const std::string& source, const std::string& destination, + const AnimationSettings& settings) { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(source.c_str(), pugi::parse_full); if (!result) { constexpr std::string_view errorFormat = "Failed to load file from {}, due to: {}"; - throw FileError(std::format(errorFormat, source.string(), result.description())); + throw FileError(std::format(errorFormat, source, result.description())); + } + + pugi::xml_node svg = doc.child("svg"); + if (!svg) { + throw Error("Unexpected document format: Expected to find a SVG element"); } AmendComment(doc); - Animate(doc, settings); + RemoveStrokeNumbers(svg); + Animate(svg, settings); if (!doc.save_file(destination.c_str())) { - throw FileError(std::format("Failed to save file to {}", destination.string())); + throw FileError(std::format("Failed to save file to {}", destination)); } } @@ -251,8 +256,56 @@ namespace Kanimaji throw ParseError(result.offset, std::format(errorFormat, result.description())); } + pugi::xml_node svg = doc.child("svg"); + if (!svg) { + throw Error("Unexpected document format: Expected to find a SVG element"); + } + AmendComment(doc); - Animate(doc, settings); + RemoveStrokeNumbers(svg); + Animate(svg, settings); + + std::stringstream str; + doc.save(str); + return str.str(); + } + + void RemoveStrokeNumbers(const std::string& source, const std::string& destination) + { + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(source.c_str(), pugi::parse_full); + if (!result) { + constexpr std::string_view errorFormat = "Failed to load file from {}, due to: {}"; + throw FileError(std::format(errorFormat, source, result.description())); + } + + pugi::xml_node svg = doc.child("svg"); + if (!svg) { + throw Error("Unexpected document format: Expected to find a SVG element"); + } + + RemoveStrokeNumbers(svg); + + if (!doc.save_file(destination.c_str())) { + throw FileError(std::format("Failed to save file to {}", destination)); + } + } + + std::string RemoveStrokeNumbers(const std::string& source) + { + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_string(source.c_str(), pugi::parse_full); + if (!result) { + constexpr std::string_view errorFormat = "Failed to parse SVG document: {}"; + throw ParseError(result.offset, std::format(errorFormat, result.description())); + } + + pugi::xml_node svg = doc.child("svg"); + if (!svg) { + throw Error("Unexpected document format: Expected to find a SVG element"); + } + + RemoveStrokeNumbers(svg); std::stringstream str; doc.save(str); From 3b5eb6f1a456bfcd7313bd532913368791812c0e Mon Sep 17 00:00:00 2001 From: TennesseeTrash Date: Sat, 14 Jun 2025 13:19:47 +0200 Subject: [PATCH 2/2] [Megane] Add tiny library to translate utf8 characters to kvg code --- CMake/gtl.cmake | 13 ++++++ CMake/mio.cmake | 13 ++++++ CMake/simdjson.cmake | 13 ++++++ Libraries/CMakeLists.txt | 1 + Libraries/Megane/CMakeLists.txt | 26 ++++++++++++ Libraries/Megane/Include/Megane/Megane.hpp | 29 +++++++++++++ Libraries/Megane/Source/Megane.cpp | 49 ++++++++++++++++++++++ Tools/KanimajiTool/CMakeLists.txt | 1 + 8 files changed, 145 insertions(+) create mode 100644 CMake/gtl.cmake create mode 100644 CMake/mio.cmake create mode 100644 CMake/simdjson.cmake create mode 100644 Libraries/Megane/CMakeLists.txt create mode 100644 Libraries/Megane/Include/Megane/Megane.hpp create mode 100644 Libraries/Megane/Source/Megane.cpp diff --git a/CMake/gtl.cmake b/CMake/gtl.cmake new file mode 100644 index 0000000..a1839b2 --- /dev/null +++ b/CMake/gtl.cmake @@ -0,0 +1,13 @@ +if(NOT TARGET gtl) + include(FetchContent) + + FetchContent_Declare( + gtl + GIT_REPOSITORY https://code.3011.io/Mirrors/gtl + GIT_TAG v1.2.0 + ) + + FetchContent_MakeAvailable( + gtl + ) +endif() diff --git a/CMake/mio.cmake b/CMake/mio.cmake new file mode 100644 index 0000000..5bddb1a --- /dev/null +++ b/CMake/mio.cmake @@ -0,0 +1,13 @@ +if(NOT TARGET mio) + include(FetchContent) + + FetchContent_Declare( + mio + GIT_REPOSITORY https://code.3011.io/Mirrors/mio + GIT_TAG 8b6b7d878c89e81614d05edca7936de41ccdd2da + ) + + FetchContent_MakeAvailable( + mio + ) +endif() diff --git a/CMake/simdjson.cmake b/CMake/simdjson.cmake new file mode 100644 index 0000000..7bc9fb6 --- /dev/null +++ b/CMake/simdjson.cmake @@ -0,0 +1,13 @@ +if(NOT TARGET simdjson) + include(FetchContent) + + FetchContent_Declare( + simdjson + GIT_REPOSITORY https://code.3011.io/Mirrors/simdjson + GIT_TAG v3.13.0 + ) + + FetchContent_MakeAvailable( + simdjson + ) +endif() diff --git a/Libraries/CMakeLists.txt b/Libraries/CMakeLists.txt index 570f2c3..9018b17 100644 --- a/Libraries/CMakeLists.txt +++ b/Libraries/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(Kanimaji) +add_subdirectory(Megane) diff --git a/Libraries/Megane/CMakeLists.txt b/Libraries/Megane/CMakeLists.txt new file mode 100644 index 0000000..9a91edc --- /dev/null +++ b/Libraries/Megane/CMakeLists.txt @@ -0,0 +1,26 @@ +include(${PROJECT_SOURCE_DIR}/CMake/gtl.cmake) +include(${PROJECT_SOURCE_DIR}/CMake/simdjson.cmake) + +add_library(Megane STATIC) + +target_compile_features(Megane + PUBLIC + cxx_std_23 +) + +target_link_libraries(Megane + PRIVATE + simdjson + PUBLIC + gtl +) + +target_include_directories(Megane + PUBLIC + "Include" +) + +target_sources(Megane + PRIVATE + "Source/Megane.cpp" +) diff --git a/Libraries/Megane/Include/Megane/Megane.hpp b/Libraries/Megane/Include/Megane/Megane.hpp new file mode 100644 index 0000000..236f6cc --- /dev/null +++ b/Libraries/Megane/Include/Megane/Megane.hpp @@ -0,0 +1,29 @@ +#ifndef MEGANE_MEGANE_HPP +#define MEGANE_MEGANE_HPP + +#include + +#include +#include + +namespace Megane +{ + class Error : public std::runtime_error + { + using std::runtime_error::runtime_error; + }; + + class Megane + { + public: + Megane(const std::string& indexPath); + ~Megane(); + + std::string GetCode(const std::string& character) const; + + private: + gtl::flat_hash_map mStorage; + }; +} + +#endif // MEGANE_MEGANE_HPP diff --git a/Libraries/Megane/Source/Megane.cpp b/Libraries/Megane/Source/Megane.cpp new file mode 100644 index 0000000..4b7f8b9 --- /dev/null +++ b/Libraries/Megane/Source/Megane.cpp @@ -0,0 +1,49 @@ +#include "Megane/Megane.hpp" + +#include + +#include +#include +#include + +namespace Megane +{ + Megane::Megane(const std::string& indexPath) + { + auto res = simdjson::padded_string::load(indexPath); + if (res.error()) { + throw Error("Could not load the file"); + } + simdjson::padded_string rawJson = std::move(res.value()); + + simdjson::ondemand::parser parser; + simdjson::ondemand::document document = parser.iterate(rawJson); + for (auto field : document.get_object()) { + std::string_view key = field.unescaped_key(); + std::string_view value; + for (auto candidate : field.value()) { + if (value.length() == 0) { + value = candidate.value_unsafe().get_string(); + } + else { + std::string_view candidateValue(candidate); + if (candidateValue.length() < value.length()) { + value = candidateValue; + } + } + } + mStorage[std::string(key)] = value; + } + } + + Megane::~Megane() = default; + + std::string Megane::GetCode(const std::string& character) const + { + auto it = mStorage.find(character); + if (it == mStorage.end()) { + throw Error("Failed to find the provided character"); + } + return it->second; + } +} diff --git a/Tools/KanimajiTool/CMakeLists.txt b/Tools/KanimajiTool/CMakeLists.txt index d194754..3724680 100644 --- a/Tools/KanimajiTool/CMakeLists.txt +++ b/Tools/KanimajiTool/CMakeLists.txt @@ -8,6 +8,7 @@ target_compile_features(KanimajiTool target_link_libraries(KanimajiTool PRIVATE Kanimaji + Megane ) target_sources(KanimajiTool