diff options
Diffstat (limited to 'cui/source/dialogs')
-rw-r--r-- | cui/source/dialogs/QrCodeGenDialog.cxx | 98 |
1 files changed, 68 insertions, 30 deletions
diff --git a/cui/source/dialogs/QrCodeGenDialog.cxx b/cui/source/dialogs/QrCodeGenDialog.cxx index 3de87abae22b..3a82a115551d 100644 --- a/cui/source/dialogs/QrCodeGenDialog.cxx +++ b/cui/source/dialogs/QrCodeGenDialog.cxx @@ -17,14 +17,26 @@ #include <utility> #include <vcl/svapp.hxx> -#if ENABLE_QRCODEGEN -#if defined(SYSTEM_QRCODEGEN) -#include <qrcodegen/QrCode.hpp> -#else -#include <QrCode.hpp> +#if ENABLE_ZXING +#include <rtl/ustrbuf.hxx> + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #endif + +#include <BarcodeFormat.h> +#include <BitArray.h> +#include <BitMatrix.h> +#include <MultiFormatWriter.h> +#include <TextUtfEncoding.h> + +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif +#endif // ENABLE_ZXING + #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/drawing/XShape.hpp> @@ -56,9 +68,37 @@ using namespace css::sheet; using namespace css::text; using namespace css::drawing; using namespace css::graphic; -#if ENABLE_QRCODEGEN -using namespace qrcodegen; +namespace +{ +#if ENABLE_ZXING +// Implementation adapted from the answer: https://stackoverflow.com/questions/10789059/create-qr-code-in-vector-image/60638350#60638350 +OUString ConvertToSVGFormat(const ZXing::BitMatrix& bitmatrix) +{ + OUStringBuffer sb; + const int width = bitmatrix.width(); + const int height = bitmatrix.height(); + ZXing::BitArray row(width); + sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 " + + OUString::number(width) + " " + OUString::number(height) + + "\" stroke=\"none\">\n" + "<path d=\""); + for (int i = 0; i < height; ++i) + { + bitmatrix.getRow(i, row); + for (int j = 0; j < width; ++j) + { + if (row.get(j)) + { + sb.append("M" + OUString::number(j) + "," + OUString::number(i) + "h1v1h-1z"); + } + } + } + sb.append("\"/>\n</svg>"); + return sb.toString(); +} #endif +} QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference<XModel> xModel, bool bEditExisting) @@ -70,7 +110,7 @@ QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference<XModel> xModel m_xBuilder->weld_radio_button("button_quartile"), m_xBuilder->weld_radio_button("button_high") } , m_xSpinBorder(m_xBuilder->weld_spin_button("edit_border")) -#if ENABLE_QRCODEGEN +#if ENABLE_ZXING , mpParent(pParent) #endif { @@ -108,7 +148,7 @@ QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference<XModel> xModel short QrCodeGenDialog::run() { -#if ENABLE_QRCODEGEN +#if ENABLE_ZXING short nRet; while (true) { @@ -120,7 +160,7 @@ short QrCodeGenDialog::run() Apply(); break; } - catch (const qrcodegen::data_too_long&) + catch (const std::exception&) { std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog( mpParent, VclMessageType::Warning, VclButtonsType::Ok, @@ -139,7 +179,7 @@ short QrCodeGenDialog::run() void QrCodeGenDialog::Apply() { -#if ENABLE_QRCODEGEN +#if ENABLE_ZXING css::drawing::QRCode aQRCode; aQRCode.Payload = m_xEdittext->get_text(); @@ -264,43 +304,41 @@ void QrCodeGenDialog::Apply() OUString QrCodeGenDialog::GenerateQRCode(OUString aQRText, tools::Long aQRECC, int aQRBorder) { -#if ENABLE_QRCODEGEN - //Select ECC:: value from aQrECC - qrcodegen::QrCode::Ecc bqrEcc = qrcodegen::QrCode::Ecc::LOW; +#if ENABLE_ZXING + // Associated ZXing error correction levels (0-8) to our constants arbitrarily. + int bqrEcc = 1; switch (aQRECC) { - case 1: + case css::drawing::QRCodeErrorCorrection::LOW: { - bqrEcc = qrcodegen::QrCode::Ecc::LOW; + bqrEcc = 1; break; } - case 2: + case css::drawing::QRCodeErrorCorrection::MEDIUM: { - bqrEcc = qrcodegen::QrCode::Ecc::MEDIUM; + bqrEcc = 3; break; } - case 3: + case css::drawing::QRCodeErrorCorrection::QUARTILE: { - bqrEcc = qrcodegen::QrCode::Ecc::QUARTILE; + bqrEcc = 5; break; } - case 4: + case css::drawing::QRCodeErrorCorrection::HIGH: { - bqrEcc = qrcodegen::QrCode::Ecc::HIGH; + bqrEcc = 7; break; } } - //OuString to char* qrtext OString o = OUStringToOString(aQRText, RTL_TEXTENCODING_UTF8); - const char* qrtext = o.pData->buffer; - - // From QR Code library - qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText(qrtext, bqrEcc); - std::string svg = qr0.toSvgString(aQRBorder); - //cstring to OUString - return OUString::createFromAscii(svg.c_str()); + std::string QRText(o.getStr(), o.getLength()); + ZXing::BarcodeFormat format = ZXing::BarcodeFormatFromString("QR_CODE"); + auto writer = ZXing::MultiFormatWriter(format).setMargin(aQRBorder).setEccLevel(bqrEcc); + writer.setEncoding(ZXing::CharacterSet::UTF8); + ZXing::BitMatrix bitmatrix = writer.encode(ZXing::TextUtfEncoding::FromUtf8(QRText), 0, 0); + return ConvertToSVGFormat(bitmatrix); #else (void)aQRText; (void)aQRECC; |