Commit 737f6b90 authored by Volker Krause's avatar Volker Krause
Browse files

Add PDF417 barcode support

Rather than implementing this ourselves (1+k lines of code, several large
data tables), this uses ZXing as an (optional) dependency, making the
implementation straightforward.

ZXing as a dependency is also interesting as it contains support for
all other formats as well, potentially allowing us to use it instead of
the other external dependencies. ZXing is larger than those, but it's
also used in other KDE code already, unlike qrencode and libdmtx.
parent c93839ac
Pipeline #91563 passed with stage
in 34 seconds
......@@ -38,6 +38,8 @@ find_package(QRencode)
set_package_properties(QRencode PROPERTIES TYPE REQUIRED)
find_package(Dmtx)
set_package_properties(Dmtx PROPERTIES TYPE RECOMMENDED)
find_package(ZXing 1.2.0)
set_package_properties(ZXing PROPERTIES TYPE RECOMMENDED)
if (Qt5_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
......
......@@ -2,6 +2,9 @@ include(CMakePackageConfigHelpers)
if(TARGET Dmtx::Dmtx)
set(HAVE_DMTX 1)
endif()
if (TARGET ZXing::ZXing)
set(HAVE_ZXING 1)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-prison.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-prison.h)
add_library(KF5Prison)
......@@ -28,6 +31,10 @@ target_sources(KF5Prison PRIVATE
if(TARGET Dmtx::Dmtx)
target_sources(KF5Prison PRIVATE datamatrixbarcode.cpp)
endif()
if(TARGET ZXing::ZXing)
target_sources(KF5Prison PRIVATE pdf417barcode.cpp)
endif()
kde_source_files_enable_exceptions(pdf417barcode.cpp)
ecm_qt_declare_logging_category(KF5Prison
HEADER prison_debug.h
......@@ -58,6 +65,9 @@ PRIVATE
if(TARGET Dmtx::Dmtx)
target_link_libraries(KF5Prison PRIVATE Dmtx::Dmtx)
endif()
if(TARGET ZXing::ZXing)
target_link_libraries(KF5Prison PRIVATE ZXing::ZXing)
endif()
install(TARGETS KF5Prison EXPORT KF5PrisonTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
......
......@@ -8,5 +8,6 @@
#define PRISON_CONFIG_H
#cmakedefine HAVE_DMTX
#cmakedefine01 HAVE_ZXING
#endif
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: MIT
*/
#include "pdf417barcode.h"
#include <ZXing/BitMatrix.h>
#include <ZXing/MultiFormatWriter.h>
using namespace Prison;
Pdf417Barcode::Pdf417Barcode()
: AbstractBarcode(TwoDimensions)
{
}
QImage Pdf417Barcode::paintImage(const QSizeF &size)
{
Q_UNUSED(size);
std::wstring input;
if (!data().isEmpty()) {
input = data().toStdWString();
} else {
const auto b = byteArrayData();
input.reserve(b.size());
std::copy(b.begin(), b.end(), std::back_inserter(input));
}
try {
ZXing::MultiFormatWriter writer(ZXing::BarcodeFormat::PDF417);
// ISO/IEC 15438:2006(E) §5.8.3 Quiet Zone
writer.setMargin(2);
// aspect ratio 4 is hard-coded in ZXing
const auto matrix = writer.encode(input, 4, 1);
QImage image(matrix.width(), matrix.height(), QImage::Format_ARGB32);
for (int y = 0; y < matrix.height(); ++y) {
for (int x = 0; x < matrix.width(); ++x) {
image.setPixel(x, y, matrix.get(x, y) ? foregroundColor().rgb() : backgroundColor().rgb());
}
}
return image;
} catch (const std::invalid_argument &e) {
}; // input too large
return {};
}
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: MIT
*/
#ifndef PRISON_PDF417BARCODE_H
#define PRISON_PDF417BARCODE_H
#include "abstractbarcode.h"
namespace Prison
{
/** PDF417 barcode.
* @see https://en.wikipedia.org/wiki/PDF417
* @see ISO/IEC 15438
*/
class Pdf417Barcode : public AbstractBarcode
{
public:
explicit Pdf417Barcode();
protected:
QImage paintImage(const QSizeF &size) override;
};
}
#endif // PRISON_PDF417BARCODE_H
......@@ -10,6 +10,7 @@
#include "code39barcode.h"
#include "code93barcode.h"
#include "datamatrixbarcode.h"
#include "pdf417barcode.h"
#include "qrcodebarcode.h"
#include <config-prison.h>
......@@ -34,6 +35,10 @@ Prison::AbstractBarcode *Prison::createBarcode(BarcodeType type)
return new Code93Barcode;
case Prison::Code128:
return new Code128Barcode;
#if HAVE_ZXING
case Prison::PDF417:
return new Pdf417Barcode;
#endif
}
return nullptr;
}
......@@ -35,7 +35,8 @@ enum BarcodeType {
Code93,
/** Code 128 barcode */
Code128,
/** PDF417 barcode */
PDF417,
};
/**
* Factory method to create a barcode of a given type.
......
......@@ -46,6 +46,7 @@ public:
Code39 = Prison::Code39,
Code93 = Prison::Code93,
Code128 = Prison::Code128,
PDF417 = Prison::PDF417,
};
Q_ENUM(BarcodeType)
explicit BarcodeQuickItem(QQuickItem *parent = nullptr);
......
......@@ -24,7 +24,7 @@ Rectangle {
}
ComboBox {
id: typeCombobox
model: [ "Null", "QRCode", "DataMatrix", "Aztec", "Code39", "Code93", "Code128" ]
model: [ "Null", "QRCode", "DataMatrix", "Aztec", "Code39", "Code93", "Code128", "PDF417" ]
currentIndex: 3
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment