Various utilities for working with the kanjivg dataset.
Find a file
2025-06-16 23:35:24 +02:00
CMake Use the static library alias provided by piguxml config 2025-06-15 22:19:56 +02:00
Libraries [Tablegen] Force preloading 2025-06-16 23:35:24 +02:00
Tools [Common] Split RGB into a new Common library 2025-06-14 19:52:18 +02:00
.gitignore Prepare the initial stubs 2025-05-25 00:42:58 +02:00
CMakeLists.txt Prepare the initial stubs 2025-05-25 00:42:58 +02:00
README.md Update the README with current API 2025-06-16 20:33:47 +02:00

kanjivg-tools

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 script (mirror).

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 are expected in the public API (apart from error handling).

Library usage

In the simplest usecase, the library consists of just two public functions:

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());

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 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:

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,
});

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:

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:

std::string GeneratePage(const std::vector<CharacterInfo>& characters,
                         const Settings& settings = Settings::Default());

void GeneratePage(const std::string& path, const std::vector<CharacterInfo>& characters,
                  const Settings& settings = Settings::Default());

#ifdef TABLEGEN_EXPOSE_XML
void GenerateAsChild(pugi::xml_node& node, const std::vector<CharacterInfo>& characters,
                     const Settings& settings = Settings::Default());

pugi::xml_document GenerateDocument(const std::vector<CharacterInfo>& characters,
                                    const Settings& settings = Settings::Default());
#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:

auto doc = GeneratePage(std::vector<CharacterInfo>(), {
    .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",
});