Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix scaling of cover art on high pixel density screens #2247

Merged
merged 2 commits into from
Nov 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/library/coverartcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mixxx::Logger kLogger("CoverArtCache");

QString pixmapCacheKey(quint16 hash, int width) {
return QString("CoverArtCache_%1_%2")
.arg(QString::number(hash)).arg(width);
.arg(QString::number(hash), QString::number(width));
}

// The transformation mode when scaling images
Expand All @@ -26,10 +26,10 @@ inline QImage resizeImageWidth(const QImage& image, int width) {
return image.scaledToWidth(width, kTransformationMode);
}

} // anonymous namespace

const bool sDebug = false;

} // anonymous namespace

CoverArtCache::CoverArtCache() {
// The initial QPixmapCache limit is 10MB.
// But it is not used just by the coverArt stuff,
Expand Down Expand Up @@ -80,6 +80,9 @@ QPixmap CoverArtCache::requestCover(const CoverInfo& requestInfo,

QPixmap pixmap;
if (QPixmapCache::find(cacheKey, &pixmap)) {
if (sDebug) {
kLogger.debug() << "CoverArtCache::requestCover cover found in cache" << requestInfo << signalWhenDone;
}
if (signalWhenDone) {
emit(coverFound(pRequestor, requestInfo, pixmap, true));
}
Expand All @@ -93,6 +96,9 @@ QPixmap CoverArtCache::requestCover(const CoverInfo& requestInfo,
return QPixmap();
}

if (sDebug) {
kLogger.debug() << "CoverArtCache::requestCover starting future for" << requestInfo;
}
m_runningRequests.insert(requestId);
// The watcher will be deleted in coverLoaded()
QFutureWatcher<FutureResult>* watcher = new QFutureWatcher<FutureResult>(this);
Expand Down
18 changes: 7 additions & 11 deletions src/library/coverartdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "library/coverartdelegate.h"
#include "library/coverartcache.h"
#include "library/dao/trackschema.h"
#include "util/compatibility.h"
#include "util/math.h"

CoverArtDelegate::CoverArtDelegate(QTableView* parent)
Expand All @@ -23,10 +24,8 @@ CoverArtDelegate::CoverArtDelegate(QTableView* parent)

CoverArtCache* pCache = CoverArtCache::instance();
if (pCache) {
connect(pCache, SIGNAL(coverFound(const QObject*, const CoverInfoRelative&,
QPixmap, bool)),
this, SLOT(slotCoverFound(const QObject*, const CoverInfoRelative&,
QPixmap, bool)));
connect(pCache, &CoverArtCache::coverFound,
this, &CoverArtDelegate::slotCoverFound);
}

TrackModel* pTrackModel = NULL;
Expand Down Expand Up @@ -108,17 +107,14 @@ void CoverArtDelegate::paintItem(QPainter *painter,
info.hash = index.sibling(index.row(), m_iCoverHashColumn).data().toUInt();
info.trackLocation = index.sibling(index.row(), m_iTrackLocationColumn).data().toString();

double scaleFactor = getDevicePixelRatioF(dynamic_cast<QWidget*>(parent()));
Be-ing marked this conversation as resolved.
Show resolved Hide resolved
// We listen for updates via slotCoverFound above and signal to
// BaseSqlTableModel when a row's cover is ready.
QPixmap pixmap = pCache->requestCover(info, this, option.rect.width(),
QPixmap pixmap = pCache->requestCover(info, this, option.rect.width() * scaleFactor,
m_bOnlyCachedCover, true);
if (!pixmap.isNull()) {
int width = math_min(pixmap.width(), option.rect.width());
int height = math_min(pixmap.height(), option.rect.height());
QRect target(option.rect.x(), option.rect.y(),
width, height);
QRect source(0, 0, target.width(), target.height());
painter->drawPixmap(target, pixmap, source);
pixmap.setDevicePixelRatio(scaleFactor);
daschuer marked this conversation as resolved.
Show resolved Hide resolved
painter->drawPixmap(option.rect.topLeft(), pixmap);
} else if (!m_bOnlyCachedCover) {
// If we asked for a non-cache image and got a null pixmap, then our
// request was queued.
Expand Down
7 changes: 5 additions & 2 deletions src/library/dlgcoverartfullsize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "library/dlgcoverartfullsize.h"
#include "library/coverartutils.h"
#include "library/coverartcache.h"
#include "util/compatibility.h"

DlgCoverArtFullSize::DlgCoverArtFullSize(QWidget* parent, BaseTrackPlayer* pPlayer)
: QDialog(parent),
Expand Down Expand Up @@ -131,8 +132,9 @@ void DlgCoverArtFullSize::slotCoverFound(const QObject* pRequestor,
dialogSize.scale(availableScreenSpace.width(), dialogSize.height(),
Qt::KeepAspectRatio);
}
QPixmap resizedPixmap = m_pixmap.scaled(size(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is in line 125 above, where the logical dialogSize is taken form the native pixel size.
Can you try to use
QSize dialogSize = m_pixmap.size() / getDevicePixelRatioF(this);
there?

QPixmap resizedPixmap = m_pixmap.scaled(size() * getDevicePixelRatioF(this),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
resizedPixmap.setDevicePixelRatio(getDevicePixelRatioF(this));
coverArt->setPixmap(resizedPixmap);
// center the window
setGeometry(QStyle::alignedRect(
Expand Down Expand Up @@ -181,8 +183,9 @@ void DlgCoverArtFullSize::resizeEvent(QResizeEvent* event) {
return;
}
// qDebug() << "DlgCoverArtFullSize::resizeEvent" << size();
QPixmap resizedPixmap = m_pixmap.scaled(size(),
QPixmap resizedPixmap = m_pixmap.scaled(size() * getDevicePixelRatioF(this),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
resizedPixmap.setDevicePixelRatio(getDevicePixelRatioF(this));
coverArt->setPixmap(resizedPixmap);
}

Expand Down
1 change: 1 addition & 0 deletions src/library/dlgtrackinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "track/beatfactory.h"
#include "track/keyfactory.h"
#include "track/keyutils.h"
#include "util/compatibility.h"
#include "util/duration.h"

const int kFilterLength = 80;
Expand Down
7 changes: 6 additions & 1 deletion src/widget/wcoverart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "library/coverartcache.h"
#include "library/coverartutils.h"
#include "library/dlgcoverartfullsize.h"
#include "util/compatibility.h"
#include "util/dnd.h"
#include "util/math.h"

Expand Down Expand Up @@ -190,7 +191,11 @@ QPixmap WCoverArt::scaledCoverArt(const QPixmap& normal) {
if (normal.isNull()) {
return QPixmap();
}
return normal.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmap scaled;
scaled = normal.scaled(size() * getDevicePixelRatioF(this),
uklotzde marked this conversation as resolved.
Show resolved Hide resolved
Qt::KeepAspectRatio, Qt::SmoothTransformation);
scaled.setDevicePixelRatio(getDevicePixelRatioF(this));
return scaled;
}

void WCoverArt::paintEvent(QPaintEvent* /*unused*/) {
Expand Down
16 changes: 9 additions & 7 deletions src/widget/wcoverartlabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "library/dlgcoverartfullsize.h"
#include "library/coverartutils.h"
#include "util/compatibility.h"

static const QSize s_labelDisplaySize = QSize(100, 100);

Expand All @@ -23,7 +24,8 @@ WCoverArtLabel::WCoverArtLabel(QWidget* parent)
connect(m_pCoverMenu, SIGNAL(reloadCoverArt()),
this, SIGNAL(reloadCoverArt()));

m_defaultCover = m_defaultCover.scaled(s_labelDisplaySize,
m_defaultCover.setDevicePixelRatio(getDevicePixelRatioF(this));
m_defaultCover = m_defaultCover.scaled(s_labelDisplaySize * getDevicePixelRatioF(this),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
setPixmap(m_defaultCover);
Expand All @@ -38,18 +40,18 @@ void WCoverArtLabel::setCoverArt(const CoverInfo& coverInfo,
QPixmap px) {
qDebug() << "WCoverArtLabel::setCoverArt" << coverInfo << px.size();

m_loadedCover = px;
m_loadedCover = px.scaled(s_labelDisplaySize * getDevicePixelRatioF(this),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
m_loadedCover.setDevicePixelRatio(getDevicePixelRatioF(this));
m_pCoverMenu->setCoverArt(coverInfo);


if (px.isNull()) {
if (m_loadedCover.isNull()) {
setPixmap(m_defaultCover);
} else {
setPixmap(px.scaled(s_labelDisplaySize, Qt::KeepAspectRatio,
Qt::SmoothTransformation));
setPixmap(m_loadedCover);
}

QSize frameSize = pixmap()->size();
QSize frameSize = pixmap()->size() / getDevicePixelRatioF(this);
frameSize += QSize(2,2); // margin
setMinimumSize(frameSize);
setMaximumSize(frameSize);
Expand Down
12 changes: 9 additions & 3 deletions src/widget/wspinny.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "control/controlobject.h"
#include "control/controlproxy.h"
#include "library/coverartcache.h"
#include "util/compatibility.h"
#include "util/dnd.h"
#include "waveform/sharedglcontext.h"
#include "util/math.h"
Expand Down Expand Up @@ -318,6 +319,8 @@ void WSpinny::render() {
&m_dGhostAngleCurrentPlaypos);
}

double scaleFactor = getDevicePixelRatioF(this);

QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::HighQualityAntialiasing);
Expand All @@ -329,8 +332,8 @@ void WSpinny::render() {

if (m_bShowCover && !m_loadedCoverScaled.isNull()) {
// Some covers aren't square, so center them.
int x = (width() - m_loadedCoverScaled.width()) / 2;
int y = (height() - m_loadedCoverScaled.height()) / 2;
int x = (width() - m_loadedCoverScaled.width() / scaleFactor) / 2;
int y = (height() - m_loadedCoverScaled.height() / scaleFactor) / 2;
p.drawPixmap(x, y, m_loadedCoverScaled);
}

Expand Down Expand Up @@ -403,7 +406,10 @@ QPixmap WSpinny::scaledCoverArt(const QPixmap& normal) {
if (normal.isNull()) {
return QPixmap();
}
return normal.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmap scaled = normal.scaled(size() * getDevicePixelRatioF(this),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
scaled.setDevicePixelRatio(getDevicePixelRatioF(this));
return scaled;
}

void WSpinny::resizeEvent(QResizeEvent* /*unused*/) {
Expand Down