diff options
author | homeboy445 <akshitsan13@gmail.com> | 2021-03-15 21:11:08 +0530 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-03-20 21:35:48 +0100 |
commit | cdeb5046be7f6259bd60f0951c51559edcab91c5 (patch) | |
tree | 90a10be2812514881888f8c15b1a10301bdfe70b /cui | |
parent | f72cd65eef4f9c32201ac785c424d5b18651464f (diff) |
tdf#139778 Switch to ZXing for generating QR code
Change-Id: Ief944266d5183bb862afe99ec6b0bdaca4956938
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112534
Tested-by: Jenkins
Tested-by: René Engelhard <rene@debian.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'cui')
-rw-r--r-- | cui/Library_cui.mk | 2 | ||||
-rw-r--r-- | cui/source/dialogs/QrCodeGenDialog.cxx | 98 | ||||
-rw-r--r-- | cui/source/inc/QrCodeGenDialog.hxx | 4 |
3 files changed, 71 insertions, 33 deletions
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index ff221a9cc55a..f2df06cc5f2c 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -73,7 +73,7 @@ $(eval $(call gb_Library_use_externals,cui,\ libxml2 \ orcus-parser \ orcus \ - qrcodegen \ + zxing \ )) ifeq ($(DISABLE_GUI),) $(eval $(call gb_Library_use_externals,cui,\ 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; diff --git a/cui/source/inc/QrCodeGenDialog.hxx b/cui/source/inc/QrCodeGenDialog.hxx index 7c39fe07ced6..c3f7a9a82e6f 100644 --- a/cui/source/inc/QrCodeGenDialog.hxx +++ b/cui/source/inc/QrCodeGenDialog.hxx @@ -8,7 +8,7 @@ */ #pragma once -#include <config_qrcodegen.h> +#include <config_zxing.h> #include <vcl/weld.hxx> @@ -33,7 +33,7 @@ private: std::unique_ptr<weld::Entry> m_xEdittext; std::unique_ptr<weld::RadioButton> m_xECC[4]; std::unique_ptr<weld::SpinButton> m_xSpinBorder; -#if ENABLE_QRCODEGEN +#if ENABLE_ZXING weld::Widget* mpParent; #endif |