From 087cb0a6f8baae36807e0e6e06a33f9644e8e893 Mon Sep 17 00:00:00 2001 From: lupoDharkael Date: Sun, 21 May 2017 18:19:25 +0200 Subject: [PATCH] Add a huge performance improvement when using the pencil --- capture/capturewidget.cpp | 44 +++++++----- capture/capturewidget.h | 3 +- capture/screenshot.cpp | 144 ++++++++++++++++++++++++++------------ capture/screenshot.h | 9 ++- config/uicoloreditor.cpp | 10 +-- 5 files changed, 140 insertions(+), 70 deletions(-) diff --git a/capture/capturewidget.cpp b/capture/capturewidget.cpp index 5ca0c3b4..80bc16c7 100644 --- a/capture/capturewidget.cpp +++ b/capture/capturewidget.cpp @@ -81,7 +81,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) : m_buttonHandler->hide(); // init screenshot createCapture(); - resize(m_screenshot.size()); + resize(m_screenshot->getScreenshot().size()); // init interface color m_uiColor = QSettings().value("uiColor").value(); show(); @@ -91,6 +91,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) : CaptureWidget::~CaptureWidget() { delete(m_buttonHandler); + delete(m_screenshot); } // redefineButtons retrieves the buttons configured to be shown with the @@ -122,10 +123,15 @@ void CaptureWidget::paintEvent(QPaintEvent *) { if (m_grabbing) { // grabWindow() should just get the background return; } - - Screenshot s(m_screenshot); - s.paintModifications(m_modifications); - painter.drawPixmap(0, 0, s.getScreenshot()); + // if we are creating a new modification to the screenshot we just draw + // a temporal modification without antialiasing in the pencil tool for + // performance. When we are not drawing we just shot the modified screenshot + if (m_mouseIsClicked && m_state != Button::Type::move) { + painter.drawPixmap(0, 0, m_screenshot->paintTemporalModification( + m_modifications.last())); + } else { + painter.drawPixmap(0, 0, m_screenshot->getScreenshot()); + } QColor overlayColor(0, 0, 0, 160); painter.setBrush(overlayColor); @@ -166,6 +172,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { if (m_state != Button::Type::move) { m_modifications.append(CaptureModification(m_state, e->pos(), m_colorPicker->getDrawColor())); + m_screenshot->paintModification(m_modifications.last()); return; } m_dragStartPoint = e->pos(); @@ -293,6 +300,10 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) { m_colorPicker->hide(); m_rightClick = false; return; + // when we end the drawing of a modification in the capture we have to + // register the last point and add the whole modification to the screenshot + } else if (m_mouseIsClicked && m_state != Button::Type::move) { + m_screenshot->paintModification(m_modifications.last()); } if (!m_selection.isNull() && !m_buttonHandler->isVisible()) { @@ -335,22 +346,18 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) { } void CaptureWidget::saveScreenshot() { - Screenshot s(m_screenshot); - s.paintModifications(m_modifications); if (m_selection.isNull()) { - s.graphicalSave(); + m_screenshot->graphicalSave(); } else { // save full screen when no selection - s.graphicalSave(getExtendedSelection()); + m_screenshot->graphicalSave(getExtendedSelection()); } } void CaptureWidget::copyScreenshot() { - Screenshot s(m_screenshot); - s.paintModifications(m_modifications); if (m_selection.isNull()) { - QApplication::clipboard()->setPixmap(s.getScreenshot()); + QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot()); } else { // copy full screen when no selection - QApplication::clipboard()->setPixmap(s.getScreenshot() + QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot() .copy(getExtendedSelection())); } close(); @@ -367,15 +374,13 @@ void CaptureWidget::openURL(QNetworkReply *reply) { } void CaptureWidget::uploadScreenshot() { - Screenshot s(m_screenshot); - s.paintModifications(m_modifications); QNetworkAccessManager *am = new QNetworkAccessManager(this); connect(am, &QNetworkAccessManager::finished, this, &CaptureWidget::openURL); if (m_selection.isNull()) { - s.uploadToImgur(am); + m_screenshot->uploadToImgur(am); } else { - s.uploadToImgur(am, getExtendedSelection()); + m_screenshot->uploadToImgur(am, getExtendedSelection()); } hide(); Q_EMIT newMessage("Uploading image..."); @@ -384,6 +389,7 @@ void CaptureWidget::uploadScreenshot() { void CaptureWidget::undo() { if (!m_modifications.isEmpty()) { m_modifications.pop_back(); + m_screenshot->paintBaseModifications(m_modifications); update(); } } @@ -464,7 +470,7 @@ void CaptureWidget::createCapture() { close(); return; } - m_screenshot = screen->grabWindow(0); + m_screenshot = new Screenshot(screen->grabWindow(0)); } void CaptureWidget::initShortcuts() { @@ -524,7 +530,7 @@ QPoint CaptureWidget::limitPointToRect(const QPoint &p, const QRect &r) const { } QRect CaptureWidget::getExtendedSelection() const { - auto devicePixelRatio = m_screenshot.devicePixelRatio(); + auto devicePixelRatio = m_screenshot->getScreenshot().devicePixelRatio(); return QRect(m_selection.left() * devicePixelRatio, m_selection.top() * devicePixelRatio, diff --git a/capture/capturewidget.h b/capture/capturewidget.h index 01470f66..39ee3bb7 100644 --- a/capture/capturewidget.h +++ b/capture/capturewidget.h @@ -36,6 +36,7 @@ class CaptureModification; class QNetworkAccessManager; class QNetworkReply; class ColorPicker; +class Screenshot; class CaptureWidget : public QWidget { Q_OBJECT @@ -74,7 +75,7 @@ protected: QRegion handleMask() const; // pixel map of the screen - QPixmap m_screenshot; + Screenshot* m_screenshot; QPoint m_dragStartPoint; QPoint m_mousePos; diff --git a/capture/screenshot.cpp b/capture/screenshot.cpp index 0fc5639d..468f6bae 100644 --- a/capture/screenshot.cpp +++ b/capture/screenshot.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,22 +35,30 @@ // Screenshot is an extension of QPixmap which lets you manage specific tasks -Screenshot::Screenshot(const QPixmap &p) : m_screenshot(p) { - -} +Screenshot::Screenshot(const QPixmap &p) : m_baseScreenshot(p), + m_modifiedScreenshot(p) {} Screenshot::~Screenshot() { if (m_accessManager) delete(m_accessManager); } void Screenshot::setScreenshot(const QPixmap &p) { - m_screenshot = p; + m_baseScreenshot = p; + m_modifiedScreenshot = p; } +// getScreenshot returns the screenshot with no modifications +QPixmap Screenshot::getBaseScreenshot() const { + return m_baseScreenshot; +} + +// getScreenshot returns the screenshot with all the modifications QPixmap Screenshot::getScreenshot() const { - return m_screenshot; + return m_modifiedScreenshot; } +// graphicalSave generates a graphical window to ask about the save path and +// saves the screenshot with all the modifications in such directory QString Screenshot::graphicalSave(const QRect &selection) const { const QString format = "png"; @@ -98,9 +107,9 @@ QString Screenshot::graphicalSave(const QRect &selection) const { QPixmap pixToSave; if (selection.isEmpty()) { - pixToSave = m_screenshot; + pixToSave = m_modifiedScreenshot; } else { // save full screen when no selection - pixToSave = m_screenshot.copy(selection); + pixToSave = m_modifiedScreenshot.copy(selection); } // if (settings.value("mouseVisible").toBool()) { @@ -115,52 +124,101 @@ QString Screenshot::graphicalSave(const QRect &selection) const { return fileName; } -QPixmap Screenshot::paintModifications(const QVector v) { - QPainter painter(&m_screenshot); +// paintModification adds a new modification to the screenshot +QPixmap Screenshot::paintModification(const CaptureModification &modification) { + QPainter painter(&m_modifiedScreenshot); painter.setRenderHint(QPainter::Antialiasing); - for (CaptureModification modification: v) { - painter.setPen(QPen(modification.getColor(), 2)); - QVector points = modification.getPoints(); - switch (modification.getType()) { - case Button::Type::arrow: - painter.drawLine(points[0], points[1]); - // TODO - break; - case Button::Type::circle: - painter.drawEllipse(QRect(points[0], points[1])); - break; - case Button::Type::line: - painter.drawLine(points[0], points[1]); - break; - case Button::Type::marker: - painter.setOpacity(0.35); - painter.setPen(QPen(modification.getColor(), 14)); - painter.drawLine(points[0], points[1]); - painter.setOpacity(1); - break; - case Button::Type::pencil: - painter.drawPolyline(points.data(), points.size()); - break; - case Button::Type::rectangle: - painter.drawRect(QRect(points[0], points[1])); - break; - default: - break; - } + painter.setPen(QPen(modification.getColor(), 2)); + QVector points = modification.getPoints(); + switch (modification.getType()) { + case Button::Type::arrow: + painter.drawLine(points[0], points[1]); + // TODO + + break; + case Button::Type::circle: + painter.drawEllipse(QRect(points[0], points[1])); + break; + case Button::Type::line: + painter.drawLine(points[0], points[1]); + break; + case Button::Type::marker: + painter.setOpacity(0.35); + painter.setPen(QPen(modification.getColor(), 14)); + painter.drawLine(points[0], points[1]); + painter.setOpacity(1); + break; + case Button::Type::pencil: + painter.drawPolyline(points.data(), points.size()); + break; + case Button::Type::rectangle: + painter.drawRect(QRect(points[0], points[1])); + break; + default: + break; } - return m_screenshot; + return m_modifiedScreenshot; +} + +QPixmap Screenshot::paintTemporalModification(const CaptureModification &modification) { + QPixmap tempPix = m_modifiedScreenshot; + QPainter painter(&tempPix); + if (modification.getType() != Button::Type::pencil) { + painter.setRenderHint(QPainter::Antialiasing); + } + + painter.setPen(QPen(modification.getColor(), 2)); + QVector points = modification.getPoints(); + switch (modification.getType()) { + case Button::Type::arrow: + painter.drawLine(points[0], points[1]); + // TODO + + break; + case Button::Type::circle: + painter.drawEllipse(QRect(points[0], points[1])); + break; + case Button::Type::line: + painter.drawLine(points[0], points[1]); + break; + case Button::Type::marker: + painter.setOpacity(0.35); + painter.setPen(QPen(modification.getColor(), 14)); + painter.drawLine(points[0], points[1]); + painter.setOpacity(1); + break; + case Button::Type::pencil: + painter.drawPolyline(points.data(), points.size()); + break; + case Button::Type::rectangle: + painter.drawRect(QRect(points[0], points[1])); + break; + default: + break; + } + return tempPix; +} + +// paintBaseModifications overrides the modifications of the screenshot with new ones +QPixmap Screenshot::paintBaseModifications(const QVector &m) { + m_modifiedScreenshot = m_baseScreenshot; + for (const CaptureModification modification: m) { + paintModification(modification); + } + return m_modifiedScreenshot; } void Screenshot::uploadToImgur(QNetworkAccessManager *accessManager, const QRect &selection) { - QString title ="asdasdf"; - QString description = "test"; + QString title ="flameshot_screenshot"; + QString datetime = QDateTime().toString(); + QString description = "flameshot " + datetime; QPixmap pixToSave; if (selection.isEmpty()) { - pixToSave = m_screenshot; + pixToSave = m_modifiedScreenshot; } else { // save full screen when no selection - pixToSave = m_screenshot.copy(selection); + pixToSave = m_modifiedScreenshot.copy(selection); } QByteArray byteArray; QBuffer buffer(&byteArray); diff --git a/capture/screenshot.h b/capture/screenshot.h index 3469f1f3..9b1559e4 100644 --- a/capture/screenshot.h +++ b/capture/screenshot.h @@ -32,14 +32,19 @@ public: ~Screenshot(); void setScreenshot(const QPixmap &); + QPixmap getBaseScreenshot() const; QPixmap getScreenshot() const; + QString graphicalSave(const QRect &selection = QRect()) const; void uploadToImgur(QNetworkAccessManager *, const QRect &selection = QRect()); - QPixmap paintModifications(const QVector); + QPixmap paintModification(const CaptureModification &); + QPixmap paintTemporalModification(const CaptureModification &); + QPixmap paintBaseModifications(const QVector &); private: - QPixmap m_screenshot; + QPixmap m_baseScreenshot; + QPixmap m_modifiedScreenshot; QPointer m_accessManager; }; diff --git a/config/uicoloreditor.cpp b/config/uicoloreditor.cpp index 56c4cccd..d8f67fcf 100644 --- a/config/uicoloreditor.cpp +++ b/config/uicoloreditor.cpp @@ -47,11 +47,11 @@ void UIcolorEditor::initColorWheel() { } void UIcolorEditor::initButton() { - bool iconsAreWhite = false; - QString bgColor = this->palette().color(QWidget::backgroundRole()).name(); - if (bgColor < QColor(Qt::gray).name()) { - iconsAreWhite = true; - } + bool iconsAreWhite = QSettings().value("whiteIconColor").toBool(); +// QString bgColor = this->palette().color(QWidget::backgroundRole()).name(); +// if (bgColor < QColor(Qt::gray).name()) { +// iconsAreWhite = true; +// } m_button = new Button(Button::Type::circle, iconsAreWhite, this); m_button->setStyleSheet(Button::getStyle()); }