Compare commits

...

2 commits

5 changed files with 72 additions and 20 deletions

View file

@ -13,9 +13,11 @@ namespace Kanimaji
std::string Animate(const std::string& source, std::string Animate(const std::string& source,
const AnimationSettings& settings = AnimationSettings::Default()); const AnimationSettings& settings = AnimationSettings::Default());
void RemoveStrokeNumbers(const std::string& source, const std::string& destination); void RemoveStrokeNumbers(const std::string& source, const std::string& destination,
const RemovalSetttings& settings = RemovalSetttings::Default());
std::string RemoveStrokeNumbers(const std::string& source); std::string RemoveStrokeNumbers(const std::string& source,
const RemovalSetttings& settings = RemovalSetttings::Default());
} }
#endif // KANIMAJI_KANIMAJI_HPP #endif // KANIMAJI_KANIMAJI_HPP

View file

@ -49,6 +49,13 @@ namespace Kanimaji
static AnimationSettings Default(); static AnimationSettings Default();
}; };
struct RemovalSetttings
{
StrokeStyle Style;
static RemovalSetttings Default();
};
} }
#endif // KANIMAJI_CONFIG_HPP #endif // KANIMAJI_CONFIG_HPP

View file

@ -12,42 +12,55 @@ namespace Kanimaji
{ {
namespace namespace
{ {
using namespace std::string_view_literals; constexpr std::string_view StaticStrokeStyleFormat(
constexpr auto StrokeProgressionFormat = "fill:none;stroke:{};stroke-width:{};stroke-linecap:round;stroke-linejoin:round;"
);
constexpr std::string_view StrokeProgressionFormat(
" " " "
"@keyframes stroke-{} {{ " "@keyframes stroke-{} {{ "
"0.000% {{ stroke-dashoffset: {:.3f}; }} " "0.000% {{ stroke-dashoffset: {:.3f}; }} "
"{:.3f}% {{ stroke-dashoffset: {:.3f}; }} " "{:.3f}% {{ stroke-dashoffset: {:.3f}; }} "
"{:.3f}% {{ stroke-dashoffset: 0; }} " "{:.3f}% {{ stroke-dashoffset: 0; }} "
"100.000% {{ stroke-dashoffset: 0; }} }}\n"sv; "100.000% {{ stroke-dashoffset: 0; }} }}\n"
constexpr auto AnimationVisibilityFormat = );
constexpr std::string_view AnimationVisibilityFormat(
" " " "
"@keyframes display-{} {{ " "@keyframes display-{} {{ "
"{:.3f}% {{ visibility: hidden; }} " "{:.3f}% {{ visibility: hidden; }} "
"{:.3f}% {{ stroke: {}; }} }}\n"sv; "{:.3f}% {{ stroke: {}; }} }}\n"
constexpr auto AnimationProgressionFormat = );
constexpr std::string_view AnimationProgressionFormat(
" " " "
"#{} {{ " "#{} {{ "
"stroke-dasharray: {:.3f} {:.3f}; " "stroke-dasharray: {:.3f} {:.3f}; "
"stroke-dashoffset: 0; " "stroke-dashoffset: 0; "
"animation: stroke-{} {:.3f}s {} infinite, " "animation: stroke-{} {:.3f}s {} infinite, "
"display-{} {:.3f}s step-start infinite; }}\n"sv; "display-{} {:.3f}s step-start infinite; }}\n"
constexpr auto BrushVisibilityFormat = );
constexpr std::string_view BrushVisibilityFormat(
" " " "
"@keyframes display-brush-{} {{ " "@keyframes display-brush-{} {{ "
"{:.3f}% {{ visibility: hidden; }} " "{:.3f}% {{ visibility: hidden; }} "
"{:.3f}% {{ visibility: visible; }} " "{:.3f}% {{ visibility: visible; }} "
"100.000% {{ visibility: hidden; }} }}\n"sv; "100.000% {{ visibility: hidden; }} }}\n"
constexpr auto BrushProgressionFormat = );
constexpr std::string_view BrushProgressionFormat(
" " " "
"#{}, #{} {{ " "#{}, #{} {{ "
"stroke-dasharray: 0 {:.3f}; " "stroke-dasharray: 0 {:.3f}; "
"animation: stroke-{} {:.3f}s {} infinite, " "animation: stroke-{} {:.3f}s {} infinite, "
"display-brush-{} {:.3f}s step-start infinite; }}\n"sv; "display-brush-{} {:.3f}s step-start infinite; }}\n"
);
constexpr auto StylesHeader = constexpr std::string_view StylesHeader(
"\n " "\n "
"/* Styles generated automatically by Kanimaji, please avoid editing manually. */\n"sv; "/* Styles generated automatically by Kanimaji, please avoid editing manually. */\n"
);
double AsSeconds(auto duration) { double AsSeconds(auto duration) {
return std::max(0.0, duration.count()); return std::max(0.0, duration.count());
@ -65,8 +78,7 @@ namespace Kanimaji
pugi::xml_node newGroup = svg.append_child("g"); pugi::xml_node newGroup = svg.append_child("g");
newGroup.append_attribute("id") = name; newGroup.append_attribute("id") = name;
newGroup.append_attribute("style") = std::format( newGroup.append_attribute("style") = std::format(
"fill:none;stroke:{};stroke-width:{};stroke-linecap:round;stroke-linejoin:round;", StaticStrokeStyleFormat, config.Colour.ToHex(), config.Width
config.Colour.ToHex(), config.Width
); );
return newGroup; return newGroup;
} }
@ -270,7 +282,8 @@ namespace Kanimaji
return str.str(); return str.str();
} }
void RemoveStrokeNumbers(const std::string& source, const std::string& destination) void RemoveStrokeNumbers(const std::string& source, const std::string& destination,
const RemovalSetttings& settings)
{ {
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(source.c_str(), pugi::parse_full); pugi::xml_parse_result result = doc.load_file(source.c_str(), pugi::parse_full);
@ -284,6 +297,13 @@ namespace Kanimaji
throw Error("Unexpected document format: Expected to find a SVG element"); throw Error("Unexpected document format: Expected to find a SVG element");
} }
pugi::xml_node pathsGroup = svg.find_child([](pugi::xml_node& node) {
return std::string_view(node.attribute("id").as_string()).contains("StrokePaths");
});
pathsGroup.attribute("style") = std::format(
StaticStrokeStyleFormat, settings.Style.Colour.ToHex(), settings.Style.Width
);
RemoveStrokeNumbers(svg); RemoveStrokeNumbers(svg);
if (!doc.save_file(destination.c_str())) { if (!doc.save_file(destination.c_str())) {
@ -291,7 +311,7 @@ namespace Kanimaji
} }
} }
std::string RemoveStrokeNumbers(const std::string& source) std::string RemoveStrokeNumbers(const std::string& source, const RemovalSetttings& settings)
{ {
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(source.c_str(), pugi::parse_full); pugi::xml_parse_result result = doc.load_string(source.c_str(), pugi::parse_full);
@ -305,6 +325,13 @@ namespace Kanimaji
throw Error("Unexpected document format: Expected to find a SVG element"); throw Error("Unexpected document format: Expected to find a SVG element");
} }
pugi::xml_node pathsGroup = svg.find_child([](pugi::xml_node& node) {
return std::string_view(node.attribute("id").as_string()).contains("StrokePaths");
});
pathsGroup.attribute("style") = std::format(
StaticStrokeStyleFormat, settings.Style.Colour.ToHex(), settings.Style.Width
);
RemoveStrokeNumbers(svg); RemoveStrokeNumbers(svg);
std::stringstream str; std::stringstream str;

