mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
f1203d365a
commit
5b6f468547
7 changed files with 31 additions and 12 deletions
|
@ -143,6 +143,7 @@ SOURCES += subsurface-mobile-main.cpp \
|
|||
stats/statsaxis.cpp \
|
||||
stats/statscolors.cpp \
|
||||
stats/statsgrid.cpp \
|
||||
stats/statshelper.cpp \
|
||||
stats/statsseries.cpp \
|
||||
stats/statsstate.cpp \
|
||||
mobile-widgets/qmlinterface.cpp \
|
||||
|
@ -295,6 +296,7 @@ HEADERS += \
|
|||
stats/statsaxis.h \
|
||||
stats/statscolors.h \
|
||||
stats/statsgrid.h \
|
||||
stats/statshelper.h \
|
||||
stats/statsseries.h \
|
||||
stats/statsstate.h \
|
||||
stats/statstranslations.h \
|
||||
|
|
|
@ -34,6 +34,8 @@ set(SUBSURFACE_STATS_SRCS
|
|||
statscolors.cpp
|
||||
statsgrid.h
|
||||
statsgrid.cpp
|
||||
statshelper.h
|
||||
statshelper.cpp
|
||||
statsseries.h
|
||||
statsseries.cpp
|
||||
statsstate.h
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -44,8 +44,9 @@ void PieSeries::Item::updatePositions(const QPointF ¢er, 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 ¢er, double radius)
|
|||
pos.ry() -= labelRect.height();
|
||||
}
|
||||
|
||||
outerLabel->setPos(QPointF(round(pos.x()), round(pos.y())));
|
||||
outerLabel->setPos(roundPos(pos));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
stats/statshelper.cpp
Normal file
10
stats/statshelper.cpp
Normal file
|
@ -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()));
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue