2025-05-24 22:15:59 +00:00
|
|
|
# kanjivg-tools
|
|
|
|
|
2025-06-08 00:53:02 +02:00
|
|
|
WIP
|
|
|
|
|
|
|
|
## Kanimaji & KanimajiTool
|
|
|
|
|
|
|
|
This is a library & program pair that implements CSS animations for SVG files in the KanjiVG
|
|
|
|
dataset, roughly based on the original [kanimaji.py](https://github.com/maurimo/kanimaji) script
|
|
|
|
([mirror](https://code.3011.io/Mirrors/kanimaji)).
|
|
|
|
|
|
|
|
The program is just a dead simple executable driver for the library.
|
|
|
|
This project is currently still work in progress, but it is feature complete, and no major changes
|
2025-06-08 00:55:18 +02:00
|
|
|
are expected in the public API (apart from error handling).
|
2025-06-08 00:53:02 +02:00
|
|
|
|
|
|
|
### Library usage
|
|
|
|
|
|
|
|
In the simplest usecase, the library consists of just two public functions:
|
|
|
|
```cpp
|
|
|
|
void AnimateFile(const Path& source, const Path& destination,
|
|
|
|
const AnimationSettings& settings = AnimationSettings::Default());
|
|
|
|
|
|
|
|
std::string Animate(const std::string& source,
|
|
|
|
const AnimationSettings& settings = AnimationSettings::Default());
|
|
|
|
```
|
|
|
|
|
|
|
|
The former function takes in two paths, where the first one specifies the file to be read, and
|
|
|
|
the second one specified a path where the resulting animated SVG image shoule be stored.
|
|
|
|
|
|
|
|
The latter takes in a string that already contains the SVG kanji data, and returns a string
|
|
|
|
containing the animated SVG file. This function performs all operations in memory.
|
|
|
|
|
|
|
|
The default settings (currently) approximate the default settings in the kanimaji.py script.
|
|
|
|
In case these are not desired, it is possible to configure the animation to an extent, e.g. like
|
|
|
|
this:
|
|
|
|
```cpp
|
|
|
|
AnimateFile("084b8.svg", "084b8-out.svg", AnimationSettings {
|
|
|
|
.StrokeProgression = Progression::EaseInOut,
|
|
|
|
.UnfilledStroke = StrokeStyle {
|
|
|
|
.Width = 2.0,
|
|
|
|
.Colour = RGB::FromHex("#EEEEEE"),
|
|
|
|
},
|
|
|
|
.FilledStroke = StrokeStyle {
|
|
|
|
.Width = 3.0,
|
|
|
|
.Colour = RGB::FromHex("#000000"),
|
|
|
|
},
|
|
|
|
.StrokeFillingColour = RGB::FromHex("#FF0000"),
|
|
|
|
.EnableBrush = Flag::Enable,
|
|
|
|
.Brush = StrokeStyle {
|
|
|
|
.Width = 5.5,
|
|
|
|
.Colour = RGB::FromHex("#FF0000"),
|
|
|
|
},
|
|
|
|
.BrushBorder = StrokeStyle {
|
|
|
|
.Width = 7.0,
|
|
|
|
.Colour = RGB::FromHex("#666666"),
|
|
|
|
},
|
|
|
|
.LengthToTimeScaling = [] (double length) -> double {
|
|
|
|
return std::pow(length, 1.0 / 3.0) / 6.0;
|
|
|
|
},
|
|
|
|
.WaitBeforeRepeating = 1s,
|
|
|
|
.DelayBetweenStrokes = 50ms,
|
|
|
|
});
|
|
|
|
```
|
2025-06-14 20:33:06 +02:00
|
|
|
|
|
|
|
## Megane
|
|
|
|
|
|
|
|
A tiny library that loads the `kvg-index.json` into a dictionary to translate the UTF-8
|
|
|
|
representation of kanji characters into the ID that kanjivg uses to refer to the characters.
|
|
|
|
|
|
|
|
Example usage:
|
|
|
|
```cpp
|
|
|
|
auto lookup = Megane::Megane("/path/to/kvg-index.json");
|
|
|
|
auto id = lookup.GetCode("日"); // id should contain "065e5.svg"
|
|
|
|
```
|
|
|
|
|
|
|
|
## Tablegen
|
|
|
|
|
|
|
|
This library generates a table of kanji images from a specified list with various configurable
|
|
|
|
values. It's made up of the following interface:
|
|
|
|
|
|
|
|
```cpp
|
2025-06-16 05:33:20 +02:00
|
|
|
std::string GeneratePage(const std::vector<CharacterInfo>& characters,
|
|
|
|
const Settings& settings = Settings::Default());
|
2025-06-14 20:33:06 +02:00
|
|
|
|
2025-06-16 05:33:20 +02:00
|
|
|
void GeneratePage(const std::string& path, const std::vector<CharacterInfo>& characters,
|
|
|
|
const Settings& settings = Settings::Default());
|
2025-06-14 20:33:06 +02:00
|
|
|
|
|
|
|
#ifdef TABLEGEN_EXPOSE_XML
|
2025-06-16 05:33:20 +02:00
|
|
|
void GenerateAsChild(pugi::xml_node& node, const std::vector<CharacterInfo>& characters,
|
|
|
|
const Settings& settings = Settings::Default());
|
2025-06-14 20:33:06 +02:00
|
|
|
|
2025-06-16 05:33:20 +02:00
|
|
|
pugi::xml_document GenerateDocument(const std::vector<CharacterInfo>& characters,
|
|
|
|
const Settings& settings = Settings::Default());
|
2025-06-14 20:33:06 +02:00
|
|
|
#endif
|
|
|
|
```
|
|
|
|
|
|
|
|
The first function returns a serialized HTML document in a string
|
|
|
|
(can return just the table by changing the `FullDocument` value in the settings).
|
|
|
|
The second function dumps the same document inside a file at the specified path.
|
|
|
|
The final two functions are hidden behing the `TABLEGEN_EXPOSE_XML` preprocessor flag, because they
|
|
|
|
expose the library that Tablegen uses internally to generate the document. They let the user
|
|
|
|
modify the XML tree before it gets serialized into the final document. The first of these functions
|
|
|
|
takes in a reference to the node that will act as the parent of the generated table.
|
|
|
|
The second function returns a whole XML document.
|
|
|
|
|
|
|
|
Some caveats:
|
|
|
|
- `GenerateDocument` returns a `pugi::xml_document`, which cannot be assigned as a child
|
|
|
|
of anothe node. You don't want to use this function if you plan to generate a full document
|
|
|
|
with the table as a child (the `FullDocument` option isn't applicable in all cases either).
|
|
|
|
- The default serialisation options do not generate a valid document, some specific options
|
|
|
|
need to be set for the document to be valid (currently `pugi::format_no_escapes`,
|
|
|
|
and `pugi::format_no_declaration`, but this is an implementation detail of the pugixml library).
|
|
|
|
|
|
|
|
The default settings generate a table with no characters (and horrible styling), you will need to
|
|
|
|
specify custom settings like this for actual use:
|
|
|
|
```cpp
|
|
|
|
auto doc = GeneratePage({
|
|
|
|
.FullDocument = Flag::Enable,
|
|
|
|
.OverrideIndentLevel = Flag::Disable,
|
|
|
|
.IndentLevel = 0,
|
|
|
|
.TableWidth = 90,
|
|
|
|
.TableMargin = 5,
|
|
|
|
.TableItemWidth = 30,
|
|
|
|
.TableItemPadding = 2,
|
|
|
|
.TableItemColour = RGB::FromHex("#666666"),
|
|
|
|
.LabelFontSize = 1.75,
|
|
|
|
.LabelFontUnits = FontSizeUnits::Em,
|
|
|
|
.ButtonColour = RGB::FromHex("#FF6347"),
|
|
|
|
.ButtonHoverColour = RGB::FromHex("#FFA500"),
|
|
|
|
.ButtonAnimationLength = 0.5,
|
|
|
|
.CharactersPerRow = 3,
|
|
|
|
.ImageFormat = "http://the.url/where/you/have/images/{}.svg",
|
|
|
|
.AnimationFormat = "http://the.url/where/you/have/animations/{}.svg",
|
|
|
|
});
|
|
|
|
```
|