diff --git a/src/BlurhashProvider.h b/src/BlurhashProvider.h index 21e4ff16..73b95eee 100644 --- a/src/BlurhashProvider.h +++ b/src/BlurhashProvider.h @@ -50,7 +50,7 @@ public: void handleDone(QImage image) { - m_image = image; + m_image = std::move(image); emit finished(); } void handleError(QString error) diff --git a/src/JdenticonProvider.cpp b/src/JdenticonProvider.cpp index e421c932..f0360ad6 100644 --- a/src/JdenticonProvider.cpp +++ b/src/JdenticonProvider.cpp @@ -19,65 +19,6 @@ #include "Utils.h" #include "jdenticoninterface.h" -static QPixmap -clipRadius(QPixmap img, double radius) -{ - QPixmap out(img.size()); - out.fill(Qt::transparent); - - QPainter painter(&out); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - - QPainterPath ppath; - ppath.addRoundedRect(img.rect(), radius, radius, Qt::SizeMode::RelativeSize); - - painter.setClipPath(ppath); - painter.drawPixmap(img.rect(), img); - - return out; -} - -JdenticonResponse::JdenticonResponse(const QString &key, - bool crop, - double radius, - const QSize &requestedSize) - : m_key(key) - , m_crop{crop} - , m_radius{radius} - , m_requestedSize(requestedSize.isValid() ? requestedSize : QSize(100, 100)) - , m_pixmap{m_requestedSize} - , jdenticonInterface_{Jdenticon::getJdenticonInterface()} -{ - setAutoDelete(false); -} - -void -JdenticonResponse::run() -{ - m_pixmap.fill(Qt::transparent); - - QPainter painter; - painter.begin(&m_pixmap); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - - try { - QSvgRenderer renderer{ - jdenticonInterface_->generate(m_key, m_requestedSize.width()).toUtf8()}; - renderer.render(&painter); - } catch (std::exception &e) { - nhlog::ui()->error( - "caught {} in jdenticonprovider, key '{}'", e.what(), m_key.toStdString()); - } - - painter.end(); - - m_pixmap = clipRadius(m_pixmap, m_radius); - - emit finished(); -} - namespace Jdenticon { JdenticonInterface * getJdenticonInterface() @@ -106,3 +47,81 @@ getJdenticonInterface() return interface; } } + +static QPixmap +clipRadius(QPixmap img, double radius) +{ + QPixmap out(img.size()); + out.fill(Qt::transparent); + + QPainter painter(&out); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + + QPainterPath ppath; + ppath.addRoundedRect(img.rect(), radius, radius, Qt::SizeMode::RelativeSize); + + painter.setClipPath(ppath); + painter.drawPixmap(img.rect(), img); + + return out; +} + +JdenticonResponse::JdenticonResponse(const QString &key, + bool crop, + double radius, + const QSize &requestedSize, + QThreadPool *pool) +{ + auto runnable = new JdenticonRunnable(key, crop, radius, requestedSize); + connect(runnable, &JdenticonRunnable::done, this, &JdenticonResponse::handleDone); + pool->start(runnable); +} + +JdenticonRunnable::JdenticonRunnable(const QString &key, + bool crop, + double radius, + const QSize &requestedSize) + : m_key(key) + , m_crop{crop} + , m_radius{radius} + , m_requestedSize(requestedSize.isValid() ? requestedSize : QSize(100, 100)) +{} + +void +JdenticonRunnable::run() +{ + QPixmap pixmap(m_requestedSize); + pixmap.fill(Qt::transparent); + + auto jdenticon = Jdenticon::getJdenticonInterface(); + if (!jdenticon) { + emit done(pixmap.toImage()); + return; + } + + QPainter painter; + painter.begin(&pixmap); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + + try { + QSvgRenderer renderer{jdenticon->generate(m_key, m_requestedSize.width()).toUtf8()}; + renderer.render(&painter); + } catch (std::exception &e) { + nhlog::ui()->error( + "caught {} in jdenticonprovider, key '{}'", e.what(), m_key.toStdString()); + } + + painter.end(); + + pixmap = clipRadius(pixmap, m_radius); + + emit done(pixmap.toImage()); +} + +bool +JdenticonProvider::isAvailable() +{ + return Jdenticon::getJdenticonInterface() != nullptr; +} diff --git a/src/JdenticonProvider.h b/src/JdenticonProvider.h index 95f3db78..b387b3c1 100644 --- a/src/JdenticonProvider.h +++ b/src/JdenticonProvider.h @@ -13,31 +13,47 @@ #include "jdenticoninterface.h" -namespace Jdenticon { -JdenticonInterface * -getJdenticonInterface(); -} - -class JdenticonResponse - : public QQuickImageResponse +class JdenticonRunnable + : public QObject , public QRunnable { + Q_OBJECT public: - JdenticonResponse(const QString &key, bool crop, double radius, const QSize &requestedSize); - - QQuickTextureFactory *textureFactory() const override - { - return QQuickTextureFactory::textureFactoryForImage(m_pixmap.toImage()); - } + JdenticonRunnable(const QString &key, bool crop, double radius, const QSize &requestedSize); void run() override; +signals: + void done(QImage img); + +private: QString m_key; bool m_crop; double m_radius; QSize m_requestedSize; - QPixmap m_pixmap; - JdenticonInterface *jdenticonInterface_ = nullptr; +}; + +class JdenticonResponse : public QQuickImageResponse +{ +public: + JdenticonResponse(const QString &key, + bool crop, + double radius, + const QSize &requestedSize, + QThreadPool *pool); + + QQuickTextureFactory *textureFactory() const override + { + return QQuickTextureFactory::textureFactoryForImage(m_pixmap); + } + + void handleDone(QImage img) + { + m_pixmap = std::move(img); + emit finished(); + } + + QImage m_pixmap; }; class JdenticonProvider @@ -47,7 +63,7 @@ class JdenticonProvider Q_OBJECT public: - static bool isAvailable() { return Jdenticon::getJdenticonInterface() != nullptr; } + static bool isAvailable(); public slots: QQuickImageResponse * @@ -70,9 +86,7 @@ public slots: } } - JdenticonResponse *response = new JdenticonResponse(id_, crop, radius, requestedSize); - pool.start(response); - return response; + return new JdenticonResponse(id_, crop, radius, requestedSize, &pool); } private: