Skip to content

Commit

Permalink
Take account of devicePixelRatio when rendering correlation plot
Browse files Browse the repository at this point in the history
  • Loading branch information
timangus committed Oct 16, 2023
1 parent a83490e commit 29fa5c2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
59 changes: 50 additions & 9 deletions source/plugins/correlation/correlationplotitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <QDesktopServices>
#include <QSet>
#include <QCollator>
#include <QQuickWindow>
#include <QDebug>

#include <cmath>
Expand Down Expand Up @@ -96,6 +97,11 @@ void CorrelationPlotWorker::setShowGridLines(bool showGridLines)
_showGridLines = showGridLines;
}

void CorrelationPlotWorker::setDevicePixelRatio(double devicePixelRatio)
{
_devicePixelRatio = devicePixelRatio;
}

void CorrelationPlotWorker::setWidth(int width)
{
_width = width;
Expand Down Expand Up @@ -200,11 +206,12 @@ void CorrelationPlotWorker::updatePixmap(CorrelationPlotUpdateType updateType)

void CorrelationPlotWorker::clone(CorrelationPlotWorker& target) const
{
target._width = _width;
target._height = _height;
target._xAxisMin = _xAxisMin;
target._xAxisMax = _xAxisMax;
target._showGridLines = _showGridLines;
target._devicePixelRatio = _devicePixelRatio;
target._width = _width;
target._height = _height;
target._xAxisMin = _xAxisMin;
target._xAxisMax = _xAxisMax;
target._showGridLines = _showGridLines;
}

void CorrelationPlotWorker::renderPixmap()
Expand Down Expand Up @@ -293,7 +300,14 @@ void CorrelationPlotWorker::renderPixmap()

// This assumes that the Qt platform has the QPlatformIntegration::ThreadedPixmaps capability,
// which should be true on the desktop, but a console warning will be shown if it isn't
const QPixmap pixmap = _customPlot->toPixmap();
QPixmap pixmap(
static_cast<int>(_width * _devicePixelRatio),
static_cast<int>(_height * _devicePixelRatio));

pixmap.fill(Qt::transparent);
QCPPainter painter(&pixmap);
painter.scale(_devicePixelRatio, _devicePixelRatio);
_customPlot->toPainter(&painter);

if(_debug)
qDebug() << "render" << _pixmapTimer.elapsed() << "ms";
Expand Down Expand Up @@ -350,6 +364,16 @@ CorrelationPlotItem::CorrelationPlotItem(QQuickItem* parent) :
Q_ARG(int, std::max(static_cast<int>(height()), static_cast<int>(minimumHeight()))));
});

connect(this, &QQuickPaintedItem::windowChanged, [this]
{
if(window() == nullptr)
return;

auto devicePixelRatio = window()->devicePixelRatio();
QMetaObject::invokeMethod(_worker, "setDevicePixelRatio", Qt::QueuedConnection,
Q_ARG(double, devicePixelRatio));
});

connect(_worker, &CorrelationPlotWorker::pixmapUpdated, this, &CorrelationPlotItem::onPixmapUpdated);
connect(_worker, &CorrelationPlotWorker::pixmapUpdated, this, &CorrelationPlotItem::pixmapUpdated);
connect(this, &CorrelationPlotItem::enabledChanged, [this] { update(); });
Expand Down Expand Up @@ -403,10 +427,27 @@ void CorrelationPlotItem::paint(QPainter* painter)
if(_pixmap.isNull())
return;

auto devicePixelRatio = window()->devicePixelRatio();

// Render the plot in the bottom left; that way when its container
// is resized, it doesn't hop around vertically, as it would if
// it had been rendered from the top left
const int yDest = static_cast<int>(height()) - _pixmap.height();
const int yOffset = static_cast<int>(height() - (_pixmap.height() / devicePixelRatio));

QRect target
{
0,
yOffset,
static_cast<int>(width()),
static_cast<int>(height()) - yOffset
};

QRect source
{
0, 0,
static_cast<int>(width() * devicePixelRatio),
static_cast<int>((height() - yOffset) * devicePixelRatio)
};

if(!isEnabled())
{
Expand Down Expand Up @@ -435,13 +476,13 @@ void CorrelationPlotItem::paint(QPainter* painter)
alphaBackgroundColor.setAlpha(127);

painter->fillRect(QRectF{0.0, 0.0, width(), height()}, alphaBackgroundColor);
painter->drawPixmap(0, yDest, QPixmap::fromImage(image));
painter->drawPixmap(target, QPixmap::fromImage(image), source);
}
else
{
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->fillRect(QRectF{0.0, 0.0, width(), height()}, backgroundColor());
painter->drawPixmap(0, yDest, _pixmap);
painter->drawPixmap(target, _pixmap, source);
}
}

Expand Down
2 changes: 2 additions & 0 deletions source/plugins/correlation/correlationplotitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class CorrelationPlotWorker : public QObject
void updateZoomed();

Q_INVOKABLE void setShowGridLines(bool showGridLines);
Q_INVOKABLE void setDevicePixelRatio(double devicePixelRatio);
Q_INVOKABLE void setWidth(int width);
Q_INVOKABLE void setHeight(int height);
Q_INVOKABLE void setXAxisRange(double min, double max);
Expand All @@ -135,6 +136,7 @@ class CorrelationPlotWorker : public QObject
QCustomPlot* _customPlot = nullptr;
QOffscreenSurface* _surface = nullptr;

double _devicePixelRatio = 1.0;
int _width = -1;
int _height = -1;
double _xAxisMin = 0.0;
Expand Down

0 comments on commit 29fa5c2

Please sign in to comment.