View file

@ -48,4 +48,14 @@ namespace Kanimaji
.DelayBetweenStrokes = 50ms, .DelayBetweenStrokes = 50ms,
}; };
} }
RemovalSetttings RemovalSetttings::Default()
{
return RemovalSetttings {
.Style = StrokeStyle {
.Width = 3.0,
.Colour = RGB::FromHex("#000000"),
},
};
}
} }

View file

@ -21,6 +21,12 @@ void AnimateFile(const Path& source, const Path& destination,
std::string Animate(const std::string& source, std::string Animate(const std::string& source,
const AnimationSettings& settings = AnimationSettings::Default()); const AnimationSettings& settings = AnimationSettings::Default());
void RemoveStrokeNumbers(const std::string& source, const std::string& destination,
const RemovalSetttings& settings = RemovalSetttings::Default());
std::string RemoveStrokeNumbers(const std::string& source,
const RemovalSetttings& settings = RemovalSetttings::Default());
``` ```
The former function takes in two paths, where the first one specifies the file to be read, and The former function takes in two paths, where the first one specifies the file to be read, and
@ -113,7 +119,7 @@ Some caveats:
The default settings generate a table with no characters (and horrible styling), you will need to The default settings generate a table with no characters (and horrible styling), you will need to
specify custom settings like this for actual use: specify custom settings like this for actual use:
```cpp ```cpp
auto doc = GeneratePage({ auto doc = GeneratePage(std::vector<CharacterInfo>(), {
.FullDocument = Flag::Enable, .FullDocument = Flag::Enable,
.OverrideIndentLevel = Flag::Disable, .OverrideIndentLevel = Flag::Disable,
.IndentLevel = 0, .IndentLevel = 0,