keepassxc

Форк
0
/
QrCode.cpp 
127 строк · 3.7 Кб
1
/*
2
 *  Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
3
 *
4
 *  This program is free software: you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation, either version 2 or (at your option)
7
 *  version 3 of the License.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17

18
#include "QrCode.h"
19
#include "QrCode_p.h"
20

21
#include <QByteArray>
22
#include <QPainter>
23
#include <QString>
24
#include <QSvgGenerator>
25

26
QrCodePrivate::QrCodePrivate()
27
    : m_qrcode(nullptr)
28
{
29
}
30

31
QrCodePrivate::~QrCodePrivate()
32
{
33
    if (m_qrcode) {
34
        QRcode_free(m_qrcode);
35
    }
36
}
37

38
QrCode::QrCode()
39
    : d_ptr(new QrCodePrivate())
40
{
41
}
42

43
QrCode::QrCode(const QString& data, const Version version, const ErrorCorrectionLevel ecl, const bool caseSensitive)
44
    : d_ptr(new QrCodePrivate())
45
{
46
    init(data, version, ecl, caseSensitive);
47
}
48

49
QrCode::QrCode(const QByteArray& data, const Version version, const ErrorCorrectionLevel ecl)
50
    : d_ptr(new QrCodePrivate())
51
{
52
    init(data, version, ecl);
53
}
54

55
QrCode::~QrCode() = default;
56

57
void QrCode::init(const QString& data, const Version version, const ErrorCorrectionLevel ecl, bool caseSensitive)
58
{
59
    if (data.isEmpty()) {
60
        return;
61
    }
62

63
    d_ptr->m_qrcode = QRcode_encodeString(data.toLocal8Bit().data(),
64
                                          static_cast<int>(version),
65
                                          static_cast<QRecLevel>(ecl),
66
                                          QR_MODE_8,
67
                                          caseSensitive ? 1 : 0);
68
}
69

70
void QrCode::init(const QByteArray& data, const Version version, const ErrorCorrectionLevel ecl)
71
{
72
    if (data.isEmpty()) {
73
        return;
74
    }
75

76
    d_ptr->m_qrcode = QRcode_encodeData(data.size(),
77
                                        reinterpret_cast<const unsigned char*>(data.data()),
78
                                        static_cast<int>(version),
79
                                        static_cast<QRecLevel>(ecl));
80
}
81

82
bool QrCode::isValid() const
83
{
84
    return d_ptr->m_qrcode != nullptr;
85
}
86

87
void QrCode::writeSvg(QIODevice* outputDevice, const int dpi, const int margin) const
88
{
89
    if (margin < 0 || d_ptr->m_qrcode == nullptr || outputDevice == nullptr) {
90
        return;
91
    }
92

93
    const int width = d_ptr->m_qrcode->width + margin * 2;
94

95
    QSvgGenerator generator;
96
    generator.setSize(QSize(width, width));
97
    generator.setViewBox(QRect(0, 0, width, width));
98
    generator.setResolution(dpi);
99
    generator.setOutputDevice(outputDevice);
100

101
    QPainter painter;
102
    painter.begin(&generator);
103

104
    // Background
105
    painter.setClipRect(QRect(0, 0, width, width));
106
    painter.fillRect(QRect(0, 0, width, width), Qt::white);
107

108
    // Foreground
109
    // "Dots" are stored in a quint8 x quint8 array using row-major order.
110
    // A dot is black if the LSB of its corresponding quint8 is 1.
111
    const QPen pen(Qt::black, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
112
    const QBrush brush(Qt::black);
113
    painter.setPen(pen);
114
    painter.setBrush(brush);
115

116
    const int rowSize = d_ptr->m_qrcode->width;
117
    unsigned char* dot = d_ptr->m_qrcode->data;
118
    for (int y = 0; y < rowSize; ++y) {
119
        for (int x = 0; x < rowSize; ++x) {
120
            if (quint8(0x01) == (static_cast<quint8>(*dot++) & quint8(0x01))) {
121
                painter.drawRect(margin + x, margin + y, 1, 1);
122
            }
123
        }
124
    }
125

126
    painter.end();
127
}
128

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.