[Libreoffice-commits] core.git: cui/Library_cui.mk cui/source

homeboy445 (via logerrit) logerrit at kemper.freedesktop.org
Sat Mar 20 20:36:35 UTC 2021


 cui/Library_cui.mk                     |    2 
 cui/source/dialogs/QrCodeGenDialog.cxx |   98 ++++++++++++++++++++++-----------
 cui/source/inc/QrCodeGenDialog.hxx     |    4 -
 3 files changed, 71 insertions(+), 33 deletions(-)

New commits:
commit cdeb5046be7f6259bd60f0951c51559edcab91c5
Author:     homeboy445 <akshitsan13 at gmail.com>
AuthorDate: Mon Mar 15 21:11:08 2021 +0530
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Sat Mar 20 21:35:48 2021 +0100

    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 at debian.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

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
 


More information about the Libreoffice-commits mailing list