summaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-02-06 12:26:54 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-02-06 10:05:41 -0800
commit5b6f4685475be7f7b68375fcab465c1626950296 (patch)
tree5321de5a6baff8d6e41e6919a52bae724c300518 /stats
parentf1203d365a4a890410038943cdd4aaaaf6ab558c (diff)
downloadsubsurface-5b6f4685475be7f7b68375fcab465c1626950296.tar.gz
statistics: don't place labels at half-integer values
Placing labels at half-integer values gives horrible rendering artifacts. Therefore, always round to integer values. The easiest way to do this is right before setting the position. Introduce a helper function to round QPointF in such scenarios. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats')
-rw-r--r--stats/CMakeLists.txt2
-rw-r--r--stats/barseries.cpp12
-rw-r--r--stats/pieseries.cpp7
-rw-r--r--stats/statshelper.cpp10
-rw-r--r--stats/statshelper.h6
-rw-r--r--stats/statsview.cpp4
6 files changed, 29 insertions, 12 deletions
diff --git a/stats/CMakeLists.txt b/stats/CMakeLists.txt
index daeb22146..1381797da 100644
--- a/stats/CMakeLists.txt
+++ b/stats/CMakeLists.txt
@@ -34,6 +34,8 @@ set(SUBSURFACE_STATS_SRCS
statscolors.cpp
statsgrid.h
statsgrid.cpp
+ statshelper.h
+ statshelper.cpp
statsseries.h
statsseries.cpp
statsstate.h
diff --git a/stats/barseries.cpp b/stats/barseries.cpp
index 766843703..252f05af6 100644
--- a/stats/barseries.cpp
+++ b/stats/barseries.cpp
@@ -118,7 +118,7 @@ void BarSeries::BarLabel::updatePosition(bool horizontal, bool center, const QRe
return;
}
QPointF pos = rect.center();
- pos.rx() -= round(itemSize.width() / 2.0);
+ pos.rx() -= itemSize.width() / 2.0;
// Heuristics: if the label fits nicely into the bar (bar height is at least twice the label height),
// then put the label in the middle of the bar. Otherwise, put it at the top of the bar.
@@ -130,29 +130,29 @@ void BarSeries::BarLabel::updatePosition(bool horizontal, bool center, const QRe
setVisible(false);
return;
}
- pos.ry() -= round(itemSize.height() / 2.0);
+ pos.ry() -= itemSize.height() / 2.0;
}
- item->setPos(pos);
+ item->setPos(roundPos(pos)); // Round to integer to avoid ugly artifacts.
} else {
if (itemSize.height() > rect.height()) {
setVisible(false);
return;
}
QPointF pos = rect.center();
- pos.ry() -= round(itemSize.height() / 2.0);
+ pos.ry() -= itemSize.height() / 2.0;
// Heuristics: if the label fits nicely into the bar (bar width is at least twice the label height),
// then put the label in the middle of the bar. Otherwise, put it to the right of the bar.
isOutside = !center && rect.width() < 2.0 * itemSize.width();
if (isOutside) {
- pos.rx() = round(rect.right() + 2.0); // Leave two pixels(?) space
+ pos.rx() = rect.right() + 2.0; // Leave two pixels(?) space
} else {
if (itemSize.width() > rect.width()) {
setVisible(false);
return;
}
}
- item->setPos(pos);
+ item->setPos(roundPos(pos)); // Round to integer to avoid ugly artifacts.
}
setVisible(true);
// If label changed from inside to outside, or vice-versa, the color might change.
diff --git a/stats/pieseries.cpp b/stats/pieseries.cpp
index 8db3bdbe3..d837abe5a 100644
--- a/stats/pieseries.cpp
+++ b/stats/pieseries.cpp
@@ -44,8 +44,9 @@ void PieSeries::Item::updatePositions(const QPointF &center, double radius)
// because half-integer values gives horrible aliasing artifacts.
if (innerLabel) {
QRectF labelRect = innerLabel->getRect();
- innerLabel->setPos(QPointF(round(center.x() + innerLabelPos.x() * radius - labelRect.width() / 2.0),
- round(center.y() + innerLabelPos.y() * radius - labelRect.height() / 2.0)));
+ QPointF pos(center.x() + innerLabelPos.x() * radius - labelRect.width() / 2.0,
+ center.y() + innerLabelPos.y() * radius - labelRect.height() / 2.0);
+ innerLabel->setPos(roundPos(pos));
}
if (outerLabel) {
QRectF labelRect = outerLabel->getRect();
@@ -59,7 +60,7 @@ void PieSeries::Item::updatePositions(const QPointF &center, double radius)
pos.ry() -= labelRect.height();
}
- outerLabel->setPos(QPointF(round(pos.x()), round(pos.y())));
+ outerLabel->setPos(roundPos(pos));
}
}
diff --git a/stats/statshelper.cpp b/stats/statshelper.cpp
new file mode 100644
index 000000000..d84ce20cf
--- /dev/null
+++ b/stats/statshelper.cpp
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "statshelper.h"
+
+#include <cmath>
+
+QPointF roundPos(const QPointF &p)
+{
+ return QPointF(round(p.x()), round(p.y()));
+}
diff --git a/stats/statshelper.h b/stats/statshelper.h
index 6b4a30ab5..45d58d022 100644
--- a/stats/statshelper.h
+++ b/stats/statshelper.h
@@ -1,12 +1,16 @@
// SPDX-License-Identifier: GPL-2.0
-// Helper functions to render the stats. Currently contains
+// Helper functions to render the stats. Includes
// QSGNode template jugglery to overcome API flaws.
#ifndef STATSHELPER_H
#define STATSHELPER_H
#include <memory>
+#include <QPointF>
#include <QSGNode>
+// Round positions to integer values to avoid ugly artifacts
+QPointF roundPos(const QPointF &p);
+
// A stupid pointer class that initializes to null and can be copy
// assigned. This is for historical reasons: unique_ptrs to ChartItems
// were replaced by plain pointers. Instead of nulling the plain pointers
diff --git a/stats/statsview.cpp b/stats/statsview.cpp
index 5514aa35d..eec7b4ba5 100644
--- a/stats/statsview.cpp
+++ b/stats/statsview.cpp
@@ -397,8 +397,8 @@ void StatsView::updateTitlePos()
{
if (!title)
return;
- title->setPos(QPointF(round(sceneBorder + (boundingRect().width() - title->getRect().width()) / 2.0),
- round(sceneBorder)));
+ QPointF pos(sceneBorder + (boundingRect().width() - title->getRect().width()) / 2.0, sceneBorder);
+ title->setPos(roundPos(pos));
}
template <typename T, class... Args>