From 5e61bbe586519c3d9bc636153d32e810da4e59a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 20 Nov 2012 11:34:52 +0100 Subject: Basic high-dpi "retina" support for Qt 5. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring Qt 5 on par with Qt 4, prepare for more comprehensive support later on. Introduce device independent pixels (dips), device pixels, and devicePixelRatio. Add high-dpi support to QPainter, QGLWidget, the cocoa platform plugin, mac and fusion styles. Dips are similar to CSS pixels, Apple points and Android density-independent pixels. Device pixels are pixels in the backing store/physical pixels on screen. devicePixelRatio is the ratio between them, which is 1.0 on standard displays and 2.0 on "retina" displays. New API: QImage::devicePixelRatio() and setDevicePixelRatio() QPixmap::devicePixelRatio() and setDevicePixelRatio() QWindow::devicePixelRatio() QScreen::devicePixelRatio() QGuiApplicaiton::devicePixelRatio() Change-Id: If98c3ca9bfdf0e1bdbcf7574cd5b912c9ff63856 Reviewed-by: Morten Johan Sørvig Reviewed-by: Gunnar Sletta --- src/widgets/itemviews/qitemdelegate.cpp | 10 ++-- src/widgets/kernel/qwidget.cpp | 29 +++++++-- src/widgets/kernel/qwidget_p.h | 1 + src/widgets/styles/qfusionstyle.cpp | 100 +++++++++++++++++--------------- src/widgets/styles/qmacstyle_mac.mm | 32 ++++++++-- src/widgets/styles/qstyle.cpp | 5 +- src/widgets/styles/qstyle_p.h | 11 +++- src/widgets/widgets/qlabel.cpp | 9 +-- 8 files changed, 127 insertions(+), 70 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index e7ca2d0c6c..7631403933 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -1060,10 +1060,12 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option, switch (value.type()) { case QVariant::Invalid: break; - case QVariant::Pixmap: - return QRect(QPoint(0, 0), qvariant_cast(value).size()); - case QVariant::Image: - return QRect(QPoint(0, 0), qvariant_cast(value).size()); + case QVariant::Pixmap: { + const QPixmap &pixmap = qvariant_cast(value); + return QRect(QPoint(0, 0), pixmap.size() / pixmap.devicePixelRatio() ); } + case QVariant::Image: { + const QImage &image = qvariant_cast(value); + return QRect(QPoint(0, 0), image.size() / image.devicePixelRatio() ); } case QVariant::Icon: { QIcon::Mode mode = d->iconMode(option.state); QIcon::State state = d->iconState(option.state); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e167e646c0..ace25fa78b 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1794,6 +1794,23 @@ QRegion QWidgetPrivate::clipRegion() const return r; } +void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion ®ion) +{ +// Transform the system clip region from device-independent pixels to device pixels +// Qt 5.0.0: This is a Mac-only code path for now, can be made cross-platform once +// it has been tested. + QPaintEngine *paintEngine = paintDevice->paintEngine(); +#ifdef Q_OS_MAC + const qreal devicePixelRatio = (paintDevice->physicalDpiX() == 0 || paintDevice->logicalDpiX() == 0) ? + 1.0 : (paintDevice->physicalDpiX() / paintDevice->logicalDpiX()); + QTransform scaleTransform; + scaleTransform.scale(devicePixelRatio, devicePixelRatio); + paintEngine->d_func()->systemClip = scaleTransform.map(region); +#else + paintEngine->d_func()->systemClip = region; +#endif +} + #ifndef QT_NO_GRAPHICSEFFECT void QWidgetPrivate::invalidateGraphicsEffectsRecursively() { @@ -4998,13 +5015,12 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore); sourced->context = &context; if (!sharedPainter) { - QPaintEngine *paintEngine = pdev->paintEngine(); - paintEngine->d_func()->systemClip = rgn.translated(offset); + setSystemClip(pdev, rgn.translated(offset)); QPainter p(pdev); p.translate(offset); context.painter = &p; graphicsEffect->draw(&p); - paintEngine->d_func()->systemClip = QRegion(); + setSystemClip(pdev, QRegion()); } else { context.painter = sharedPainter; if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { @@ -5061,7 +5077,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP #endif if (sharedPainter) - paintEngine->d_func()->systemClip = toBePainted; + setSystemClip(pdev, toBePainted); else paintEngine->d_func()->systemRect = q->data->crect; @@ -5073,7 +5089,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP } if (!sharedPainter) - paintEngine->d_func()->systemClip = toBePainted.translated(offset); + setSystemClip(pdev, toBePainted.translated(offset)); if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) { QPainter p(q); @@ -5108,7 +5124,8 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP paintEngine->d_func()->systemRect = QRect(); else paintEngine->d_func()->currentClipDevice = 0; - paintEngine->d_func()->systemClip = QRegion(); + + setSystemClip(pdev, QRegion()); } q->setAttribute(Qt::WA_WState_InPaintEvent, false); if (q->paintingActive()) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 8aba276966..1d183e41f1 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -402,6 +402,7 @@ public: QRect clipRect() const; QRegion clipRegion() const; + void setSystemClip(QPaintDevice *paintDevice, const QRegion ®ion); void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const; void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = 0, bool alsoNonOpaque = false) const; diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index ebcdc10d59..623cdb55b9 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -303,7 +303,7 @@ static void qt_fusion_draw_mdibutton(QPainter *painter, const QStyleOptionTitleB gradient.setColorAt(1, mdiButtonGradientStopColor); QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110)); - painter->setPen(QPen(mdiButtonBorderColor, 1)); + painter->setPen(QPen(mdiButtonBorderColor)); const QLine lines[4] = { QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()), QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()), @@ -457,7 +457,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, if (const QStyleOptionTabBarBase *tbb = qstyleoption_cast(option)) { painter->save(); - painter->setPen(QPen(outline.lighter(110), 0)); + painter->setPen(QPen(outline.lighter(110))); switch (tbb->shape) { case QTabBar::RoundedNorth: { QRegion region(tbb->rect); @@ -603,7 +603,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, } } break; - case PE_Frame: + case PE_Frame: { if (widget && widget->inherits("QComboBoxPrivateContainer")){ QStyleOption copy = *option; copy.state |= State_Raised; @@ -611,14 +611,16 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, break; } painter->save(); - painter->setPen(outline.lighter(108)); + QPen thePen(outline.lighter(108)); + thePen.setCosmetic(false); + painter->setPen(thePen); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); - painter->restore(); + painter->restore(); } break; case PE_FrameMenu: painter->save(); { - painter->setPen(QPen(outline, 1)); + painter->setPen(QPen(outline)); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); QColor frameLight = option->palette.background().color().lighter(160); QColor frameShadow = option->palette.background().color().darker(110); @@ -644,9 +646,9 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, QRect rect= option->rect; painter->setPen(softshadow); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); - painter->setPen(QPen(option->palette.light(), 0)); + painter->setPen(QPen(option->palette.light(), 1)); painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1)); - painter->setPen(QPen(option->palette.background().color().darker(120), 0)); + painter->setPen(QPen(option->palette.background().color().darker(120))); painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1)); painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1)); @@ -680,12 +682,12 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->save(); { QRect rect= option->rect; - painter->setPen(QPen(outline.darker(150), 0)); + painter->setPen(QPen(outline.darker(150))); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); - painter->setPen(QPen(option->palette.light(), 0)); + painter->setPen(QPen(option->palette.light(), 1)); painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1)); - painter->setPen(QPen(option->palette.background().color().darker(120), 0)); + painter->setPen(QPen(option->palette.background().color().darker(120))); painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1)); painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), @@ -705,7 +707,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->translate(0.5, 0.5); // Draw Outline - painter->setPen( QPen(hasFocus ? highlightedOutline : outline, 0)); + painter->setPen( QPen(hasFocus ? highlightedOutline : outline)); painter->setBrush(option->palette.base()); painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2); @@ -740,10 +742,10 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, gradient.setColorAt(1, (state & State_Sunken) ? pressedColor : option->palette.base().color()); painter->setBrush((state & State_Sunken) ? QBrush(pressedColor) : gradient); - painter->setPen(QPen(outline.lighter(110), 1)); + painter->setPen(QPen(outline.lighter(110))); if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) - painter->setPen(QPen(highlightedOutline, 1)); + painter->setPen(QPen(highlightedOutline)); painter->drawRect(rect); QColor checkMarkColor = option->palette.text().color().darker(120); @@ -785,9 +787,9 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->setRenderHint(QPainter::Antialiasing, true); QPainterPath circle; circle.addEllipse(rect.center() + QPoint(1.0, 1.0), 6.5, 6.5); - painter->setPen(QPen(option->palette.background().color().darker(150), 1)); + painter->setPen(QPen(option->palette.background().color().darker(150))); if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) - painter->setPen(QPen(highlightedOutline, 1)); + painter->setPen(QPen(highlightedOutline)); painter->drawPath(circle); if (state & (State_On )) { @@ -862,7 +864,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, if (isFlat && !isDown) { if (isDefault) { r = option->rect.adjusted(0, 1, 0, -1); - painter->setPen(QPen(Qt::black, 0)); + painter->setPen(QPen(Qt::black)); const QLine lines[4] = { QLine(QPoint(r.left() + 2, r.top()), QPoint(r.right() - 2, r.top())), @@ -910,7 +912,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, p->setBrush(Qt::NoBrush); // Outline - p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline, 1)); + p->setPen(!isEnabled ? QPen(darkOutline.lighter(115)) : QPen(darkOutline)); p->drawRoundedRect(r, 2.0, 2.0); p->setPen(d->innerContrastLine()); @@ -1300,7 +1302,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio painter->drawLine(rect.topLeft() - QPoint(0, 1), rect.topRight() - QPoint(0, 1)); painter->setBrush(option->palette.base()); - painter->setPen(QPen(outline, 0)); + painter->setPen(QPen(outline)); painter->drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2); // Inner shadow @@ -1359,14 +1361,14 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio progressBar.setRect(rect.left(), rect.top(), width - 1, rect.height() - 1); if (!complete) { painter->drawLine(progressBar.topRight() + QPoint(2, 1), progressBar.bottomRight() + QPoint(2, 0)); - painter->setPen(QPen(highlight.darker(140), 0)); + painter->setPen(QPen(highlight.darker(140))); painter->drawLine(progressBar.topRight() + QPoint(1, 1), progressBar.bottomRight() + QPoint(1, 0)); } } else { progressBar.setRect(rect.right() - width - 1, rect.top(), width + 2, rect.height() - 1); if (!complete) { painter->drawLine(progressBar.topLeft() + QPoint(-2, 1), progressBar.bottomLeft() + QPoint(-2, 0)); - painter->setPen(QPen(highlight.darker(140), 0)); + painter->setPen(QPen(highlight.darker(140))); painter->drawLine(progressBar.topLeft() + QPoint(-1, 1), progressBar.bottomLeft() + QPoint(-1, 0)); } } @@ -1376,7 +1378,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio if (indeterminate || bar->progress > bar->minimum) { - painter->setPen(QPen(outline, 0)); + painter->setPen(QPen(outline)); QColor highlightedGradientStartColor = highlight.lighter(120); QColor highlightedGradientStopColor = highlight; @@ -1471,7 +1473,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio QRect r = option->rect; if (act) { painter->setBrush(option->palette.highlight().color()); - painter->setPen(QPen(highlightOutline, 0)); + painter->setPen(QPen(highlightOutline)); painter->drawRect(r.adjusted(0, 0, -1, -1)); // painter->drawRoundedRect(r.adjusted(1, 1, -1, -1), 2, 2); @@ -1518,7 +1520,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio if (selected) { QRect r = option->rect; painter->fillRect(r, highlight); - painter->setPen(QPen(highlightOutline, 0)); + painter->setPen(QPen(highlightOutline)); const QLine lines[4] = { QLine(QPoint(r.left() + 1, r.bottom()), QPoint(r.right() - 1, r.bottom())), QLine(QPoint(r.left() + 1, r.top()), QPoint(r.right() - 1, r.top())), @@ -2141,15 +2143,18 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QPixmap upArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), (spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled) ? arrowColor : disabledColor); - cachePainter.drawPixmap(QRect(upRect.center().x() - upArrow.width() / 4 + 1, - upRect.center().y() - upArrow.height() / 4 + 1, - upArrow.width()/2, upArrow.height()/2), upArrow); + QRectF upArrowRect = QRectF(upRect.center().x() - upArrow.width() / 4.0 + 1.0, + upRect.center().y() - upArrow.height() / 4.0 + 1.0, + upArrow.width() / 2.0, upArrow.height() / 2.0); + + cachePainter.drawPixmap(upArrowRect, upArrow, QRectF(QPointF(0.0, 0.0), upArrow.size())); QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), (spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled) ? arrowColor : disabledColor, 180); - cachePainter.drawPixmap(QRect(downRect.center().x() - downArrow.width() / 4 + 1, - downRect.center().y() - downArrow.height() / 4 + 1, - downArrow.width()/2, downArrow.height()/2), downArrow); + QRectF downArrowRect = QRectF(downRect.center().x() - downArrow.width() / 4.0 + 1.0, + downRect.center().y() - downArrow.height() / 4.0 + 1.0, + downArrow.width() / 2.0, downArrow.height() / 2.0); + cachePainter.drawPixmap(downArrowRect, downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size())); } cachePainter.end(); @@ -2486,7 +2491,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption // Paint slider if (scrollBar->subControls & SC_ScrollBarSlider) { QRect pixmapRect = scrollBarSlider; - painter->setPen(QPen(alphaOutline, 0)); + painter->setPen(QPen(alphaOutline)); if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider) painter->setBrush(midColor2); else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider) @@ -2521,7 +2526,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption painter->setPen(Qt::NoPen); painter->drawRect(scrollBarSubLine.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, 0, 0)); - painter->setPen(QPen(alphaOutline, 1)); + painter->setPen(QPen(alphaOutline)); if (option->state & State_Horizontal) { if (option->direction == Qt::RightToLeft) { pixmapRect.setLeft(scrollBarSubLine.left()); @@ -2545,9 +2550,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption rotation = option->direction == Qt::LeftToRight ? -90 : 90; QRect upRect = scrollBarSubLine.translated(horizontal ? -2 : -1, 0); QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation); - painter->drawPixmap(QRect(upRect.center().x() - arrowPixmap.width() / 4 + 2, - upRect.center().y() - arrowPixmap.height() / 4 + 1, - arrowPixmap.width()/2, arrowPixmap.height()/2), arrowPixmap); + painter->drawPixmap(QRectF(upRect.center().x() - arrowPixmap.width() / 4.0 + 2.0, + upRect.center().y() - arrowPixmap.height() / 4.0 + 1.0, + arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0), + arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size())); } // The AddLine (down/right) button @@ -2584,9 +2590,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption rotation = option->direction == Qt::LeftToRight ? 90 : -90; QRect downRect = scrollBarAddLine.translated(-1, 1); QPixmap arrowPixmap = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, rotation); - painter->drawPixmap(QRect(downRect.center().x() - arrowPixmap.width() / 4 + 2, - downRect.center().y() - arrowPixmap.height() / 4, - arrowPixmap.width()/2, arrowPixmap.height()/2), arrowPixmap); + painter->drawPixmap(QRectF(downRect.center().x() - arrowPixmap.width() / 4.0 + 2.0, + downRect.center().y() - arrowPixmap.height() / 4.0, + arrowPixmap.width() / 2.0, arrowPixmap.height() / 2.0), + arrowPixmap, QRectF(QPoint(0.0, 0.0), arrowPixmap.size())); } } @@ -2640,7 +2647,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption downArrowRect.left() - 6: downArrowRect.right() + 6); proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, &cachePainter, widget); cachePainter.restore(); - cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 0)); + cachePainter.setPen( QPen(hasFocus ? option->palette.highlight() : outline.lighter(110), 1)); if (!sunken) { int borderSize = 1; @@ -2677,9 +2684,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QColor arrowColor = option->palette.buttonText().color(); arrowColor.setAlpha(220); QPixmap downArrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180); - cachePainter.drawPixmap(QRect(downArrowRect.center().x() - downArrow.width() / 4 + 1, - downArrowRect.center().y() - downArrow.height() / 4 + 1, - downArrow.width()/2, downArrow.height()/2), downArrow); + cachePainter.drawPixmap(QRectF(downArrowRect.center().x() - downArrow.width() / 4.0 + 1.0, + downArrowRect.center().y() - downArrow.height() / 4.0 + 1.0, + downArrow.width() / 2.0, downArrow.height() / 2.0), + downArrow, QRectF(QPointF(0.0, 0.0), downArrow.size())); } cachePainter.end(); QPixmapCache::insert(pixmapName, cache); @@ -2730,7 +2738,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption gradient.setStart(pixmapRect.left(), pixmapRect.center().y()); gradient.setFinalStop(pixmapRect.right(), pixmapRect.center().y()); } - groovePainter.setPen(QPen(outline, 0)); + groovePainter.setPen(QPen(outline)); gradient.setColorAt(0, grooveColor.darker(110)); gradient.setColorAt(1, grooveColor.lighter(110));//palette.button().color().darker(115)); groovePainter.setBrush(gradient); @@ -2764,7 +2772,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption groovePainter.setRenderHint(QPainter::Antialiasing, true); groovePainter.translate(0.5, 0.5); - groovePainter.setPen(QPen(outline, 0)); + groovePainter.setPen(QPen(outline)); gradient.setColorAt(0, activeHighlight); gradient.setColorAt(1, activeHighlight.lighter(130)); groovePainter.setBrush(gradient); @@ -2813,9 +2821,9 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption handlePainter.setBrush(QColor(0, 0, 0, 40)); handlePainter.drawRect(r.adjusted(-1, 2, 1, -2)); - handlePainter.setPen(QPen(d->outline(option->palette), 1)); + handlePainter.setPen(QPen(d->outline(option->palette))); if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) - handlePainter.setPen(QPen(d->highlightedOutline(option->palette), 1)); + handlePainter.setPen(QPen(d->highlightedOutline(option->palette))); handlePainter.setBrush(gradient); handlePainter.drawRoundedRect(r, 2, 2); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 759b3678d7..89ea4d553a 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -462,7 +462,7 @@ class QMacCGContext { CGContextRef context; public: - QMacCGContext(QPainter *p); //qpaintengine_mac.cpp + QMacCGContext(QPainter *p); inline QMacCGContext() { context = 0; } inline QMacCGContext(const QPaintDevice *pdev) { extern CGContextRef qt_mac_cg_context(const QPaintDevice *); @@ -6476,6 +6476,18 @@ void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig } } +// move to QRegion? +void qt_mac_scale_region(QRegion *region, qreal scaleFactor) +{ + QVector scaledRects; + scaledRects.reserve(region->rects().count()); + + foreach (const QRect &rect, region->rects()) { + scaledRects.append(QRect(rect.topLeft(), rect.size() * scaleFactor)); + } + region->setRects(&scaledRects[0], scaledRects.count()); +} + QMacCGContext::QMacCGContext(QPainter *p) { QPaintEngine *pe = p->paintEngine(); @@ -6502,20 +6514,28 @@ QMacCGContext::QMacCGContext(QPainter *p) CGContextScaleCTM(context, 1, -1); if (devType == QInternal::Widget) { - QRegion clip = p->paintEngine()->systemClip(); - QTransform native = p->deviceTransform(); + // Set the clip rect which is an intersection of the system clip + // and the painter clip. To make matters more interesting these + // are in device pixels and device-independent pixels, respectively. + const qreal devicePixelRatio = image->devicePixelRatio(); + + QRegion clip = p->paintEngine()->systemClip(); // get system clip in device pixels + QTransform native = p->deviceTransform(); // get device transform. dx/dy is in device pixels if (p->hasClipping()) { - QRegion r = p->clipRegion(); + QRegion r = p->clipRegion(); // get painter clip, which is in device-independent pixels + qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels r.translate(native.dx(), native.dy()); if (clip.isEmpty()) clip = r; else clip &= r; } - qt_mac_clip_cg(context, clip, 0); + qt_mac_clip_cg(context, clip, 0); // clip in device pixels - CGContextTranslateCTM(context, native.dx(), native.dy()); + // Scale the context so that painting happens in device-independet pixels. + CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); + CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio); } } else { qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 76d6efadee..ab66cdae9f 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -618,10 +618,11 @@ void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, c void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const { - QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size(), rect); + int scale = pixmap.devicePixelRatio(); + QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size() / scale, rect); QRect inter = aligned.intersected(rect); - painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height()); + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width() * scale, inter.height() *scale); } /*! diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h index 85e8e54b16..78dfc6fed9 100644 --- a/src/widgets/styles/qstyle_p.h +++ b/src/widgets/styles/qstyle_p.h @@ -43,6 +43,7 @@ #define QSTYLE_P_H #include "private/qobject_p.h" +#include #include QT_BEGIN_NAMESPACE @@ -74,12 +75,18 @@ public: inline QImage styleCacheImage(const QSize &size) { - return QImage(size, QImage::Format_ARGB32_Premultiplied); + const qreal pixelRatio = qApp->devicePixelRatio(); + QImage cacheImage = QImage(size * pixelRatio, QImage::Format_ARGB32_Premultiplied); + cacheImage.setDevicePixelRatio(pixelRatio); + return cacheImage; } inline QPixmap styleCachePixmap(const QSize &size) { - return QPixmap(size); + const qreal pixelRatio = qApp->devicePixelRatio(); + QPixmap cachePixmap = QPixmap(size * pixelRatio); + cachePixmap.setDevicePixelRatio(pixelRatio); + return cachePixmap; } #define BEGIN_STYLE_PIXMAPCACHE(a) \ diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index a133b9c310..3b3d15f6d0 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -562,17 +562,18 @@ QSize QLabelPrivate::sizeForWidth(int w) const int vextra = hextra; QFontMetrics fm = q->fontMetrics(); - if (pixmap && !pixmap->isNull()) + if (pixmap && !pixmap->isNull()) { br = pixmap->rect(); + br.setSize(br.size() / pixmap->devicePixelRatio()); #ifndef QT_NO_PICTURE - else if (picture && !picture->isNull()) + } else if (picture && !picture->isNull()) { br = picture->boundingRect(); #endif #ifndef QT_NO_MOVIE - else if (movie && !movie->currentPixmap().isNull()) + } else if (movie && !movie->currentPixmap().isNull()) { br = movie->currentPixmap().rect(); #endif - else if (isTextLabel) { + } else if (isTextLabel) { int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); // Add indentation int m = indent; -- cgit v1.2.3