In C++ version: moved QrCode.toSvgString() out of the library and into the runnable demo program, slightly adapted some code, updated documentation comments.

pull/118/head
Project Nayuki 3 years ago
parent 5bc7bce3c3
commit cd037d9149

@ -18,7 +18,7 @@ Core features:
* Available in 6 programming languages, all with nearly equal functionality: Java, TypeScript/JavaScript, Python, Rust, C++, C * Available in 6 programming languages, all with nearly equal functionality: Java, TypeScript/JavaScript, Python, Rust, C++, C
* Significantly shorter code but more documentation comments compared to competing libraries * Significantly shorter code but more documentation comments compared to competing libraries
* Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard * Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
* Output formats: Raw modules/pixels of the QR symbol (all languages), SVG XML string (all languages except C) * Output format: Raw modules/pixels of the QR symbol
* Detects finder-like penalty patterns more accurately than other implementations * Detects finder-like penalty patterns more accurately than other implementations
* Encodes numeric and special-alphanumeric text in less space than general text * Encodes numeric and special-alphanumeric text in less space than general text
* Open source code under the permissive MIT License * Open source code under the permissive MIT License
@ -105,7 +105,7 @@ C++ language:
// Simple operation // Simple operation
QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM); QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
std::string svg = qr0.toSvgString(4); std::string svg = toSvgString(qr0, 4); // See QrCodeGeneratorDemo
// Manual operation // Manual operation
std::vector<QrSegment> segs = std::vector<QrSegment> segs =

@ -385,34 +385,6 @@ bool QrCode::getModule(int x, int y) const {
} }
std::string QrCode::toSvgString(int border) const {
if (border < 0)
throw std::domain_error("Border must be non-negative");
if (border > INT_MAX / 2 || border * 2 > INT_MAX - size)
throw std::overflow_error("Border too large");
std::ostringstream sb;
sb << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
sb << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
sb << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ";
sb << (size + border * 2) << " " << (size + border * 2) << "\" stroke=\"none\">\n";
sb << "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
sb << "\t<path d=\"";
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
if (getModule(x, y)) {
if (x != 0 || y != 0)
sb << " ";
sb << "M" << (x + border) << "," << (y + border) << "h1v1h-1z";
}
}
}
sb << "\" fill=\"#000000\"/>\n";
sb << "</svg>\n";
return sb.str();
}
void QrCode::drawFunctionPatterns() { void QrCode::drawFunctionPatterns() {
// Draw horizontal and vertical timing patterns // Draw horizontal and vertical timing patterns
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {

@ -369,13 +369,6 @@ class QrCode final {
public: bool getModule(int x, int y) const; public: bool getModule(int x, int y) const;
/*
* Returns a string of SVG code for an image depicting this QR Code, with the given number
* of border modules. The string always uses Unix newlines (\n), regardless of the platform.
*/
public: std::string toSvgString(int border) const;
/*---- Private helper methods for constructor: Drawing function modules ----*/ /*---- Private helper methods for constructor: Drawing function modules ----*/

@ -24,10 +24,12 @@
* Software. * Software.
*/ */
#include <climits>
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "QrCode.hpp" #include "QrCode.hpp"
@ -42,6 +44,7 @@ static void doBasicDemo();
static void doVarietyDemo(); static void doVarietyDemo();
static void doSegmentDemo(); static void doSegmentDemo();
static void doMaskDemo(); static void doMaskDemo();
static std::string toSvgString(const QrCode &qr, int border);
static void printQr(const QrCode &qr); static void printQr(const QrCode &qr);
@ -66,7 +69,7 @@ static void doBasicDemo() {
// Make and print the QR Code symbol // Make and print the QR Code symbol
const QrCode qr = QrCode::encodeText(text, errCorLvl); const QrCode qr = QrCode::encodeText(text, errCorLvl);
printQr(qr); printQr(qr);
std::cout << qr.toSvgString(4) << std::endl; std::cout << toSvgString(qr, 4) << std::endl;
} }
@ -186,6 +189,36 @@ static void doMaskDemo() {
/*---- Utilities ----*/ /*---- Utilities ----*/
// Returns a string of SVG code for an image depicting the given QR Code, with the given number
// of border modules. The string always uses Unix newlines (\n), regardless of the platform.
static std::string toSvgString(const QrCode &qr, int border) {
if (border < 0)
throw std::domain_error("Border must be non-negative");
if (border > INT_MAX / 2 || border * 2 > INT_MAX - qr.getSize())
throw std::overflow_error("Border too large");
std::ostringstream sb;
sb << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
sb << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
sb << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ";
sb << (qr.getSize() + border * 2) << " " << (qr.getSize() + border * 2) << "\" stroke=\"none\">\n";
sb << "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
sb << "\t<path d=\"";
for (int y = 0; y < qr.getSize(); y++) {
for (int x = 0; x < qr.getSize(); x++) {
if (qr.getModule(x, y)) {
if (x != 0 || y != 0)
sb << " ";
sb << "M" << (x + border) << "," << (y + border) << "h1v1h-1z";
}
}
}
sb << "\" fill=\"#000000\"/>\n";
sb << "</svg>\n";
return sb.str();
}
// Prints the given QrCode object to the console. // Prints the given QrCode object to the console.
static void printQr(const QrCode &qr) { static void printQr(const QrCode &qr) {
int border = 4; int border = 4;

Loading…
Cancel
Save