File indexing completed on 2024-05-12 04:01:31
0001 /* 0002 SPDX-FileCopyrightText: 2010-2016 Sune Vuorela <sune@vuorela.dk> 0003 SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org> 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #include <config-prison.h> 0008 0009 #include "barcode.h" 0010 0011 #include "abstractbarcode_p.h" 0012 #include "aztecbarcode_p.h" 0013 #include "code128barcode_p.h" 0014 #include "code39barcode_p.h" 0015 #include "code93barcode_p.h" 0016 #include "datamatrixbarcode_p.h" 0017 #include "pdf417barcode_p.h" 0018 #include "qrcodebarcode_p.h" 0019 #if HAVE_ZXING 0020 #include "zxingonedbarcode_p.h" 0021 #endif 0022 0023 #include <QColor> 0024 #include <QPainter> 0025 #include <QVariant> 0026 0027 using namespace Prison; 0028 0029 std::optional<Barcode> Barcode::create(Prison::BarcodeType format) 0030 { 0031 std::unique_ptr<AbstractBarcodePrivate> d; 0032 switch (format) { 0033 case Prison::QRCode: 0034 d = std::make_unique<QRCodeBarcode>(); 0035 break; 0036 case Prison::DataMatrix: 0037 #if HAVE_DMTX 0038 d = std::make_unique<DataMatrixBarcode>(); 0039 #endif 0040 break; 0041 case Prison::Aztec: 0042 d = std::make_unique<AztecBarcode>(); 0043 break; 0044 case Prison::Code39: 0045 d = std::make_unique<Code39Barcode>(); 0046 break; 0047 case Prison::Code93: 0048 d = std::make_unique<Code93Barcode>(); 0049 break; 0050 case Prison::Code128: 0051 d = std::make_unique<Code128Barcode>(); 0052 break; 0053 case Prison::PDF417: 0054 #if HAVE_ZXING 0055 d = std::make_unique<Pdf417Barcode>(); 0056 #endif 0057 break; 0058 case Prison::EAN13: 0059 #if HAVE_ZXING 0060 d = std::make_unique<ZXingOneDBarcode<ZXing::BarcodeFormat::EAN13>>(); 0061 #endif 0062 break; 0063 } 0064 0065 if (d) { 0066 d->m_format = format; 0067 return Barcode(std::move(d)); 0068 } 0069 return std::nullopt; 0070 } 0071 0072 Barcode::Barcode(std::unique_ptr<AbstractBarcodePrivate> &&dd) 0073 : d(std::move(dd)) 0074 { 0075 } 0076 0077 Barcode::Barcode(Barcode &&) = default; 0078 Barcode::~Barcode() = default; 0079 Barcode &Barcode::operator=(Barcode &&) = default; 0080 0081 Prison::BarcodeType Barcode::format() const 0082 { 0083 return d->m_format; 0084 } 0085 0086 QString Barcode::data() const 0087 { 0088 return d->m_data.userType() == QMetaType::QString ? d->m_data.toString() : QString(); 0089 } 0090 0091 QByteArray Barcode::byteArrayData() const 0092 { 0093 return d->m_data.userType() == QMetaType::QByteArray ? d->m_data.toByteArray() : QByteArray(); 0094 } 0095 0096 QImage Barcode::toImage(const QSizeF &size) 0097 { 0098 d->recompute(); 0099 if (d->m_cache.isNull() || d->sizeTooSmall(size)) { 0100 return QImage(); 0101 } 0102 0103 // scale to the requested size, using only full integer factors to keep the code readable 0104 int scaleX = std::max<int>(1, size.width() / d->m_cache.width()); 0105 int scaleY = std::max<int>(1, size.height() / d->m_cache.height()); 0106 if (dimensions() == TwoDimensions) { 0107 scaleX = scaleY = std::min(scaleX, scaleY); 0108 } 0109 0110 QImage out(d->m_cache.width() * scaleX, d->m_cache.height() * scaleY, d->m_cache.format()); 0111 QPainter p(&out); 0112 p.setRenderHint(QPainter::SmoothPixmapTransform, false); 0113 p.drawImage(out.rect(), d->m_cache, d->m_cache.rect()); 0114 return out; 0115 } 0116 0117 void Barcode::setData(const QString &data) 0118 { 0119 if (d) { 0120 d->m_data = data; 0121 d->m_cache = QImage(); 0122 } 0123 } 0124 0125 void Barcode::setData(const QByteArray &data) 0126 { 0127 d->m_data = data; 0128 d->m_cache = QImage(); 0129 } 0130 0131 QSizeF Barcode::minimumSize() const 0132 { 0133 d->recompute(); 0134 return d->m_cache.size(); 0135 } 0136 0137 QSizeF Barcode::preferredSize(qreal devicePixelRatio) const 0138 { 0139 d->recompute(); 0140 return d->preferredSize(devicePixelRatio); 0141 } 0142 0143 QColor Barcode::backgroundColor() const 0144 { 0145 return d->m_background; 0146 } 0147 0148 QColor Barcode::foregroundColor() const 0149 { 0150 return d->m_foreground; 0151 } 0152 0153 void Barcode::setBackgroundColor(const QColor &backgroundcolor) 0154 { 0155 if (backgroundcolor != backgroundColor()) { 0156 d->m_background = backgroundcolor; 0157 d->m_cache = QImage(); 0158 } 0159 } 0160 0161 void Barcode::setForegroundColor(const QColor &foregroundcolor) 0162 { 0163 if (foregroundcolor != foregroundColor()) { 0164 d->m_foreground = foregroundcolor; 0165 d->m_cache = QImage(); 0166 } 0167 } 0168 0169 Barcode::Dimensions Barcode::dimensions() const 0170 { 0171 return d->m_dimension; 0172 }