From cdeb5046be7f6259bd60f0951c51559edcab91c5 Mon Sep 17 00:00:00 2001 From: homeboy445 Date: Mon, 15 Mar 2021 21:11:08 +0530 Subject: tdf#139778 Switch to ZXing for generating QR code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ief944266d5183bb862afe99ec6b0bdaca4956938 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112534 Tested-by: Jenkins Tested-by: René Engelhard Reviewed-by: Mike Kaganski --- cui/Library_cui.mk | 2 +- cui/source/dialogs/QrCodeGenDialog.cxx | 98 +++++++++++++++++++++++----------- cui/source/inc/QrCodeGenDialog.hxx | 4 +- 3 files changed, 71 insertions(+), 33 deletions(-) (limited to 'cui') 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 #include -#if ENABLE_QRCODEGEN -#if defined(SYSTEM_QRCODEGEN) -#include -#else -#include +#if ENABLE_ZXING +#include + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #endif + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#pragma GCC diagnostic pop #endif +#endif // ENABLE_ZXING + #include #include #include @@ -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("\n" + "\n" + "\n"); + return sb.toString(); +} #endif +} QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference xModel, bool bEditExisting) @@ -70,7 +110,7 @@ QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference 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 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 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 +#include #include @@ -33,7 +33,7 @@ private: std::unique_ptr m_xEdittext; std::unique_ptr m_xECC[4]; std::unique_ptr m_xSpinBorder; -#if ENABLE_QRCODEGEN +#if ENABLE_ZXING weld::Widget* mpParent; #endif -- cgit v1.2.3