summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhomeboy445 <akshitsan13@gmail.com>2021-03-15 21:11:08 +0530
committerMike Kaganski <mike.kaganski@collabora.com>2021-03-20 21:35:48 +0100
commitcdeb5046be7f6259bd60f0951c51559edcab91c5 (patch)
tree90a10be2812514881888f8c15b1a10301bdfe70b
parentf72cd65eef4f9c32201ac785c424d5b18651464f (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>
-rw-r--r--cui/Library_cui.mk2
-rw-r--r--cui/source/dialogs/QrCodeGenDialog.cxx98
-rw-r--r--cui/source/inc/QrCodeGenDialog.hxx4
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