Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
#include "singleinstance.h"
#include <QApplication>
#include <QFontDatabase>
#include <QGuiApplication>

int main(int argc, char *argv[])
{
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

QApplication app(argc, argv);
// Set application information
QApplication::setApplicationName("Notes");
Expand Down
6 changes: 3 additions & 3 deletions src/notelistdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ QTimeLine::State NoteListDelegate::animationState()
void NoteListDelegate::paintBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
auto bufferSize = bufferSizeHint(option, index);
QPixmap buffer{ bufferSize };
QPixmap buffer = utils::makeDevicePixelRatioPixmap(bufferSize, m_view);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Once this buffer is DPR-aware, the drawPixmap(..., buffer, QRect{...}) calls lower in paintBackground() still need to convert their source rects before drawing. One compact way is to add this near the draw section and route those calls through it:

auto drawBuffer = [&buffer, painter](const QRect &targetRect, const QRect &sourceRect) {
    painter->drawPixmap(targetRect, buffer, utils::devicePixelRatioPixmapSourceRect(sourceRect, buffer));
};

Then replace each painter->drawPixmap(..., buffer, QRect{...}) in this function with drawBuffer(..., QRect{...}). The same pattern applies to the animated label buffer in paintLabels().

buffer.fill(Qt::transparent);
QPainter bufferPainter{ &buffer };
bufferPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QRect bufferRect = buffer.rect();
QRect bufferRect{ QPoint{ }, bufferSize };
auto isPinned = index.data(NoteListModel::NoteIsPinned).toBool();
auto const *model = static_cast<NoteListModel *>(m_view->model());
if (model->hasPinnedNote() && model->isFirstPinnedNote(index) && static_cast<NoteListView *>(m_view)->isPinnedNotesCollapsed()) {
Expand Down Expand Up @@ -419,7 +419,7 @@ void NoteListDelegate::paintLabels(QPainter *painter, const QStyleOptionViewItem
{
if (m_animatedIndexes.contains(index)) {
auto bufferSize = bufferSizeHint(option, index);
QPixmap buffer{ bufferSize };
QPixmap buffer = utils::makeDevicePixelRatioPixmap(bufferSize, m_view);
buffer.fill(Qt::transparent);
QPainter bufferPainter{ &buffer };
bufferPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
Expand Down
6 changes: 3 additions & 3 deletions src/notelistdelegateeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,11 @@ NoteListDelegateEditor::~NoteListDelegateEditor()
void NoteListDelegateEditor::paintBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
auto bufferSize = rect().size();
QPixmap buffer{ bufferSize };
QPixmap buffer = utils::makeDevicePixelRatioPixmap(bufferSize, this);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Same coordinate-space issue here: the buffer is now DPR-aware, but the later source rect passed to drawPixmap() is still logical. The final draw should convert that source rect first, for example:

auto rowHeight = rect().height();
const QRect sourceRect{ 0, bufferSize.height() - rowHeight, rect().width(), rowHeight };
painter->drawPixmap(rect(), buffer, utils::devicePixelRatioPixmapSourceRect(sourceRect, buffer));

buffer.fill(Qt::transparent);
QPainter bufferPainter{ &buffer };
bufferPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QRect bufferRect = buffer.rect();
QRect bufferRect{ QPoint{ }, bufferSize };
auto const *noteListModel = static_cast<NoteListModel *>(m_view->model());
if (noteListModel->hasPinnedNote() && (noteListModel->isFirstPinnedNote(index) || noteListModel->isFirstUnpinnedNote(index))) {
int fifthYOffset = 0;
Expand Down Expand Up @@ -375,7 +375,7 @@ bool NoteListDelegateEditor::underMouseC() const

QPixmap NoteListDelegateEditor::renderToPixmap()
{
QPixmap result{ rect().size() };
QPixmap result = utils::makeDevicePixelRatioPixmap(rect().size(), this);
result.fill(Qt::yellow);
QPainter painter(&result);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
Expand Down
34 changes: 32 additions & 2 deletions src/utils.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#pragma once

#include <QGuiApplication>
#include <cmath>
#include <QString>
#include <QDateTime>
#include <QPixmap>

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This helper will also need QRect for converting logical source rects to pixmap/device-pixel source rects.

Suggested change
#include <QPixmap>
#include <QPixmap>
#include <QRect>

#include <QScreen>
#include <QString>
#include <QWidget>
#include <QWindow>

namespace utils {

Expand Down Expand Up @@ -44,4 +49,29 @@ inline QString parseDateTime(const QDateTime &dateTime)
return dateTime.date().toString("M/d/yy");
}

} // namespace utils
inline qreal devicePixelRatioForWidget(const QWidget *widget)
{
if (widget != nullptr) {
if (auto *topLevelWindow = widget->window(); (topLevelWindow != nullptr) && (topLevelWindow->windowHandle() != nullptr)) {
return topLevelWindow->windowHandle()->devicePixelRatio();
}

return widget->devicePixelRatioF();
}

if (auto *screen = QGuiApplication::primaryScreen(); screen != nullptr) {
return screen->devicePixelRatio();
}

return qreal(1);
}

inline QPixmap makeDevicePixelRatioPixmap(const QSize &logicalSize, const QWidget *widget)
{
const qreal scale = devicePixelRatioForWidget(widget);
QPixmap pixmap(logicalSize * scale);
pixmap.setDevicePixelRatio(scale);
return pixmap;
}
Comment on lines +69 to +75

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Could we pair the DPR pixmap allocator with a small source-rect conversion helper? Painting into the pixmap stays in logical coordinates, but QPainter::drawPixmap(..., sourceRect) reads sourceRect in pixmap/device pixels.

Suggested change
inline QPixmap makeDevicePixelRatioPixmap(const QSize &logicalSize, const QWidget *widget)
{
const qreal scale = devicePixelRatioForWidget(widget);
QPixmap pixmap(logicalSize * scale);
pixmap.setDevicePixelRatio(scale);
return pixmap;
}
inline QPixmap makeDevicePixelRatioPixmap(const QSize &logicalSize, const QWidget *widget)
{
const qreal scale = devicePixelRatioForWidget(widget);
QPixmap pixmap(logicalSize * scale);
pixmap.setDevicePixelRatio(scale);
return pixmap;
}
inline QRect devicePixelRatioPixmapSourceRect(const QRect &logicalRect, const QPixmap &pixmap)
{
const qreal scale = pixmap.devicePixelRatio();
const QRectF scaledRect(logicalRect.x() * scale, logicalRect.y() * scale, logicalRect.width() * scale, logicalRect.height() * scale);
return scaledRect.toAlignedRect();
}


} // namespace utils