summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qblendfunctions.cpp40
-rw-r--r--src/gui/painting/qbrush.cpp24
-rw-r--r--src/gui/painting/qdrawhelper.cpp22
-rw-r--r--src/gui/painting/qpaintbuffer.cpp95
-rw-r--r--src/gui/painting/qpaintbuffer_p.h5
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp25
-rw-r--r--src/gui/painting/qpen.cpp33
-rw-r--r--src/gui/painting/qtransform.cpp9
9 files changed, 159 insertions, 98 deletions
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index f8dd424..8737f10 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -223,11 +223,23 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
- const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
+ quint32 basex;
+ quint32 srcy;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + 0.5 - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + 0.5 - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + 0.5 - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + 0.5 - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
@@ -723,11 +735,23 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
- const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
+ quint32 basex;
+ quint32 srcy;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + 0.5 - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + 0.5 - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + 0.5 - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + 0.5 - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index cbfbba6..6f5d892 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -970,7 +970,29 @@ bool QBrush::operator==(const QBrush &b) const
QDebug operator<<(QDebug dbg, const QBrush &b)
{
#ifndef Q_BROKEN_DEBUG_STREAM
- dbg.nospace() << "QBrush(" << b.color() << ',' << b.style() << ')';
+ char *BRUSH_STYLES[] = {
+ "NoBrush",
+ "SolidPattern",
+ "Dense1Pattern",
+ "Dense2Pattern",
+ "Dense3Pattern",
+ "Dense4Pattern",
+ "Dense5Pattern",
+ "Dense6Pattern",
+ "Dense7Pattern",
+ "HorPattern",
+ "VerPattern",
+ "CrossPattern",
+ "BDiagPattern",
+ "FDiagPattern",
+ "DiagCrossPattern",
+ "LinearGradientPattern",
+ "RadialGradientPattern",
+ "ConicalGradientPattern",
+ "TexturePattern"
+ };
+
+ dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
return dbg.space();
#else
qWarning("This compiler doesn't support streaming QBrush to QDebug");
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 41602a1..4df7f8a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2386,12 +2386,12 @@ static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int len
}
/*
- if 2.Sca < Sa
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise if 8.Dca <= Da
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ if 2.Sca <= Sa
+ Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca <= Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca > Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
*/
static inline int soft_light_op(int dst, int src, int da, int sa)
{
@@ -2400,13 +2400,11 @@ static inline int soft_light_op(int dst, int src, int da, int sa)
const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
if (src2 < sa)
- return (dst * ((sa * 255) - (255 - dst_np) * (src2 - sa)) + temp) / 65025;
- else if (8 * dst <= da)
- return (dst * ((sa * 255) - ((255 - dst_np) * (src2 - sa) * ((3 * 255) - 8 * dst_np)) / 255) + temp) / 65025;
+ return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
+ else if (4 * dst <= da)
+ return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
else {
- // sqrt is too expensive to do three times per pixel, so skipping it for now
- // a future possibility is to use a LUT
- return ((dst * sa * 255) + (int(dst_np) * da - (dst * 255)) * (src2 - sa) + temp) / 65025;
+ return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
}
}
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index 6b9d77c..b8700c3 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -48,7 +48,7 @@
#include <QDebug>
-//#define QPAINTBUFFER_DEBUG_DRAW
+// #define QPAINTBUFFER_DEBUG_DRAW
QT_BEGIN_NAMESPACE
@@ -247,23 +247,24 @@ void QPaintBuffer::draw(QPainter *painter, int frame) const
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBuffer::draw() --------------------------------";
-// printf("Float buffer:");
-// for (int i=0; i<d->floats.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+9);
-// }
-// printf("%4.2f ", d->floats[i]);
-// }
-// printf("\n");
-
-// printf("Int Buffer:");
-// for (int i=0; i<d->ints.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+10);
-// }
-// printf("%5d", d->ints[i]);
-// }
-// printf("\n");
+ Q_D(const QPaintBuffer);
+ printf("Float buffer:");
+ for (int i=0; i<d->floats.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+9);
+ }
+ printf("%4.2f ", d->floats[i]);
+ }
+ printf("\n");
+
+ printf("Int Buffer:");
+ for (int i=0; i<d->ints.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+10);
+ }
+ printf("%5d", d->ints[i]);
+ }
+ printf("\n");
#endif
if (painter && !painter->isActive())
@@ -406,16 +407,17 @@ void QPaintBufferEngine::clipEnabledChanged()
void QPaintBufferEngine::penChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->pen;
-#endif
const QPen &pen = state()->pen;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetPen) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged (compressed)" << state()->pen;
+#endif
buffer->variants[buffer->commands.last().offset] = pen;
return;
}
+
if (buffer->calculateBoundingRect) {
if (pen.style() == Qt::NoPen) {
buffer->penWidthAdjustment = 0;
@@ -427,22 +429,28 @@ void QPaintBufferEngine::penChanged()
buffer->penWidthAdjustment = transformedWidth.x() / 2.0;
}
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged" << state()->pen;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetPen, pen);
}
void QPaintBufferEngine::brushChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->brush;
-#endif
const QBrush &brush = state()->brush;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetBrush) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged (compressed)" << state()->brush;
+#endif
buffer->variants[buffer->commands.last().offset] = brush;
return;
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged" << state()->brush;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrush, brush);
}
@@ -488,14 +496,14 @@ void QPaintBufferEngine::transformChanged()
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetTransform) {
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: compressing " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged (compressing) " << state()->matrix;
#endif
buffer->variants[buffer->commands.last().offset] = state()->matrix;
return;
}
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged:" << state()->matrix;
#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetTransform, state()->matrix);
}
@@ -514,7 +522,18 @@ void QPaintBufferEngine::draw(const QVectorPath &path)
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBufferEngine: draw vpath:" << path.elementCount();
#endif
- buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+
+ bool hasBrush = qbrush_style(state()->brush) != Qt::NoBrush;
+ bool hasPen = qpen_style(state()->pen) != Qt::NoPen
+ && qbrush_style(qpen_brush(state()->pen)) != Qt::NoBrush;
+
+ if (hasPen || hasBrush)
+ buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ else
+ qDebug() << " - no pen or brush active, discarded...\n";
+#endif
+
// if (buffer->calculateBoundingRect) {
// QRealRect r = path.controlPointRect();
// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1));
@@ -745,15 +764,15 @@ void QPaintBufferEngine::drawEllipse(const QRect &r)
void QPaintBufferEngine::drawPath(const QPainterPath &path)
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
-#endif
- // ### Path -> QVariant
- // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
+// #ifdef QPAINTBUFFER_DEBUG_DRAW
+// qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
+// #endif
+// // ### Path -> QVariant
+// // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
QPaintEngineEx::drawPath(path);
- if (buffer->calculateBoundingRect)
- buffer->updateBoundingRect(path.boundingRect());
+// if (buffer->calculateBoundingRect)
+// buffer->updateBoundingRect(path.boundingRect());
}
void QPaintBufferEngine::drawPoints(const QPoint *points, int pointCount)
@@ -1424,10 +1443,6 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
QTextItemInt &ti = (*tiCopy)();
QString text(ti.text());
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
-#endif
-
QFont font(ti.font());
font.setUnderline(false);
font.setStrikeOut(false);
@@ -1439,6 +1454,10 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
justificationWidth = si.width.toReal();
qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY());
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
+#endif
+
if (scaleFactor != 1.0) {
QFont fnt(font);
QFakeDevice fake;
diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h
index 6a7ac73..adf0564 100644
--- a/src/gui/painting/qpaintbuffer_p.h
+++ b/src/gui/painting/qpaintbuffer_p.h
@@ -66,6 +66,7 @@ class QPaintBufferPlayback;
class Q_GUI_EXPORT QPaintBuffer : public QPaintDevice
{
+ Q_DECLARE_PRIVATE(QPaintBuffer);
public:
QPaintBuffer();
QPaintBuffer(const QPaintBuffer &other);
@@ -311,7 +312,7 @@ public:
virtual ~QPainterReplayer() { }
void setupTransform(QPainter *painter);
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);
protected:
@@ -326,7 +327,7 @@ class Q_GUI_EXPORT QPaintEngineExReplayer : public QPainterReplayer
public:
QPaintEngineExReplayer() { }
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
};
class QPaintBufferEnginePrivate;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 9e21182..1fb8aab 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -431,6 +431,10 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
// Some engines might decide to optimize for the non-shape hint later on...
uint flags = QVectorPath::WindingFill;
+
+ if (path.elementCount() > 2)
+ flags |= QVectorPath::NonConvexShapeMask;
+
if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
flags |= QVectorPath::CurvedShapeMask;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 09a4563..48629d1 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -3787,27 +3787,14 @@ void QPainter::setPen(const QPen &pen)
if (d->state->pen == pen)
return;
+ d->state->pen = pen;
+
if (d->extended) {
- d->state->pen = pen;
d->checkEmulation();
d->extended->penChanged();
return;
}
- // Do some checks to see if we are the same pen.
- Qt::PenStyle currentStyle = d->state->pen.style();
- if (currentStyle == pen.style() && currentStyle != Qt::CustomDashLine) {
- if (currentStyle == Qt::NoPen ||
- (d->state->pen.isSolid() && pen.isSolid()
- && d->state->pen.color() == pen.color()
- && d->state->pen.widthF() == pen.widthF()
- && d->state->pen.capStyle() == pen.capStyle()
- && d->state->pen.joinStyle() == pen.joinStyle()
- && d->state->pen.isCosmetic() == pen.isCosmetic()))
- return;
- }
-
- d->state->pen = pen;
d->state->dirtyFlags |= QPaintEngine::DirtyPen;
}
@@ -3890,14 +3877,6 @@ void QPainter::setBrush(const QBrush &brush)
return;
}
- Qt::BrushStyle currentStyle = d->state->brush.style();
- if (currentStyle == brush.style()) {
- if (currentStyle == Qt::NoBrush
- || (currentStyle == Qt::SolidPattern
- && d->state->brush.color() == brush.color()))
- return;
- }
-
d->state->brush = brush;
d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 41efc80..77aa748 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -835,16 +835,17 @@ bool QPen::operator==(const QPen &p) const
{
QPenData *dd = static_cast<QPenData *>(d);
QPenData *pdd = static_cast<QPenData *>(p.d);
- return (p.d == d) || (p.d->style == d->style
- && p.d->capStyle == d->capStyle
- && p.d->joinStyle == d->joinStyle
- && p.d->width == d->width
- && pdd->miterLimit == dd->miterLimit
- && (d->style != Qt::CustomDashLine
- || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
- pdd->dashPattern == dd->dashPattern))
- && p.d->brush == d->brush
- && pdd->cosmetic == dd->cosmetic);
+ return (p.d == d)
+ || (p.d->style == d->style
+ && p.d->capStyle == d->capStyle
+ && p.d->joinStyle == d->joinStyle
+ && p.d->width == d->width
+ && pdd->miterLimit == dd->miterLimit
+ && (d->style != Qt::CustomDashLine
+ || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
+ pdd->dashPattern == dd->dashPattern))
+ && p.d->brush == d->brush
+ && pdd->cosmetic == dd->cosmetic);
}
@@ -983,8 +984,18 @@ QDataStream &operator>>(QDataStream &s, QPen &p)
QDebug operator<<(QDebug dbg, const QPen &p)
{
#ifndef Q_BROKEN_DEBUG_STREAM
+ const char *PEN_STYLES[] = {
+ "NoPen",
+ "SolidLine",
+ "DashLine",
+ "DotLine",
+ "DashDotLine",
+ "DashDotDotLine",
+ "CustomDashLine"
+ };
+
dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
- << ',' << int(p.style()) << ',' << int(p.capStyle())
+ << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
<< ',' << int(p.joinStyle()) << ',' << p.dashPattern()
<< ',' << p.dashOffset()
<< ',' << p.miterLimit() << ')';
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 8118450..1bd5842 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -2214,12 +2214,14 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
const QTransform::TransformationType type = transform.type();
if (type <= QTransform::TxTranslate) {
- *scale = 1;
+ if (scale)
+ *scale = 1;
return true;
} else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
- *scale = qMax(xScale, yScale);
+ if (scale)
+ *scale = qMax(xScale, yScale);
return qFuzzyCompare(xScale, yScale);
}
@@ -2227,7 +2229,8 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
+ transform.m21() * transform.m21();
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
- *scale = qSqrt(qMax(xScale, yScale));
+ if (scale)
+ *scale = qSqrt(qMax(xScale, yScale));
return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}