summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp13
-rw-r--r--src/gui/opengl/qtriangulatingstroker.cpp8
-rw-r--r--src/gui/opengl/qtriangulatingstroker_p.h4
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp2
-rw-r--r--src/gui/painting/qpaintbuffer.cpp2
-rw-r--r--src/gui/painting/qpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp9
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp51
-rw-r--r--src/gui/painting/qpainter_p.h9
-rw-r--r--src/gui/painting/qpdf.cpp9
-rw-r--r--src/gui/painting/qpdf_p.h2
-rw-r--r--src/gui/painting/qpen.cpp44
-rw-r--r--src/gui/painting/qpen_p.h3
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp10
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm4
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha.cpp8
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp13
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp10
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp10
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp1
21 files changed, 107 insertions, 111 deletions
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index e0f1fe50a6..8e967207d4 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 0be6e12721..6c8ab7d607 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 295ddbab5a..ba21c0820f 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 2eab7b25c5..7fcab1f087 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 1e5a00e835..d7b16114b8 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 09b1f0a8e4..339421f5e2 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 e0eab8dc73..1a63ced897 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 dd93a58635..113cbd8a8e 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 69267b259b..090faf15aa 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 6ad1cb07cc..0e46cee4b5 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<QPen &>(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 d2aa938aed..1d07d44dd8 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -44,6 +44,7 @@
#include <qfile.h>
#include <qtemporaryfile.h>
#include <private/qmath_p.h>
+#include <private/qpainter_p.h>
#include <qnumeric.h>
#include "private/qfont_p.h"
#include <qimagewriter.h>
@@ -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 ba86803288..735c5d13e0 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 d86a5f0392..6b71c3818f 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<qreal> 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<QPenData *>(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 93f2532e63..4b2fcaa71d 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 7c47f3b3eb..e542397663 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 8c47527648..404c03dd30 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 e3312f2db7..387e87766b 100644
--- a/src/printsupport/kernel/qpaintengine_alpha.cpp
+++ b/src/printsupport/kernel/qpaintengine_alpha.cpp
@@ -45,6 +45,7 @@
#include <qdebug.h>
#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 27351dee48..28e0363d6e 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 375aa9b6ca..c432902fc2 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 6dd03e76b0..762f93f55b 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 05ae51c630..859f07a36b 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);