diff --git a/libs/ui/kis_fps_decoration.h b/libs/ui/kis_fps_decoration.h --- a/libs/ui/kis_fps_decoration.h +++ b/libs/ui/kis_fps_decoration.h @@ -31,7 +31,9 @@ static const QString idTag; private: - void draw(QPainter& gc); + QSize draw(QPainter& gc); + + QPixmap m_pixmap; }; #endif /* __KIS_FPS_DECORATION_H */ diff --git a/libs/ui/kis_fps_decoration.cpp b/libs/ui/kis_fps_decoration.cpp --- a/libs/ui/kis_fps_decoration.cpp +++ b/libs/ui/kis_fps_decoration.cpp @@ -38,22 +38,33 @@ void KisFpsDecoration::drawDecoration(QPainter& gc, const QRectF& /*updateRect*/, const KisCoordinatesConverter */*converter*/, KisCanvas2* /*canvas*/) { -#ifdef Q_OS_OSX - QPixmap pixmap(320, 128); - pixmap.fill(Qt::transparent); - { - QPainter painter(&pixmap); - draw(painter); + // we always paint into a pixmap instead of directly into gc, as the latter + // approach is known to cause garbled graphics on macOS, Windows, and even + // sometimes Linux. + + for (int i = 0; i < 2; i++) { + m_pixmap.fill(Qt::transparent); + + QSize size; + { + QPainter painter(&m_pixmap); + size = draw(painter); + } + + if ((m_pixmap.width() >= size.width() && m_pixmap.height() == size.height()) || i > 0) { + break; + } + + // make it bigger than the measured text to allow for some variation. + m_pixmap = QPixmap(size.width() * 1.1, size.height()); } - gc.drawPixmap(0, 0, pixmap); -#else - draw(gc); -#endif + + gc.drawPixmap(0, 0, m_pixmap); } -void KisFpsDecoration::draw(QPainter& gc) +QSize KisFpsDecoration::draw(QPainter& gc) { QStringList lines; @@ -80,9 +91,10 @@ } + int maxWidth = 0; QPoint startPoint(20,30); - const int lineSpacing = QFontMetrics(gc.font()).lineSpacing(); - + const QFontMetrics metrics(gc.font()); + const int lineSpacing = metrics.lineSpacing(); gc.save(); @@ -91,9 +103,12 @@ gc.drawText(startPoint + QPoint(1,1), line); gc.setPen(QPen(Qt::black)); gc.drawText(startPoint, line); + maxWidth = qMax(maxWidth, metrics.boundingRect(line).right()); startPoint += QPoint(0, lineSpacing); } gc.restore(); + + return QSize(maxWidth + startPoint.x() + 1, startPoint.y() + 1); }