From b213d5bfa3a8ed81077cd8eaf229764ff2f1b346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 15 Oct 2012 17:06:34 +0200 Subject: [PATCH] Make QPen default to 1-width non-cosmetic. Use the Qt4CompatiblePainting render hint when painting with QPainter to treat default constructed QPens as cosmetic still. The NonCosmeticDefaultPen render hint gets documented as obsolete, since it was in any case not respected by the raster nor OpenGL paint engine. Change-Id: I04d910e9700baf7f13a8aac07a3633014bb9283e Reviewed-by: Jens Bache-Wiig --- dist/changes-5.0.0 | 5 ++ src/gui/opengl/qopenglpaintengine.cpp | 13 ++--- src/gui/opengl/qtriangulatingstroker.cpp | 8 +-- src/gui/opengl/qtriangulatingstroker_p.h | 4 +- src/gui/painting/qcosmeticstroker.cpp | 2 +- src/gui/painting/qpaintbuffer.cpp | 2 +- src/gui/painting/qpaintengine.cpp | 2 +- src/gui/painting/qpaintengine_raster.cpp | 9 ++-- src/gui/painting/qpaintengineex.cpp | 4 +- src/gui/painting/qpainter.cpp | 51 +++++------------- src/gui/painting/qpainter_p.h | 9 ++-- src/gui/painting/qpdf.cpp | 9 ++-- src/gui/painting/qpdf_p.h | 2 +- src/gui/painting/qpen.cpp | 44 +++++++++------ src/gui/painting/qpen_p.h | 3 +- .../qpaintengineex_opengl2.cpp | 10 ++-- .../platforms/cocoa/qpaintengine_mac.mm | 4 +- .../kernel/qpaintengine_alpha.cpp | 8 ++- src/printsupport/kernel/qprintengine_win.cpp | 13 +++-- src/widgets/graphicsview/qgraphicsitem.cpp | 10 ++-- .../graphicsview/qgraphicsproxywidget.cpp | 10 ---- src/widgets/graphicsview/qgraphicswidget.cpp | 1 - .../gui/painting/qpainter/tst_qpainter.cpp | 1 + .../qpathclipper/tst_qpathclipper.cpp | 4 +- tests/auto/gui/painting/qpen/tst_qpen.cpp | 4 +- .../qgraphicseffect/tst_qgraphicseffect.cpp | 4 ++ .../qgraphicsitem/tst_qgraphicsitem.cpp | 42 ++++++++++++++- .../tst_qgraphicspolygonitem.cpp | 2 + .../qgraphicsscene/tst_qgraphicsscene.cpp | 35 ++++++++---- .../tst_qgraphicssceneindex.cpp | 2 +- .../qgraphicsview/tst_qgraphicsview.cpp | 54 ++++++++++++------- 31 files changed, 224 insertions(+), 147 deletions(-) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 5c9d5147c41..e42c5660f49 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -519,6 +519,11 @@ QtGui rectangle filling. It's possible to still get the old behavior by setting the QPainter::Qt4CompatiblePainting render hint. +* Behavioral change regarding QPen: The default QPen constructors now create a + 1-width non-cosmetic pen as opposed to a 0-width cosmetic pen. The old + behavior can be emulated by setting the QPainter::Qt4CompatiblePainting + render hint when painting. + QtWidgets --------- * QInputContext removed as well as related getters and setters on QWidget and QApplication. diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index e0f1fe50a65..8e967207d49 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1194,7 +1194,7 @@ void QOpenGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) return; QOpenGL2PaintEngineState *s = state(); - if (pen.isCosmetic() && !qt_scaleForTransform(s->transform(), 0)) { + if (qt_pen_is_cosmetic(pen, state()->renderHints) && !qt_scaleForTransform(s->transform(), 0)) { // QTriangulatingStroker class is not meant to support cosmetically sheared strokes. QPaintEngineEx::stroke(path, pen); return; @@ -1229,15 +1229,16 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p : QRectF(0, 0, width, height)); if (penStyle == Qt::SolidLine) { - stroker.process(path, pen, clip); + stroker.process(path, pen, clip, s->renderHints); } else { // Some sort of dash - dasher.process(path, pen, clip); + dasher.process(path, pen, clip, s->renderHints); QVectorPath dashStroke(dasher.points(), dasher.elementCount(), - dasher.elementTypes()); - stroker.process(dashStroke, pen, clip); + dasher.elementTypes(), + s->renderHints); + stroker.process(dashStroke, pen, clip, s->renderHints); } if (!stroker.vertexCount()) @@ -1261,7 +1262,7 @@ void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &p ? qMax(pen.miterLimit() * width, width) : width; - if (pen.isCosmetic()) + if (qt_pen_is_cosmetic(pen, q->state()->renderHints)) extra = extra * inverseScale; QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); diff --git a/src/gui/opengl/qtriangulatingstroker.cpp b/src/gui/opengl/qtriangulatingstroker.cpp index 0be6e12721f..6c8ab7d607f 100644 --- a/src/gui/opengl/qtriangulatingstroker.cpp +++ b/src/gui/opengl/qtriangulatingstroker.cpp @@ -81,7 +81,7 @@ static inline void skipDuplicatePoints(const qreal **pts, const qreal *endPts) } } -void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &) +void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &, QPainter::RenderHints hints) { const qreal *pts = path.points(); const QPainterPath::ElementType *types = path.elements(); @@ -95,7 +95,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co m_width = realWidth / 2; - bool cosmetic = pen.isCosmetic(); + bool cosmetic = qt_pen_is_cosmetic(pen, hints); if (cosmetic) { m_width = m_width * m_inv_scale; } @@ -519,14 +519,14 @@ QDashedStrokeProcessor::QDashedStrokeProcessor() m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo); } -void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip) +void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints) { const qreal *pts = path.points(); const QPainterPath::ElementType *types = path.elements(); int count = path.elementCount(); - bool cosmetic = pen.isCosmetic(); + bool cosmetic = qt_pen_is_cosmetic(pen, hints); m_points.reset(); m_types.reset(); diff --git a/src/gui/opengl/qtriangulatingstroker_p.h b/src/gui/opengl/qtriangulatingstroker_p.h index 295ddbab5aa..ba21c0820f3 100644 --- a/src/gui/opengl/qtriangulatingstroker_p.h +++ b/src/gui/opengl/qtriangulatingstroker_p.h @@ -55,7 +55,7 @@ class Q_GUI_EXPORT QTriangulatingStroker { public: QTriangulatingStroker() : m_vertices(0) {} - void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints); inline int vertexCount() const { return m_vertices.size(); } inline const float *vertices() const { return m_vertices.data(); } @@ -97,7 +97,7 @@ class Q_GUI_EXPORT QDashedStrokeProcessor public: QDashedStrokeProcessor(); - void process(const QVectorPath &path, const QPen &pen, const QRectF &clip); + void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints); inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) { m_points.add(x); diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 2eab7b25c50..7fcab1f0877 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -275,7 +275,7 @@ void QCosmeticStroker::setup() qreal width = state->lastPen.widthF(); if (width == 0) opacity = 256; - else if (state->lastPen.isCosmetic()) + else if (qt_pen_is_cosmetic(state->lastPen, state->renderHints)) opacity = (int) 256*width; else opacity = (int) 256*width*state->txscale; diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 1e5a00e8359..d7b16114b8a 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -680,7 +680,7 @@ void QPaintBufferEngine::penChanged() } else { qreal penWidth = (pen.widthF() == 0) ? 1 : pen.widthF(); QPointF transformedWidth(penWidth, penWidth); - if (!pen.isCosmetic()) + if (!qt_pen_is_cosmetic(pen, state()->renderHints)) transformedWidth = painter()->transform().map(transformedWidth); buffer->penWidthAdjustment = transformedWidth.x() / 2.0; } diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 09b1f0a8e41..339421f5e21 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -445,7 +445,7 @@ void QPaintEngine::drawPoints(const QPointF *points, int pointCount) p->save(); QTransform transform; - if (p->pen().isCosmetic()) { + if (qt_pen_is_cosmetic(p->pen(), p->renderHints())) { transform = p->transform(); p->setTransform(QTransform()); } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e0eab8dc73d..1a63ced8976 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -771,7 +771,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen) } else if (pen_style != Qt::NoPen) { if (!d->dashStroker) d->dashStroker.reset(new QDashStroker(&d->basicStroker)); - if (pen.isCosmetic()) { + if (qt_pen_is_cosmetic(pen, s->renderHints)) { d->dashStroker->setClipRect(d->deviceRect); } else { // ### I've seen this inverted devrect multiple places now... @@ -786,10 +786,11 @@ void QRasterPaintEngine::updatePen(const QPen &pen) } ensureRasterState(); // needed because of tx_noshear... + bool cosmetic = qt_pen_is_cosmetic(pen, s->renderHints); s->flags.fast_pen = pen_style > Qt::NoPen && s->penData.blend - && ((pen.isCosmetic() && penWidth <= 1) - || (!pen.isCosmetic() && s->flags.tx_noshear && penWidth * s->txscale <= 1)); + && ((cosmetic && penWidth <= 1) + || (!cosmetic && s->flags.tx_noshear && penWidth * s->txscale <= 1)); s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear; @@ -1610,7 +1611,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding); stroker.drawPath(path); } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) { - qreal width = s->lastPen.isCosmetic() + qreal width = qt_pen_is_cosmetic(s->lastPen, s->renderHints) ? (qpen_widthf(s->lastPen) == 0 ? 1 : qpen_widthf(s->lastPen)) : qpen_widthf(s->lastPen) * s->txscale; int dashIndex = 0; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index dd93a586355..113cbd8a8ec 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -435,7 +435,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } if (pen.style() > Qt::SolidLine) { - if (pen.isCosmetic()) { + if (qt_pen_is_cosmetic(pen, state()->renderHints)){ d->activeStroker->setClipRect(d->exDeviceRect); } else { QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); @@ -462,7 +462,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) flags |= QVectorPath::CurvedShapeMask; // ### Perspective Xforms are currently not supported... - if (!pen.isCosmetic()) { + if (!qt_pen_is_cosmetic(pen, state()->renderHints)) { // We include cosmetic pens in this case to avoid having to // change the current transform. Normal transformed, // non-cosmetic pens will be transformed as part of fill diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 69267b259b6..090faf15aa9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -897,26 +897,8 @@ void QPainterPrivate::updateState(QPainterState *newState) if (!newState) { engine->state = newState; - } else if (newState->state() || engine->state!=newState) { - bool setNonCosmeticPen = (newState->renderHints & QPainter::NonCosmeticDefaultPen) - && newState->pen.widthF() == 0; - if (setNonCosmeticPen) { - // Override the default pen's cosmetic state if the - // NonCosmeticDefaultPen render hint is used. - QPen oldPen = newState->pen; - newState->pen.setWidth(1); - newState->pen.setCosmetic(false); - newState->dirtyFlags |= QPaintEngine::DirtyPen; - - updateStateImpl(newState); - - // Restore the state pen back to its default to preserve visible - // state. - newState->pen = oldPen; - } else { - updateStateImpl(newState); - } + updateStateImpl(newState); } } @@ -1417,14 +1399,13 @@ void QPainterPrivate::updateState(QPainterState *newState) indicating that the engine should use fragment programs and offscreen rendering for antialiasing. - \value NonCosmeticDefaultPen The engine should interpret pens with a width - of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic - pen with a width of 1. + \value NonCosmeticDefaultPen This value is obsolete, the default for QPen + is now non-cosmetic. \value Qt4CompatiblePainting Compatibility hint telling the engine to use the same X11 based fill rules as in Qt 4, where aliased rendering is offset - by slightly less than half a pixel. Potentially useful when porting a - Qt 4 application to Qt 5. + by slightly less than half a pixel. Also will treat default constructed pens + as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5. \sa renderHints(), setRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}, {Concentric Circles Example} @@ -3849,13 +3830,10 @@ void QPainter::setPen(const QColor &color) return; } - if (d->state->pen.style() == Qt::SolidLine - && d->state->pen.widthF() == 0 - && d->state->pen.isSolid() - && d->state->pen.color() == color) - return; + QPen pen(color.isValid() ? color : QColor(Qt::black)); - QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine); + if (d->state->pen == pen) + return; d->state->pen = pen; if (d->extended) @@ -3904,7 +3882,7 @@ void QPainter::setPen(const QPen &pen) /*! \overload - Sets the painter's pen to have the given \a style, width 0 and + Sets the painter's pen to have the given \a style, width 1 and black color. */ @@ -3916,15 +3894,12 @@ void QPainter::setPen(Qt::PenStyle style) return; } - if (d->state->pen.style() == style - && (style == Qt::NoPen || (d->state->pen.widthF() == 0 - && d->state->pen.isSolid() - && d->state->pen.color() == QColor(Qt::black)))) + QPen pen = QPen(style); + + if (d->state->pen == pen) return; - // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color) - // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen - d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style); + d->state->pen = pen; if (d->extended) d->extended->penChanged(); diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 6ad1cb07cc3..0e46cee4b5d 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -241,10 +241,6 @@ public: void updateMatrix(); void updateInvMatrix(); - int rectSubtraction() const { - return state->pen.style() != Qt::NoPen && state->pen.width() == 0 ? 1 : 0; - } - void checkEmulation(); static QPainterPrivate *get(QPainter *painter) @@ -269,6 +265,11 @@ Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, Q QString qt_generate_brush_key(const QBrush &brush); +inline bool qt_pen_is_cosmetic(const QPen &pen, QPainter::RenderHints hints) +{ + return pen.isCosmetic() || (const_cast(pen).data_ptr()->defaultWidth && (hints & QPainter::Qt4CompatiblePainting)); +} + QT_END_NAMESPACE #endif // QPAINTER_P_H diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index d2aa938aed8..1d07d44dd84 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include "private/qfont_p.h" #include @@ -784,7 +785,7 @@ QPdf::Stroker::Stroker() basicStroker.setStrokeWidth(.1); } -void QPdf::Stroker::setPen(const QPen &pen) +void QPdf::Stroker::setPen(const QPen &pen, QPainter::RenderHints hints) { if (pen.style() == Qt::NoPen) { stroker = 0; @@ -792,7 +793,7 @@ void QPdf::Stroker::setPen(const QPen &pen) } qreal w = pen.widthF(); bool zeroWidth = w < 0.0001; - cosmeticPen = pen.isCosmetic(); + cosmeticPen = qt_pen_is_cosmetic(pen, hints); if (zeroWidth) w = .1; @@ -1198,12 +1199,14 @@ void QPdfEngine::updateState(const QPaintEngineState &state) if (flags & DirtyPen) { d->pen = state.pen(); d->hasPen = d->pen.style() != Qt::NoPen; - d->stroker.setPen(d->pen); + d->stroker.setPen(d->pen, state.renderHints()); QBrush penBrush = d->pen.brush(); bool oldSimple = d->simplePen; d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque()); if (oldSimple != d->simplePen) flags |= DirtyTransform; + } else if (flags & DirtyHints) { + d->stroker.setPen(d->pen, state.renderHints()); } if (flags & DirtyBrush) { d->brush = state.brush(); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index ba86803288d..735c5d13e04 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -124,7 +124,7 @@ namespace QPdf { struct Stroker { Stroker(); - void setPen(const QPen &pen); + void setPen(const QPen &pen, QPainter::RenderHints hints); void strokePath(const QPainterPath &path); ByteStream *stream; bool first; diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index d86a5f03921..6b71c3818fe 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -86,7 +86,7 @@ typedef QPenPrivate QPenData; \snippet code/src_gui_painting_qpen.cpp 1 - The default pen is a solid black brush with 0 width, square + The default pen is a solid black brush with 1 width, square cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin). In addition QPen provides the color() and setColor() @@ -230,9 +230,9 @@ typedef QPenPrivate QPenData; \internal */ inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle, - Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle) + Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle, bool _defaultWidth) : ref(1), dashOffset(0), miterLimit(2), - cosmetic(false) + cosmetic(false), defaultWidth(_defaultWidth) { width = _width; brush = _brush; @@ -261,12 +261,12 @@ public: }; Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance, - (Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join)) + (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join)) Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance, - (Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join)) + (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join)) /*! - Constructs a default black solid line pen with 0 width. + Constructs a default black solid line pen with 1 width. */ QPen::QPen() @@ -276,7 +276,7 @@ QPen::QPen() } /*! - Constructs a black pen with 0 width and the given \a style. + Constructs a black pen with 1 width and the given \a style. \sa setStyle() */ @@ -287,20 +287,20 @@ QPen::QPen(Qt::PenStyle style) d = nullPenInstance()->pen; d->ref.ref(); } else { - d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join); + d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join); } } /*! - Constructs a solid line pen with 0 width and the given \a color. + Constructs a solid line pen with 1 width and the given \a color. \sa setBrush(), setColor() */ QPen::QPen(const QColor &color) { - d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join); + d = new QPenData(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join); } @@ -315,7 +315,7 @@ QPen::QPen(const QColor &color) QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j) { - d = new QPenData(brush, width, s, c, j); + d = new QPenData(brush, width, s, c, j, false); } /*! @@ -655,12 +655,15 @@ void QPen::setWidth(int width) void QPen::setWidthF(qreal width) { - if (width < 0.f) + if (width < 0.f) { qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined"); + return; + } if (qAbs(d->width - width) < 0.00000001f) return; detach(); d->width = width; + d->defaultWidth = false; } @@ -785,8 +788,7 @@ bool QPen::isSolid() const used with. Drawing a shape with a cosmetic pen ensures that its outline will have the same thickness at different scale factors. - A zero width pen is cosmetic by default; pens with a non-zero width - are non-cosmetic. + A zero width pen is cosmetic by default. \sa setCosmetic(), widthF() */ @@ -848,7 +850,8 @@ bool QPen::operator==(const QPen &p) const || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) && pdd->dashPattern == dd->dashPattern)) && p.d->brush == d->brush - && pdd->cosmetic == dd->cosmetic); + && pdd->cosmetic == dd->cosmetic + && pdd->defaultWidth == dd->defaultWidth); } @@ -910,6 +913,8 @@ QDataStream &operator<<(QDataStream &s, const QPen &p) } if (s.version() >= 9) s << double(p.dashOffset()); + if (s.version() >= QDataStream::Qt_5_0) + s << bool(dd->defaultWidth); } return s; } @@ -935,6 +940,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p) QVector dashPattern; double dashOffset = 0; bool cosmetic = false; + bool defaultWidth = false; if (s.version() < QDataStream::Qt_4_3) { quint8 style8; s >> style8; @@ -967,6 +973,13 @@ QDataStream &operator>>(QDataStream &s, QPen &p) s >> dashOffset; } + if (s.version() >= QDataStream::Qt_5_0) { + s >> defaultWidth; + } else { + // best we can do for legacy pens + defaultWidth = qFuzzyIsNull(width); + } + p.detach(); QPenData *dd = static_cast(p.d); dd->width = width; @@ -978,6 +991,7 @@ QDataStream &operator>>(QDataStream &s, QPen &p) dd->miterLimit = miterLimit; dd->dashOffset = dashOffset; dd->cosmetic = cosmetic; + dd->defaultWidth = defaultWidth; return s; } diff --git a/src/gui/painting/qpen_p.h b/src/gui/painting/qpen_p.h index 93f2532e639..4b2fcaa71dd 100644 --- a/src/gui/painting/qpen_p.h +++ b/src/gui/painting/qpen_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QPenPrivate { public: QPenPrivate(const QBrush &brush, qreal width, Qt::PenStyle, Qt::PenCapStyle, - Qt::PenJoinStyle _joinStyle); + Qt::PenJoinStyle _joinStyle, bool defaultWidth = true); QAtomicInt ref; qreal width; QBrush brush; @@ -71,6 +71,7 @@ public: qreal dashOffset; qreal miterLimit; uint cosmetic : 1; + uint defaultWidth : 1; // default-constructed width? used for cosmetic pen compatibility }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 7c47f3b3eb4..e5423976637 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1201,7 +1201,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) return; QOpenGL2PaintEngineState *s = state(); - if (pen.isCosmetic() && !qt_scaleForTransform(s->transform(), 0)) { + if (qt_pen_is_cosmetic(pen, s->renderHints) && !qt_scaleForTransform(s->transform(), 0)) { // QTriangulatingStroker class is not meant to support cosmetically sheared strokes. QPaintEngineEx::stroke(path, pen); return; @@ -1236,15 +1236,15 @@ void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) : QRectF(0, 0, width, height)); if (penStyle == Qt::SolidLine) { - stroker.process(path, pen, clip); + stroker.process(path, pen, clip, s->renderHints); } else { // Some sort of dash - dasher.process(path, pen, clip); + dasher.process(path, pen, clip, s->renderHints); QVectorPath dashStroke(dasher.points(), dasher.elementCount(), dasher.elementTypes()); - stroker.process(dashStroke, pen, clip); + stroker.process(dashStroke, pen, clip, s->renderHints); } if (!stroker.vertexCount()) @@ -1268,7 +1268,7 @@ void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) ? qMax(pen.miterLimit() * width, width) : width; - if (pen.isCosmetic()) + if (qt_pen_is_cosmetic(pen, s->renderHints)) extra = extra * inverseScale; QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 8c475276489..404c03dd303 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -717,8 +717,8 @@ QCoreGraphicsPaintEngine::updateState(const QPaintEngineState &state) if (flags & DirtyCompositionMode) updateCompositionMode(state.compositionMode()); - if (flags & (DirtyPen | DirtyTransform)) { - if (!d->current.pen.isCosmetic()) { + if (flags & (DirtyPen | DirtyTransform | DirtyHints)) { + if (!qt_pen_is_cosmetic(d->current.pen, state.renderHints())) { d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticNone; } else if (d->current.transform.m11() < d->current.transform.m22()-1.0 || d->current.transform.m11() > d->current.transform.m22()+1.0) { diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index e3312f2db77..387e87766b9 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -45,6 +45,7 @@ #include #include "private/qpaintengine_alpha_p.h" +#include "private/qpainter_p.h" #include "private/qpicture_p.h" #include "private/qfont_p.h" #include "QtGui/qpicture.h" @@ -384,11 +385,14 @@ QAlphaPaintEnginePrivate::~QAlphaPaintEnginePrivate() QRectF QAlphaPaintEnginePrivate::addPenWidth(const QPainterPath &path) { + Q_Q(QAlphaPaintEngine); + QPainterPath tmp = path; if (m_pen.style() == Qt::NoPen) return (path.controlPointRect() * m_transform).boundingRect(); - if (m_pen.isCosmetic()) + bool cosmetic = qt_pen_is_cosmetic(m_pen, q->state->renderHints()); + if (cosmetic) tmp = path * m_transform; QPainterPathStroker stroker; @@ -399,7 +403,7 @@ QRectF QAlphaPaintEnginePrivate::addPenWidth(const QPainterPath &path) stroker.setJoinStyle(m_pen.joinStyle()); stroker.setCapStyle(m_pen.capStyle()); tmp = stroker.createStroke(tmp); - if (m_pen.isCosmetic()) + if (cosmetic) return tmp.controlPointRect(); return (tmp.controlPointRect() * m_transform).boundingRect(); diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 27351dee483..28e0363d6e1 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -852,6 +852,8 @@ void QWin32PrintEnginePrivate::fillPath_dev(const QPainterPath &path, const QCol void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QColor &color, qreal penWidth) { + Q_Q(QWin32PrintEngine); + composeGdiPath(path); LOGBRUSH brush; brush.lbStyle = BS_SOLID; @@ -868,7 +870,9 @@ void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QC else if (pen.joinStyle() == Qt::RoundJoin) joinStyle = PS_JOIN_ROUND; - HPEN pen = ExtCreatePen(((penWidth == 0) ? PS_COSMETIC : PS_GEOMETRIC) + bool cosmetic = qt_pen_is_cosmetic(pen, q->state->renderHints()); + + HPEN pen = ExtCreatePen((cosmetic ? PS_COSMETIC : PS_GEOMETRIC) | PS_SOLID | capStyle | joinStyle, (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); @@ -885,6 +889,8 @@ void QWin32PrintEnginePrivate::fillPath(const QPainterPath &path, const QColor & void QWin32PrintEnginePrivate::strokePath(const QPainterPath &path, const QColor &color) { + Q_Q(QWin32PrintEngine); + QPainterPathStroker stroker; if (pen.style() == Qt::CustomDashLine) { stroker.setDashPattern(pen.dashPattern()); @@ -898,11 +904,12 @@ void QWin32PrintEnginePrivate::strokePath(const QPainterPath &path, const QColor QPainterPath stroke; qreal width = pen.widthF(); - if (pen.style() == Qt::SolidLine && (pen.isCosmetic() || matrix.type() < QTransform::TxScale)) { + bool cosmetic = qt_pen_is_cosmetic(pen, q->state->renderHints()); + if (pen.style() == Qt::SolidLine && (cosmetic || matrix.type() < QTransform::TxScale)) { strokePath_dev(path * matrix, color, width); } else { stroker.setWidth(width); - if (pen.isCosmetic()) { + if (cosmetic) { stroke = stroker.createStroke(path * matrix); } else { stroke = stroker.createStroke(path) * painterMatrix; diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 375aa9b6ca0..c432902fc2b 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -8030,7 +8030,7 @@ QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem() /*! Returns the item's pen. If no pen has been set, this function returns - QPen(), a default black solid line pen with 0 width. + QPen(), a default black solid line pen with 1 width. */ QPen QAbstractGraphicsShapeItem::pen() const { @@ -8204,7 +8204,7 @@ QRectF QGraphicsPathItem::boundingRect() const { Q_D(const QGraphicsPathItem); if (d->boundingRect.isNull()) { - qreal pw = pen().widthF(); + qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF(); if (pw == 0.0) d->boundingRect = d->path.controlPointRect(); else { @@ -8434,7 +8434,7 @@ QRectF QGraphicsRectItem::boundingRect() const { Q_D(const QGraphicsRectItem); if (d->boundingRect.isNull()) { - qreal halfpw = pen().widthF() / 2; + qreal halfpw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF() / 2; d->boundingRect = d->rect; if (halfpw > 0.0) d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw); @@ -8723,7 +8723,7 @@ QRectF QGraphicsEllipseItem::boundingRect() const { Q_D(const QGraphicsEllipseItem); if (d->boundingRect.isNull()) { - qreal pw = pen().widthF(); + qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF(); if (pw == 0.0 && d->spanAngle == 360 * 16) d->boundingRect = d->rect; else @@ -8959,7 +8959,7 @@ QRectF QGraphicsPolygonItem::boundingRect() const { Q_D(const QGraphicsPolygonItem); if (d->boundingRect.isNull()) { - qreal pw = pen().widthF(); + qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF(); if (pw == 0.0) d->boundingRect = d->polygon.boundingRect(); else diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index 6dd03e76b09..762f93f55bf 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -1485,17 +1485,7 @@ void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsIt if (exposedWidgetRect.isEmpty()) return; - // Disable QPainter's default pen being cosmetic. This allows widgets and - // styles to follow Qt's existing defaults without getting ugly cosmetic - // lines when scaled. - bool restore = !(painter->renderHints() & QPainter::NonCosmeticDefaultPen); - painter->setRenderHints(QPainter::NonCosmeticDefaultPen, true); - d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect); - - // Restore the render hints if necessary. - if (restore) - painter->setRenderHints(QPainter::NonCosmeticDefaultPen, false); } /*! diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 05ae51c6307..859f07a36be 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -2299,7 +2299,6 @@ void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGrap painter->fillRect(windowFrameRect, palette().window()); } } - painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Draw title int height = (int)d->titleBarHeight(bar); diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 24be319173d..09180b3de9d 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -1490,6 +1490,7 @@ void tst_QPainter::setWindow() pixmap.fill(QColor(Qt::white)); QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Qt4CompatiblePainting); painter.setWindow(0, 0, 3, 3); painter.drawLine(1, 1, 2, 2); diff --git a/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp index 2ccc6c4ad36..4172076f6af 100644 --- a/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp +++ b/tests/auto/gui/painting/qpathclipper/tst_qpathclipper.cpp @@ -470,9 +470,9 @@ void tst_QPathClipper::clipTest(int subjectIndex, int clipIndex, QPathClipper::O p.setRenderHint(QPainter::Antialiasing); p.scale(scale, scale); p.translate(-bounds.topLeft()); - p.setPen(Qt::black); + p.setPen(QPen(Qt::black, 0)); p.drawPath(subject); - p.setPen(Qt::red); + p.setPen(QPen(Qt::red, 0)); p.drawPath(clip); p.end(); diff --git a/tests/auto/gui/painting/qpen/tst_qpen.cpp b/tests/auto/gui/painting/qpen/tst_qpen.cpp index 35a71ba0a92..1ef7a4d0c4f 100644 --- a/tests/auto/gui/painting/qpen/tst_qpen.cpp +++ b/tests/auto/gui/painting/qpen/tst_qpen.cpp @@ -154,9 +154,9 @@ void tst_QPen::constructor_data() QTest::addColumn("capStyle"); QTest::addColumn("joinStyle"); - QTest::newRow("solid_black") << QPen() << QBrush(Qt::black) << 0. << (int)Qt::SolidLine + QTest::newRow("solid_black") << QPen() << QBrush(Qt::black) << 1. << (int)Qt::SolidLine << (int) Qt::SquareCap << (int)Qt::BevelJoin; - QTest::newRow("solid_red") << QPen(Qt::red) << QBrush(Qt::red) << 0. << (int)Qt::SolidLine + QTest::newRow("solid_red") << QPen(Qt::red) << QBrush(Qt::red) << 1. << (int)Qt::SolidLine << (int)Qt::SquareCap << (int)Qt::BevelJoin; QTest::newRow("full") << QPen(QBrush(QLinearGradient(0, 0, 100, 100)), 10, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin) diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp index 1ddee7714ae..a0646591e84 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp @@ -234,6 +234,7 @@ void tst_QGraphicsEffect::boundingRect() // Install effect on QGraphicsItem. QRectF itemRect(0, 0, 100, 100); QGraphicsRectItem *item = new QGraphicsRectItem; + item->setPen(QPen(Qt::black, 0)); item->setRect(itemRect); item->setGraphicsEffect(effect); int margin = effect->margin(); @@ -265,16 +266,19 @@ void tst_QGraphicsEffect::boundingRect2() { CustomEffect *effect = new CustomEffect; QGraphicsRectItem *root = new QGraphicsRectItem; + root->setPen(QPen(Qt::black, 0)); root->setGraphicsEffect(effect); QGraphicsRectItem *child = new QGraphicsRectItem; QRectF childRect(0, 0, 100, 100); + child->setPen(QPen(Qt::black, 0)); child->setFlag(QGraphicsItem::ItemClipsChildrenToShape); child->setRect(childRect); child->setParentItem(root); QGraphicsRectItem *grandChild = new QGraphicsRectItem; QRectF grandChildRect(0, 0, 200, 200); + grandChild->setPen(QPen(Qt::black, 0)); grandChild->setRect(grandChildRect); grandChild->setParentItem(child); diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index f78b40bdf0c..490d79b270a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -491,6 +491,7 @@ void tst_QGraphicsItem::construction() switch (i) { case 0: item = new QGraphicsEllipseItem; + ((QGraphicsEllipseItem *)item)->setPen(QPen(Qt::black, 0)); QCOMPARE(int(item->type()), int(QGraphicsEllipseItem::Type)); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsEllipseItem *)item); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsRectItem *)0); @@ -498,6 +499,7 @@ void tst_QGraphicsItem::construction() break; case 1: item = new QGraphicsLineItem; + ((QGraphicsLineItem *)item)->setPen(QPen(Qt::black, 0)); QCOMPARE(int(item->type()), int(QGraphicsLineItem::Type)); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsLineItem *)item); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsRectItem *)0); @@ -505,6 +507,7 @@ void tst_QGraphicsItem::construction() break; case 2: item = new QGraphicsPathItem; + ((QGraphicsPathItem *)item)->setPen(QPen(Qt::black, 0)); QCOMPARE(int(item->type()), int(QGraphicsPathItem::Type)); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsPathItem *)item); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsRectItem *)0); @@ -519,6 +522,7 @@ void tst_QGraphicsItem::construction() break; case 4: item = new QGraphicsPolygonItem; + ((QGraphicsPolygonItem *)item)->setPen(QPen(Qt::black, 0)); QCOMPARE(int(item->type()), int(QGraphicsPolygonItem::Type)); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsPolygonItem *)item); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsRectItem *)0); @@ -526,6 +530,7 @@ void tst_QGraphicsItem::construction() break; case 5: item = new QGraphicsRectItem; + ((QGraphicsRectItem *)item)->setPen(QPen(Qt::black, 0)); QCOMPARE(int(item->type()), int(QGraphicsRectItem::Type)); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsRectItem *)item); QCOMPARE(qgraphicsitem_cast(item), (QGraphicsLineItem *)0); @@ -579,7 +584,9 @@ public: BoundingRectItem(QGraphicsItem *parent = 0) : QGraphicsRectItem(0, 0, parent ? 200 : 100, parent ? 200 : 100, parent) - {} + { + setPen(QPen(Qt::black, 0)); + } QRectF boundingRect() const { @@ -2204,6 +2211,7 @@ void tst_QGraphicsItem::setMatrix() QSignalSpy spy(&scene, SIGNAL(changed(QList))); QRectF unrotatedRect(-12, -34, 56, 78); QGraphicsRectItem item(unrotatedRect, 0); + item.setPen(QPen(Qt::black, 0)); scene.addItem(&item); scene.update(scene.sceneRect()); QApplication::instance()->processEvents(); @@ -2277,6 +2285,7 @@ void tst_QGraphicsItem::zValue() void tst_QGraphicsItem::shape() { QGraphicsLineItem line(QLineF(-10, -10, 20, 20)); + line.setPen(QPen(Qt::black, 0)); // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 // if we pass a value of 0.0 to QPainterPathStroker::setWidth() @@ -2317,6 +2326,7 @@ void tst_QGraphicsItem::shape() QCOMPARE(line.shape(), p); QGraphicsRectItem rect(QRectF(-10, -10, 20, 20)); + rect.setPen(QPen(Qt::black, 0)); QPainterPathStroker ps1; ps1.setWidth(penWidthZero); path = QPainterPath(); @@ -2326,6 +2336,7 @@ void tst_QGraphicsItem::shape() QCOMPARE(rect.shape(), p); QGraphicsEllipseItem ellipse(QRectF(-10, -10, 20, 20)); + ellipse.setPen(QPen(Qt::black, 0)); QPainterPathStroker ps2; ps2.setWidth(ellipse.pen().widthF() <= 0.0 ? penWidthZero : ellipse.pen().widthF()); path = QPainterPath(); @@ -2339,6 +2350,7 @@ void tst_QGraphicsItem::shape() p = ps3.createStroke(path); p.addPath(path); QGraphicsPathItem pathItem(path); + pathItem.setPen(QPen(Qt::black, 0)); QCOMPARE(pathItem.shape(), p); QRegion region(QRect(0, 0, 300, 200)); @@ -2377,6 +2389,7 @@ void tst_QGraphicsItem::shape() QPolygonF poly; poly << QPointF(0, 0) << QPointF(10, 0) << QPointF(0, 10); QGraphicsPolygonItem polygon(poly); + polygon.setPen(QPen(Qt::black, 0)); path = QPainterPath(); path.addPolygon(poly); @@ -3393,6 +3406,12 @@ void tst_QGraphicsItem::childrenBoundingRectTransformed() rect4->setParentItem(rect3); rect5->setParentItem(rect4); + rect->setPen(QPen(Qt::black, 0)); + rect2->setPen(QPen(Qt::black, 0)); + rect3->setPen(QPen(Qt::black, 0)); + rect4->setPen(QPen(Qt::black, 0)); + rect5->setPen(QPen(Qt::black, 0)); + rect2->setTransform(QTransform().translate(50, 50).rotate(45)); rect2->setPos(25, 25); rect3->setTransform(QTransform().translate(50, 50).rotate(45)); @@ -3425,6 +3444,9 @@ void tst_QGraphicsItem::childrenBoundingRect2() QGraphicsLineItem l2(100, 0, 100, 100, &box); QGraphicsLineItem l3(0, 0, 0, 100, &box); // Make sure lines (zero with/height) are included in the childrenBoundingRect. + l1.setPen(QPen(Qt::black, 0)); + l2.setPen(QPen(Qt::black, 0)); + l3.setPen(QPen(Qt::black, 0)); QCOMPARE(box.childrenBoundingRect(), QRectF(0, 0, 100, 100)); } @@ -3442,6 +3464,12 @@ void tst_QGraphicsItem::childrenBoundingRect3() rect4->setParentItem(rect3); rect5->setParentItem(rect4); + rect->setPen(QPen(Qt::black, 0)); + rect2->setPen(QPen(Qt::black, 0)); + rect3->setPen(QPen(Qt::black, 0)); + rect4->setPen(QPen(Qt::black, 0)); + rect5->setPen(QPen(Qt::black, 0)); + rect2->setTransform(QTransform().translate(50, 50).rotate(45)); rect2->setPos(25, 25); rect3->setTransform(QTransform().translate(50, 50).rotate(45)); @@ -3495,6 +3523,9 @@ void tst_QGraphicsItem::childrenBoundingRect5() QGraphicsRectItem *child = scene.addRect(QRectF(0, 0, 100, 100)); child->setParentItem(parent); + parent->setPen(QPen(Qt::black, 0)); + child->setPen(QPen(Qt::black, 0)); + QGraphicsView view(&scene); view.show(); @@ -4382,6 +4413,7 @@ void tst_QGraphicsItem::defaultItemTest_QGraphicsTextItem() void tst_QGraphicsItem::defaultItemTest_QGraphicsEllipseItem() { QGraphicsEllipseItem item; + item.setPen(QPen(Qt::black, 0)); QVERIFY(item.rect().isNull()); QVERIFY(item.boundingRect().isNull()); QVERIFY(item.shape().isEmpty()); @@ -6517,6 +6549,7 @@ void tst_QGraphicsItem::boundingRegion() QFETCH(QRegion, expectedRegion); QGraphicsLineItem item(line); + item.setPen(QPen(Qt::black, 0)); QCOMPARE(item.boundingRegionGranularity(), qreal(0.0)); item.setBoundingRegionGranularity(granularity); QCOMPARE(item.boundingRegionGranularity(), granularity); @@ -6980,6 +7013,7 @@ public: TransformDebugItem() : QGraphicsRectItem(QRectF(-10, -10, 20, 20)) { + setPen(QPen(Qt::black, 0)); setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256)); } @@ -7047,7 +7081,9 @@ void tst_QGraphicsItem::sceneTransformCache() // parent is transformed. QGraphicsScene scene; QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100); + rect->setPen(QPen(Qt::black, 0)); QGraphicsRectItem *rect2 = scene.addRect(0, 0, 100, 100); + rect2->setPen(QPen(Qt::black, 0)); rect2->setParentItem(rect); rect2->rotate(90); rect->translate(0, 50); @@ -7071,9 +7107,11 @@ void tst_QGraphicsItem::sceneTransformCache() QGraphicsRectItem *rect3 = scene.addRect(0, 0, 100, 100); QGraphicsRectItem *rect4 = scene.addRect(0, 0, 100, 100); rect3->setPos(QPointF(10,10)); + rect3->setPen(QPen(Qt::black, 0)); rect4->setParentItem(rect3); rect4->setPos(QPointF(10,10)); + rect4->setPen(QPen(Qt::black, 0)); QCOMPARE(rect4->mapToScene(rect4->boundingRect().topLeft()), QPointF(20,20)); @@ -7084,9 +7122,11 @@ void tst_QGraphicsItem::sceneTransformCache() QGraphicsRectItem *rect5 = scene.addRect(0, 0, 100, 100); QGraphicsRectItem *rect6 = scene.addRect(0, 0, 100, 100); rect5->setPos(QPointF(20,20)); + rect5->setPen(QPen(Qt::black, 0)); rect6->setParentItem(rect5); rect6->setPos(QPointF(10,10)); + rect6->setPen(QPen(Qt::black, 0)); //test if rect6 transform is ok QCOMPARE(rect6->mapToScene(rect6->boundingRect().topLeft()), QPointF(30,30)); diff --git a/tests/auto/widgets/graphicsview/qgraphicspolygonitem/tst_qgraphicspolygonitem.cpp b/tests/auto/widgets/graphicsview/qgraphicspolygonitem/tst_qgraphicspolygonitem.cpp index 79a3c614623..bc091a08beb 100644 --- a/tests/auto/widgets/graphicsview/qgraphicspolygonitem/tst_qgraphicspolygonitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicspolygonitem/tst_qgraphicspolygonitem.cpp @@ -42,6 +42,7 @@ #include #include +#include Q_DECLARE_METATYPE(QPolygonF) @@ -170,6 +171,7 @@ void tst_QGraphicsPolygonItem::boundingRect() QFETCH(QRectF, boundingRect); SubQGraphicsPolygonItem item(polygon); + item.setPen(QPen(Qt::black, 0)); QCOMPARE(item.boundingRect(), boundingRect); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 90d21d6d958..a4aa2a6e415 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -322,7 +322,8 @@ void tst_QGraphicsScene::sceneRect() QCOMPARE(scene.sceneRect(), QRectF()); QCOMPARE(sceneRectChanged.count(), 0); - QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10)); + QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 10, 10)); + item->setPen(QPen(Qt::black, 0)); item->setPos(-5, -5); QCOMPARE(sceneRectChanged.count(), 0); @@ -458,7 +459,9 @@ void tst_QGraphicsScene::items() { QGraphicsScene scene; QGraphicsLineItem *l1 = scene.addLine(-5, 0, 5, 0); + l1->setPen(QPen(Qt::black, 0)); QGraphicsLineItem *l2 = scene.addLine(0, -5, 0, 5); + l2->setPen(QPen(Qt::black, 0)); QVERIFY(!l1->sceneBoundingRect().intersects(l2->sceneBoundingRect())); QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect())); QList items; @@ -533,7 +536,9 @@ void tst_QGraphicsScene::itemsBoundingRect() foreach (QRectF rect, rects) { QPainterPath path; path.addRect(rect); - scene.addPath(path)->setMatrix(matrix); + QGraphicsPathItem *item = scene.addPath(path); + item->setPen(QPen(Qt::black, 0)); + item->setMatrix(matrix); } QCOMPARE(scene.itemsBoundingRect(), boundingRect); @@ -597,7 +602,8 @@ void tst_QGraphicsScene::items_QPointF() QPainterPath path; path.addRect(0, 0, rect.width(), rect.height()); - QGraphicsItem *item = scene.addPath(path); + QGraphicsPathItem *item = scene.addPath(path); + item->setPen(QPen(Qt::black, 0)); item->setZValue(n++); item->setPos(rect.topLeft()); addedItems << item; @@ -1170,6 +1176,9 @@ void tst_QGraphicsScene::addPath() QCOMPARE(path->pen(), QPen(Qt::red)); QCOMPARE(path->path(), p); QCOMPARE(path->brush(), QBrush(Qt::blue)); + + path->setPen(QPen(Qt::red, 0)); + QCOMPARE(scene.itemAt(0, 0), (QGraphicsItem *)path); QCOMPARE(scene.itemAt(-9.9, 0), (QGraphicsItem *)path); QCOMPARE(scene.itemAt(9.9, 0), (QGraphicsItem *)path); @@ -1222,6 +1231,9 @@ void tst_QGraphicsScene::addRect() QCOMPARE(rect->pen(), QPen(Qt::red)); QCOMPARE(rect->brush(), QBrush(Qt::blue)); QCOMPARE(rect->rect(), QRectF(-10, -10, 20, 20)); + + rect->setPen(QPen(Qt::red, 0)); + QCOMPARE(scene.itemAt(0, 0), (QGraphicsItem *)rect); QCOMPARE(scene.itemAt(-10, -10), (QGraphicsItem *)rect); QCOMPARE(scene.itemAt(-9.9, 0), (QGraphicsItem *)rect); @@ -1397,7 +1409,7 @@ void tst_QGraphicsScene::clear() QGraphicsScene scene; scene.clear(); QVERIFY(scene.items().isEmpty()); - scene.addRect(0, 0, 100, 100); + scene.addRect(0, 0, 100, 100)->setPen(QPen(Qt::black, 0)); QCOMPARE(scene.sceneRect(), QRectF(0, 0, 100, 100)); scene.clear(); QVERIFY(scene.items().isEmpty()); @@ -2610,8 +2622,8 @@ void tst_QGraphicsScene::render() QGraphicsView view; QGraphicsScene scene(&view); - scene.addEllipse(QRectF(-10, -10, 20, 20), QPen(Qt::black), QBrush(Qt::white)); - scene.addEllipse(QRectF(-2, -7, 4, 4), QPen(Qt::black), QBrush(Qt::yellow))->setZValue(1); + scene.addEllipse(QRectF(-10, -10, 20, 20), QPen(Qt::black, 0), QBrush(Qt::white)); + scene.addEllipse(QRectF(-2, -7, 4, 4), QPen(Qt::black, 0), QBrush(Qt::yellow))->setZValue(1); QGraphicsPixmapItem *item = scene.addPixmap(pix); item->setZValue(2); item->setOffset(QPointF(3, 3)); @@ -2808,6 +2820,7 @@ void tst_QGraphicsScene::update() QGraphicsScene scene; QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100); + rect->setPen(QPen(Qt::black, 0)); scene.addItem(rect); qApp->processEvents(); rect->setPos(-100, -100); @@ -3484,6 +3497,7 @@ void tst_QGraphicsScene::task176178_itemIndexMethodBreaksSceneRect() QGraphicsScene scene; scene.setItemIndexMethod(QGraphicsScene::NoIndex); QGraphicsRectItem *rect = new QGraphicsRectItem; + rect->setPen(QPen(Qt::black, 0)); rect->setRect(0,0,100,100); scene.addItem(rect); QCOMPARE(scene.sceneRect(), rect->rect()); @@ -3513,11 +3527,11 @@ void tst_QGraphicsScene::task250680_childClip() { QGraphicsRectItem *clipper = new QGraphicsRectItem; clipper->setFlag(QGraphicsItem::ItemClipsChildrenToShape); - clipper->setPen(QPen(Qt::green)); + clipper->setPen(QPen(Qt::green, 0)); clipper->setRect(200, 200, 640, 480); QGraphicsRectItem *rect = new QGraphicsRectItem(clipper); - rect->setPen(QPen(Qt::red)); + rect->setPen(QPen(Qt::red, 0)); rect->setBrush(QBrush(QColor(255, 0, 0, 75))); rect->setPos(320, 240); rect->setRect(-25, -25, 50, 50); @@ -3662,6 +3676,7 @@ void tst_QGraphicsScene::changedSignal() view = new QGraphicsView(&scene); QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 10, 10); + rect->setPen(QPen(Qt::black, 0)); scene.addItem(rect); QCOMPARE(cl.changes.size(), 0); @@ -4246,13 +4261,13 @@ void tst_QGraphicsScene::siblingIndexAlwaysValid() // first add the blue rect QGraphicsRectItem* const item1 = new QGraphicsRectItem(QRect( 10, 10, 10, 10 )); - item1->setPen(QColor(Qt::blue)); + item1->setPen(QPen(Qt::blue, 0)); item1->setBrush(Qt::blue); scene2.addItem(item1); // then add the red rect QGraphicsRectItem* const item2 = new QGraphicsRectItem(5, 5, 10, 10); - item2->setPen(QColor(Qt::red)); + item2->setPen(QPen(Qt::red, 0)); item2->setBrush(Qt::red); scene2.addItem(item2); diff --git a/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 70ebd3c8a78..593fa4e2ef4 100644 --- a/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -132,7 +132,7 @@ void tst_QGraphicsSceneIndex::overlappedItems() for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) - scene.addRect(i*50, j*50, 200, 200); + scene.addRect(i*50, j*50, 200, 200)->setPen(QPen(Qt::black, 0)); QCOMPARE(scene.items(QPointF(5, 5)).count(), 1); QCOMPARE(scene.items(QPointF(55, 55)).count(), 4); diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 474ac47ea1d..d2b7001e932 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -542,6 +542,7 @@ void tst_QGraphicsView::sceneRect() QCOMPARE(view.sceneRect(), QRectF()); QGraphicsScene scene; QGraphicsRectItem *item = scene.addRect(QRectF(-100, -100, 100, 100)); + item->setPen(QPen(Qt::black, 0)); view.setScene(&scene); @@ -1510,6 +1511,7 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust() QGraphicsScene scene(-100, -100, 200, 200); CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100)); + rect->setPen(QPen(Qt::black, 0)); scene.addItem(rect); QGraphicsView view(&scene); @@ -2603,8 +2605,13 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() MyScene scene; // Add transformed dummy items to make sure the painter's worldTransform() is changed in drawItems. - scene.addRect(0, 0, 20, 20)->setTransform(QTransform::fromScale(2, 2)); - scene.addRect(50, 50, 20, 20)->setTransform(QTransform::fromTranslate(200, 200)); + QGraphicsRectItem *rectA = scene.addRect(0, 0, 20, 20); + QGraphicsRectItem *rectB = scene.addRect(50, 50, 20, 20); + + rectA->setTransform(QTransform::fromScale(2, 2)); + rectA->setPen(QPen(Qt::black, 0)); + rectB->setTransform(QTransform::fromTranslate(200, 200)); + rectB->setPen(QPen(Qt::black, 0)); foreach (QGraphicsItem *item, scene.items()) item->setOpacity(0.6); @@ -3367,10 +3374,11 @@ void tst_QGraphicsView::moveItemWhileScrolling() setScene(new QGraphicsScene(0, 0, 1000, 1000)); rect = scene()->addRect(0, 0, 10, 10); rect->setPos(50, 50); + rect->setPen(QPen(Qt::black, 0)); painted = false; } QRegion lastPaintedRegion; - QGraphicsItem *rect; + QGraphicsRectItem *rect; bool painted; void waitForPaintEvent() { @@ -4331,25 +4339,31 @@ void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins() view.show(); qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); - QPoint mouseViewPos(20, 20); - sendMouseMove(view.viewport(), mouseViewPos); - - QPointF mouseScenePos = view.mapToScene(mouseViewPos); - view.setTransform(QTransform().scale(5, 5).rotate(5, Qt::ZAxis), true); - - QPointF newMouseScenePos = view.mapToScene(mouseViewPos); - - qreal slack = 1; - - const qreal dx = qAbs(newMouseScenePos.x() - mouseScenePos.x()); - const qreal dy = qAbs(newMouseScenePos.y() - mouseScenePos.y()); - const QByteArray message = QString::fromLatin1("QTBUG-22455, distance: dx=%1, dy=%2 slack=%3 (%4)."). - arg(dx).arg(dy).arg(slack).arg(qApp->style()->metaObject()->className()).toLocal8Bit(); // This is highly unstable (observed to pass on Windows and some Linux configurations). -#ifdef Q_OS_MAC - QEXPECT_FAIL("", message.constData(), Abort); +#ifndef Q_OS_MAC + for (int i = 0; i < 4; ++i) { + QPoint mouseViewPos(20, 20); + sendMouseMove(view.viewport(), mouseViewPos); + + QPointF mouseScenePos = view.mapToScene(mouseViewPos); + view.setTransform(QTransform().scale(5, 5).rotate(5, Qt::ZAxis), true); + + qreal slack = 1; + + QPointF newMouseScenePos = view.mapToScene(mouseViewPos); + + const qreal dx = qAbs(newMouseScenePos.x() - mouseScenePos.x()); + const qreal dy = qAbs(newMouseScenePos.y() - mouseScenePos.y()); + const QByteArray message = QString::fromLatin1("QTBUG-22455, distance: dx=%1, dy=%2 slack=%3 (%4)."). + arg(dx).arg(dy).arg(slack).arg(qApp->style()->metaObject()->className()).toLocal8Bit(); + if (i == 9 || (dx < slack && dy < slack)) { + QVERIFY2(dx < slack && dy < slack, message.constData()); + break; + } + + QTest::qWait(100); + } #endif - QVERIFY2(dx < slack && dy < slack, message.constData()); } void tst_QGraphicsView::task259503_scrollingArtifacts()