#include #include #include #include "QR.hpp" #include "renderers/ConsoleRenderer.hpp" #include "renderers/PNGRenderer.hpp" #include "renderers/SVGRenderer.hpp" #include "renderers/JPGRenderer.hpp" #include "renderers/BMPRenderer.hpp" namespace massivedynamic { QR::QR(const std::string& data, std::string outputFile, size_t size, qrcodegen::QrCode::Ecc type) : outputFile(std::move(outputFile)) { qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.c_str(), type); static_assert(FormatLength == 5, "exhaustive formats: did you miss to add something here?"); this->renderers.insert({Format::CONSOLE, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::PNG, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::SVG, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::JPG, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::BMP, std::make_unique(this->pixels, qr.getSize(), size)}); // this is inherently stupid, but "qrcodegen::QrCode" does not give access to the // `segments` vector member and the class itself is marked final. for (int y = 0; y < qr.getSize(); y++) { for (int x = 0; x < qr.getSize(); x++) this->pixels.push_back(qr.getModule(x, y)); } } void QR::render(Format format) { assert(this->renderers.find(format) != this->renderers.end() && "ERROR: a non-valid renderer has been selected"); this->renderers.at(format)->render(this->outputFile); } }