summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-08-04 08:33:52 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-08-04 09:02:17 (GMT)
commit4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1 (patch)
treeb34985c5716d98f01b9f36fd4a98f2ac9710099f /src/gui/painting
parenta0df97c03f26a38af17a42fb44ad6910536c8857 (diff)
parent2076f150995e541308b1d8da936b3e12ab68b886 (diff)
downloadQt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.zip
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.gz
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: config.tests/unix/openssl/openssl.pri demos/embedded/embedded.pro examples/itemviews/chart/chart.pro examples/network/network.pro examples/painting/painterpaths/painterpaths.pro examples/threads/mandelbrot/mandelbrot.pro qmake/project.cpp src/3rdparty/libtiff/libtiff/tif_config.h src/corelib/arch/arch.pri src/corelib/global/qglobal.cpp src/corelib/kernel/kernel.pri src/corelib/kernel/qcore_unix_p.h src/corelib/kernel/qobject.cpp src/corelib/thread/qthread_unix.cpp src/corelib/tools/qsharedpointer_impl.h src/corelib/tools/tools.pri src/gui/kernel/qaction.h src/gui/kernel/qapplication.cpp src/gui/painting/qregion.h src/gui/widgets/qlineedit.cpp src/gui/widgets/qlineedit_p.h src/network/socket/qnativesocketengine_unix.cpp tests/auto/qdir/tst_qdir.cpp tests/auto/qdiriterator/tst_qdiriterator.cpp tests/auto/qhttp/qhttp.pro tests/auto/qline/qline.pro tests/auto/qnetworkreply/tst_qnetworkreply.cpp tests/auto/qresourceengine/qresourceengine.pro tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qstring/qstring.pro tests/auto/qtcpsocket/qtcpsocket.pro tests/auto/qtcpsocket/tst_qtcpsocket.cpp
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/painting.pri8
-rw-r--r--src/gui/painting/qbackingstore.cpp3
-rw-r--r--src/gui/painting/qblendfunctions.cpp8
-rw-r--r--src/gui/painting/qbrush.h9
-rw-r--r--src/gui/painting/qdrawhelper.cpp72
-rw-r--r--src/gui/painting/qgrayraster.c4
-rw-r--r--src/gui/painting/qoutlinemapper.cpp28
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp95
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpaintengineex.cpp132
-rw-r--r--src/gui/painting/qpainterpath.cpp2
-rw-r--r--src/gui/painting/qregion.cpp28
-rw-r--r--src/gui/painting/qregion.h5
-rw-r--r--src/gui/painting/qregion_mac.cpp38
-rw-r--r--src/gui/painting/qregion_win.cpp514
-rw-r--r--src/gui/painting/qregion_wince.cpp119
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h4
-rw-r--r--src/gui/painting/qtransform.cpp47
-rw-r--r--src/gui/painting/qtransform.h4
-rw-r--r--src/gui/painting/qvectorpath_p.h2
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp4
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp4
22 files changed, 302 insertions, 830 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index d153215..4121be6 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -101,8 +101,8 @@ win32 {
painting/qcolormap_win.cpp \
painting/qpaintdevice_win.cpp \
painting/qprintengine_win.cpp \
- painting/qprinterinfo_win.cpp \
- painting/qregion_win.cpp
+ painting/qprinterinfo_win.cpp
+
!win32-borland:!wince*:LIBS += -lmsimg32
}
@@ -127,10 +127,6 @@ embedded {
painting/qwindowsurface_raster.cpp \
}
-wince* {
- SOURCES -= painting/qregion_win.cpp
-}
-
unix:x11 {
HEADERS += \
painting/qpaintengine_x11_p.h
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 405acb7..40c9bf2 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -39,6 +39,9 @@
**
****************************************************************************/
+
+#include "qplatformdefs.h"
+
#include "qbackingstore_p.h"
#include <QtCore/qglobal.h>
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 831d389..fc2eb60 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -223,8 +223,8 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix);
- const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy);
+ 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((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
@@ -723,8 +723,8 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix);
- const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy);
+ 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((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h
index 5479305..fdb3a8a 100644
--- a/src/gui/painting/qbrush.h
+++ b/src/gui/painting/qbrush.h
@@ -52,6 +52,15 @@
#include <QtGui/qimage.h>
#include <QtGui/qpixmap.h>
+#if defined(Q_OS_VXWORKS)
+# if defined(m_data)
+# undef m_data
+# endif
+# if defined(m_type)
+# undef m_type
+# endif
+#endif
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index a70923d..d77ed57 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -4954,30 +4954,60 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
if (sy < 0)
sy += image_height;
- while (length) {
- int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
-
- DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
- const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
- if (modeSource && coverage == 255) {
+ if (modeSource && coverage == 255) {
+ // Copy the first texture block
+ length = image_width;
+ while (length) {
+ int l = qMin(image_width - sx, length);
+ if (buffer_size < l)
+ l = buffer_size;
+ DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
+ const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
qt_memconvert<DST, SRC>(dest, src, l);
- } else if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest24(dest, src, coverage, l);
- } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
- (quintptr(dest) & 3) == (quintptr(src) & 3))
- {
- blendUntransformed_dest16(dest, src, coverage, l);
- } else {
- blendUntransformed_unaligned(dest, src, coverage, l);
+ length -= l;
+ sx = 0;
}
- x += l;
- length -= l;
- sx = 0;
+ // Now use the rasterBuffer as the source of the texture,
+ // We can now progressively copy larger blocks
+ // - Less cpu time in code figuring out what to copy
+ // We are dealing with one block of data
+ // - More likely to fit in the cache
+ // - can use memcpy
+ int copy_image_width = image_width;
+ length = spans->len - image_width;
+ DST *src = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
+ DST *dest = src + copy_image_width;
+ while (copy_image_width < length) {
+ qt_memconvert(dest, src, copy_image_width);
+ dest += copy_image_width;
+ length -= copy_image_width;
+ copy_image_width *= 2;
+ }
+ qt_memconvert(dest, src, length);
+ } else {
+ while (length) {
+ int l = qMin(image_width - sx, length);
+ if (buffer_size < l)
+ l = buffer_size;
+ DST *dest = ((DST*)data->rasterBuffer->scanLine(spans->y)) + x;
+ const SRC *src = (SRC*)data->texture.scanLine(sy) + sx;
+ if (sizeof(DST) == 3 && sizeof(SRC) == 3 && l >= 4 &&
+ (quintptr(dest) & 3) == (quintptr(src) & 3))
+ {
+ blendUntransformed_dest24(dest, src, coverage, l);
+ } else if (sizeof(DST) == 2 && sizeof(SRC) == 2 && l >= 2 &&
+ (quintptr(dest) & 3) == (quintptr(src) & 3))
+ {
+ blendUntransformed_dest16(dest, src, coverage, l);
+ } else {
+ blendUntransformed_unaligned(dest, src, coverage, l);
+ }
+
+ x += l;
+ length -= l;
+ sx = 0;
+ }
}
++spans;
}
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c
index 888fd9a..6ab7055 100644
--- a/src/gui/painting/qgrayraster.c
+++ b/src/gui/painting/qgrayraster.c
@@ -134,7 +134,9 @@
#define ErrRaster_MemoryOverflow -4
-
+#if defined(VXWORKS)
+# include <vxWorksCommon.h> /* needed for setjmp.h */
+#endif
#include <string.h> /* for qt_ft_memcpy() */
#include <setjmp.h>
#include <limits.h>
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp
index 401fad9..70125b9 100644
--- a/src/gui/painting/qoutlinemapper.cpp
+++ b/src/gui/painting/qoutlinemapper.cpp
@@ -198,32 +198,8 @@ void QOutlineMapper::endOutline()
m_m22 * e.y() + m_m12 * e.x() + m_dy);
}
} else {
- // ## TODO: this case needs to be plain code polygonal paths
- QPainterPath path;
- if (m_element_types.isEmpty()) {
- if (!m_elements.isEmpty())
- path.moveTo(m_elements.at(0));
- for (int i=1; i<m_elements.size(); ++i)
- path.lineTo(m_elements.at(i));
- } else {
- for (int i=0; i<m_elements.size(); ++i) {
- switch (m_element_types.at(i)) {
- case QPainterPath::MoveToElement:
- path.moveTo(m_elements.at(i));
- break;
- case QPainterPath::LineToElement:
- path.lineTo(m_elements.at(i));
- break;
- case QPainterPath::CurveToElement:
- path.cubicTo(m_elements.at(i), m_elements.at(i+1), m_elements.at(i+2));
- i += 2;
- break;
- default:
- Q_ASSERT(false);
- break;
- }
- }
- }
+ const QVectorPath vp((qreal *)m_elements.data(), m_elements.size(), m_element_types.data());
+ QPainterPath path = vp.convertToPainterPath();
path = QTransform(m_m11, m_m12, m_m13, m_m21, m_m22, m_m23, m_dx, m_dy, m_m33).map(path);
uint old_txop = m_txop;
m_txop = QTransform::TxNone;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 3d8e349..d9af3f6 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1675,34 +1675,6 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
QPaintEngineEx::drawRects(rects, rectCount);
}
-void QRasterPaintEnginePrivate::strokeProjective(const QPainterPath &path)
-{
- Q_Q(QRasterPaintEngine);
- QRasterPaintEngineState *s = q->state();
-
- const QPen &pen = s->lastPen;
- QPainterPathStroker pathStroker;
- pathStroker.setWidth(pen.width() == 0 ? qreal(1) : pen.width());
- pathStroker.setCapStyle(pen.capStyle());
- pathStroker.setJoinStyle(pen.joinStyle());
- pathStroker.setMiterLimit(pen.miterLimit());
- pathStroker.setDashOffset(pen.dashOffset());
-
- if (qpen_style(pen) == Qt::CustomDashLine)
- pathStroker.setDashPattern(pen.dashPattern());
- else
- pathStroker.setDashPattern(qpen_style(pen));
-
- outlineMapper->setMatrix(QTransform());
- const QPainterPath stroke = pen.isCosmetic()
- ? pathStroker.createStroke(s->matrix.map(path))
- : s->matrix.map(pathStroker.createStroke(path));
-
- rasterize(outlineMapper->convertPath(stroke), s->penData.blend, &s->penData, rasterBuffer);
- outlinemapper_xform_dirty = true;
-}
-
-
/*!
\internal
@@ -1767,6 +1739,8 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
const QLineF *lines = reinterpret_cast<const QLineF *>(path.points());
for (int i = 0; i < lineCount; ++i) {
+ if (path.shape() == QVectorPath::LinesHint)
+ dashOffset = s->lastPen.dashOffset();
if (lines[i].p1() == lines[i].p2()) {
if (s->lastPen.capStyle() != Qt::FlatCap) {
QPointF p = lines[i].p1();
@@ -1972,67 +1946,6 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
fillRect(r, &d->solid_color_filler);
}
-/*!
- \reimp
-*/
-void QRasterPaintEngine::drawPath(const QPainterPath &path)
-{
-#ifdef QT_DEBUG_DRAW
- QRectF bounds = path.boundingRect();
- qDebug(" - QRasterPaintEngine::drawPath(), [%.2f, %.2f, %.2f, %.2f]",
- bounds.x(), bounds.y(), bounds.width(), bounds.height());
-#endif
-
- if (path.isEmpty())
- return;
-
- // Filling..,
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- ensureBrush();
- if (s->brushData.blend) {
- ensureOutlineMapper();
- fillPath(path, &s->brushData);
- }
-
- // Stroking...
- ensurePen();
- if (!s->penData.blend)
- return;
- {
- if (s->matrix.type() >= QTransform::TxProject) {
- d->strokeProjective(path);
- } else {
- Q_ASSERT(s->stroker);
- d->outlineMapper->beginOutline(Qt::WindingFill);
- qreal txscale = 1;
- if (s->pen.isCosmetic() || (qt_scaleForTransform(s->matrix, &txscale) && txscale != 1)) {
- const qreal strokeWidth = d->basicStroker.strokeWidth();
- const QRectF clipRect = d->dashStroker ? d->dashStroker->clipRect() : QRectF();
- if (d->dashStroker)
- d->dashStroker->setClipRect(d->deviceRect);
- d->basicStroker.setStrokeWidth(strokeWidth * txscale);
- d->outlineMapper->setMatrix(QTransform());
- s->stroker->strokePath(path, d->outlineMapper, s->matrix);
- d->outlinemapper_xform_dirty = true;
- d->basicStroker.setStrokeWidth(strokeWidth);
- if (d->dashStroker)
- d->dashStroker->setClipRect(clipRect);
- } else {
- ensureOutlineMapper();
- s->stroker->strokePath(path, d->outlineMapper, QTransform());
- }
- d->outlineMapper->endOutline();
-
- ProcessSpans blend = d->getPenFunc(d->outlineMapper->controlPointRect,
- &s->penData);
- d->rasterize(d->outlineMapper->outline(), blend, &s->penData, d->rasterBuffer);
- }
- }
-
-}
-
static inline bool isAbove(const QPointF *a, const QPointF *b)
{
return a->y() < b->y();
@@ -3546,8 +3459,8 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
int m22 = int(s->matrix.m22());
int dx = qFloor(s->matrix.dx() + aliasedCoordinateDelta);
int dy = qFloor(s->matrix.dy() + aliasedCoordinateDelta);
- int dashOffset = int(s->lastPen.dashOffset());
for (int i=0; i<lineCount; ++i) {
+ int dashOffset = int(s->lastPen.dashOffset());
if (s->flags.int_xform) {
const QLine &l = lines[i];
int x1 = l.x1() * m11 + dx;
@@ -3646,8 +3559,8 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
? LineDrawNormal
: LineDrawIncludeLastPixel;
- int dashOffset = int(s->lastPen.dashOffset());
for (int i=0; i<lineCount; ++i) {
+ int dashOffset = int(s->lastPen.dashOffset());
QLineF line = (lines[i] * s->matrix).translated(aliasedCoordinateDelta, aliasedCoordinateDelta);
const QRectF brect(QPointF(line.x1(), line.y1()),
QPointF(line.x2(), line.y2()));
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 283c442..3dab491 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -165,7 +165,6 @@ public:
void updateMatrix(const QTransform &matrix);
- void drawPath(const QPainterPath &path);
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
void fillPath(const QPainterPath &path, QSpanData *fillData);
@@ -327,7 +326,6 @@ public:
inline const QClipData *clip() const;
- void strokeProjective(const QPainterPath &path);
void initializeRasterizer(QSpanData *data);
void recalculateFastImages();
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index a71fe52..81dce4f 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -42,6 +42,7 @@
#include "qpaintengineex_p.h"
#include "qpainter_p.h"
#include "qstroker_p.h"
+#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
#include <qvarlengtharray.h>
@@ -91,6 +92,40 @@ QRectF QVectorPath::controlPointRect() const
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}
+QPainterPath QVectorPath::convertToPainterPath() const
+{
+ QPainterPath path;
+
+ if (m_count == 0)
+ return path;
+
+ const QPointF *points = (const QPointF *) m_points;
+
+ if (m_elements) {
+ for (int i=0; i<m_count; ++i) {
+ switch (m_elements[i]) {
+ case QPainterPath::MoveToElement:
+ path.moveTo(points[i]);
+ break;
+ case QPainterPath::LineToElement:
+ path.lineTo(points[i]);
+ break;
+ case QPainterPath::CurveToElement:
+ path.cubicTo(points[i], points[i+1], points[i+2]);
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ path.moveTo(points[0]);
+ for (int i=1; i<m_count; ++i)
+ path.lineTo(points[i]);
+ }
+
+ return path;
+}
+
const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
Q_ASSERT(path.d_func());
@@ -384,7 +419,6 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
const qreal *lastPoint = points + (pointCount<<1);
- d->activeStroker->begin(d->strokeHandler);
d->strokeHandler->types.reset();
d->strokeHandler->pts.reset();
@@ -393,13 +427,13 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
flags |= QVectorPath::CurvedShapeHint;
- // ### Perspective Xforms are currently not supported...
qreal txscale = 1;
if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) {
// 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
// later, so they are also covered here..
+ d->activeStroker->begin(d->strokeHandler);
if (types) {
while (points < lastPoint) {
switch (*types) {
@@ -448,69 +482,75 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
QVectorPath strokePath(d->strokeHandler->pts.data(),
d->strokeHandler->types.size(),
d->strokeHandler->types.data(),
- QVectorPath::WindingFill);
+ flags);
fill(strokePath, pen.brush());
} else {
const qreal strokeWidth = d->stroker.strokeWidth();
d->stroker.setStrokeWidth(strokeWidth * txscale);
// For cosmetic pens we need a bit of trickery... We to process xform the input points
- if (types) {
- while (points < lastPoint) {
- switch (*types) {
- case QPainterPath::MoveToElement: {
- QPointF pt = (*(QPointF *) points) * state()->matrix;
- d->activeStroker->moveTo(pt.x(), pt.y());
- points += 2;
- ++types;
- break;
+ if (state()->matrix.type() >= QTransform::TxProject) {
+ QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
+ d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
+ } else {
+ d->activeStroker->begin(d->strokeHandler);
+ if (types) {
+ while (points < lastPoint) {
+ switch (*types) {
+ case QPainterPath::MoveToElement: {
+ QPointF pt = (*(QPointF *) points) * state()->matrix;
+ d->activeStroker->moveTo(pt.x(), pt.y());
+ points += 2;
+ ++types;
+ break;
+ }
+ case QPainterPath::LineToElement: {
+ QPointF pt = (*(QPointF *) points) * state()->matrix;
+ d->activeStroker->lineTo(pt.x(), pt.y());
+ points += 2;
+ ++types;
+ break;
+ }
+ case QPainterPath::CurveToElement: {
+ QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
+ QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
+ QPointF e = ((QPointF *) points)[2] * state()->matrix;
+ d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
+ points += 6;
+ types += 3;
+ flags |= QVectorPath::CurvedShapeHint;
+ break;
+ }
+ default:
+ break;
+ }
}
- case QPainterPath::LineToElement: {
- QPointF pt = (*(QPointF *) points) * state()->matrix;
+ if (path.hasImplicitClose()) {
+ QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
d->activeStroker->lineTo(pt.x(), pt.y());
- points += 2;
- ++types;
- break;
}
- case QPainterPath::CurveToElement: {
- QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
- QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
- QPointF e = ((QPointF *) points)[2] * state()->matrix;
- d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
- points += 6;
- types += 3;
- flags |= QVectorPath::CurvedShapeHint;
- break;
- }
- default:
- break;
- }
- }
- if (path.hasImplicitClose()) {
- QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
- d->activeStroker->lineTo(pt.x(), pt.y());
- }
- } else {
- QPointF p = ((QPointF *)points)[0] * state()->matrix;
- d->activeStroker->moveTo(p.x(), p.y());
- points += 2;
- ++types;
- while (points < lastPoint) {
+ } else {
QPointF p = ((QPointF *)points)[0] * state()->matrix;
- d->activeStroker->lineTo(p.x(), p.y());
+ d->activeStroker->moveTo(p.x(), p.y());
points += 2;
++types;
+ while (points < lastPoint) {
+ QPointF p = ((QPointF *)points)[0] * state()->matrix;
+ d->activeStroker->lineTo(p.x(), p.y());
+ points += 2;
+ ++types;
+ }
+ if (path.hasImplicitClose())
+ d->activeStroker->lineTo(p.x(), p.y());
}
- if (path.hasImplicitClose())
- d->activeStroker->lineTo(p.x(), p.y());
+ d->activeStroker->end();
}
- d->activeStroker->end();
d->stroker.setStrokeWidth(strokeWidth);
QVectorPath strokePath(d->strokeHandler->pts.data(),
d->strokeHandler->types.size(),
d->strokeHandler->types.data(),
- QVectorPath::WindingFill);
+ flags);
QTransform xform = state()->matrix;
state()->matrix = QTransform();
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index b5301d1..f9fd61e 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -3280,6 +3280,8 @@ void QPainterPath::setDirty(bool dirty)
{
d_func()->dirtyBounds = dirty;
d_func()->dirtyControlBounds = dirty;
+ delete d_func()->pathConverter;
+ d_func()->pathConverter = 0;
}
void QPainterPath::computeBoundingRect() const
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index 7289a6b..47d24b3 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -49,7 +49,7 @@
#include <qdebug.h>
-#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
+#if defined(Q_OS_UNIX) || defined(Q_WS_WIN)
#include "qimage.h"
#include "qbitmap.h"
#include <stdlib.h>
@@ -545,7 +545,7 @@ QRegion& QRegion::operator|=(const QRegion &r)
\sa intersected()
*/
-#if !defined (Q_OS_UNIX) && !defined (Q_OS_WINCE)
+#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
QRegion& QRegion::operator+=(const QRect &r)
{
return operator+=(QRegion(r));
@@ -561,16 +561,14 @@ QRegion& QRegion::operator+=(const QRect &r)
\sa intersected()
*/
-#if !defined(Q_WS_WIN) || defined(Q_OS_WINCE)
QRegion& QRegion::operator&=(const QRegion &r)
{ return *this = *this & r; }
-#endif
/*!
\overload
\since 4.4
*/
-#if defined (Q_OS_UNIX) || defined (Q_OS_WINCE)
+#if defined (Q_OS_UNIX) || defined (Q_WS_WIN)
QRegion& QRegion::operator&=(const QRect &r)
{
return *this = *this & r;
@@ -591,10 +589,8 @@ QRegion& QRegion::operator&=(const QRect &r)
\sa subtracted()
*/
-#if !defined(Q_WS_WIN) || defined(Q_OS_WINCE)
QRegion& QRegion::operator-=(const QRegion &r)
{ return *this = *this - r; }
-#endif
/*!
Applies the xored() function to this region and \a r and
@@ -731,7 +727,7 @@ bool QRegion::intersects(const QRect &rect) const
return false;
}
-#if !defined (Q_OS_UNIX) && !defined (Q_OS_WINCE)
+#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
/*!
\overload
\since 4.4
@@ -1086,7 +1082,7 @@ Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region)
return result;
}
-#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
+#if defined(Q_OS_UNIX) || defined(Q_WS_WIN)
//#define QT_REGION_DEBUG
/*
@@ -1627,9 +1623,9 @@ QT_END_INCLUDE_NAMESPACE
QT_BEGIN_INCLUDE_NAMESPACE
# include "qregion_mac.cpp"
QT_END_INCLUDE_NAMESPACE
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
QT_BEGIN_INCLUDE_NAMESPACE
-# include "qregion_wince.cpp"
+# include "qregion_win.cpp"
QT_END_INCLUDE_NAMESPACE
#elif defined(Q_WS_QWS)
static QRegionPrivate qrp;
@@ -3846,7 +3842,7 @@ QRegion::QRegion(const QRect &r, RegionType t)
#if defined(Q_WS_X11)
d->rgn = 0;
d->xrectangles = 0;
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
d->rgn = 0;
#endif
if (t == Rectangle) {
@@ -3868,7 +3864,7 @@ QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)
#if defined(Q_WS_X11)
d->rgn = 0;
d->xrectangles = 0;
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
d->rgn = 0;
#endif
d->qt_rgn = PolygonRegion(a.constData(), a.size(),
@@ -3898,7 +3894,7 @@ QRegion::QRegion(const QBitmap &bm)
#if defined(Q_WS_X11)
d->rgn = 0;
d->xrectangles = 0;
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
d->rgn = 0;
#endif
d->qt_rgn = qt_bitmapToRegion(bm);
@@ -3913,7 +3909,7 @@ void QRegion::cleanUp(QRegion::QRegionData *x)
XDestroyRegion(x->rgn);
if (x->xrectangles)
free(x->xrectangles);
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
if (x->rgn)
qt_win_dispose_rgn(x->rgn);
#endif
@@ -3948,7 +3944,7 @@ QRegion QRegion::copy() const
#if defined(Q_WS_X11)
x->rgn = 0;
x->xrectangles = 0;
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_WS_WIN)
x->rgn = 0;
#endif
if (d->qt_rgn)
diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h
index 61a0623..8a56d54 100644
--- a/src/gui/painting/qregion.h
+++ b/src/gui/painting/qregion.h
@@ -59,7 +59,7 @@ QT_MODULE(Gui)
template <class T> class QVector;
class QVariant;
-#if defined(Q_WS_QWS) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
struct QRegionPrivate;
#endif
@@ -148,6 +148,7 @@ public:
#elif defined(Q_WS_MAC)
#if defined Q_WS_MAC32
RgnHandle toQDRgn() const;
+ RgnHandle toQDRgnForUpdate_sys() const;
static QRegion fromQDRgn(RgnHandle shape);
#endif
#ifdef QT_MAC_USE_COCOA
@@ -199,7 +200,7 @@ private:
#elif defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
mutable RgnHandle unused; // Here for binary compatability reasons. ### Qt 5 remove.
#endif
-#if defined(Q_WS_QWS) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
QRegionPrivate *qt_rgn;
#endif
};
diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp
index b57f234..9b0e99f 100644
--- a/src/gui/painting/qregion_mac.cpp
+++ b/src/gui/painting/qregion_mac.cpp
@@ -155,6 +155,44 @@ RgnHandle QRegion::toQDRgn() const
}
return rgnHandle;
}
+
+/*!
+ \internal
+ Create's a RegionHandle, it's the caller's responsibility to release.
+ Returns 0 if the QRegion overflows.
+*/
+RgnHandle QRegion::toQDRgnForUpdate_sys() const
+{
+ RgnHandle rgnHandle = qt_mac_get_rgn();
+ if(d->qt_rgn && d->qt_rgn->numRects) {
+ RgnHandle tmp_rgn = qt_mac_get_rgn();
+ int n = d->qt_rgn->numRects;
+ const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
+ while (n--) {
+
+ // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion
+ // in QWidgetPrivate::update_sys().
+ enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value
+ qDebug() << qt_r->x() << qt_r->y() << qt_r->right() << qt_r->bottom();
+ if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) {
+ qt_mac_dispose_rgn(tmp_rgn);
+ qt_mac_dispose_rgn(rgnHandle);
+ return 0;
+ }
+
+ SetRectRgn(tmp_rgn,
+ qMax(SHRT_MIN, qt_r->x()),
+ qMax(SHRT_MIN, qt_r->y()),
+ qMin(SHRT_MAX, qt_r->right() + 1),
+ qMin(SHRT_MAX, qt_r->bottom() + 1));
+ UnionRgn(rgnHandle, tmp_rgn, rgnHandle);
+ ++qt_r;
+ }
+ qt_mac_dispose_rgn(tmp_rgn);
+ }
+ return rgnHandle;
+}
+
#endif
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
diff --git a/src/gui/painting/qregion_win.cpp b/src/gui/painting/qregion_win.cpp
index 249b1a6..2d5e76b 100644
--- a/src/gui/painting/qregion_win.cpp
+++ b/src/gui/painting/qregion_win.cpp
@@ -39,27 +39,25 @@
**
****************************************************************************/
+#include "qatomic.h"
#include "qbitmap.h"
#include "qbuffer.h"
#include "qimage.h"
#include "qpolygon.h"
#include "qregion.h"
#include "qt_windows.h"
+#include "qpainterpath.h"
+#include "qguifunctions_wince.h"
QT_BEGIN_NAMESPACE
+QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 };
-/*
- In Windows versions before Windows Vista CreateRectRgn - when called in a multi-threaded
- environment - might return an invalid handle. This function works around this limitation
- by verifying the handle with a quick GetRegionData() call and re-creates the region
- if necessary.
-*/
HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom)
{
const int tries = 10;
for (int i = 0; i < tries; ++i) {
- HRGN region = 0;
+ HRGN region;
switch (type) {
case QRegion::Rectangle:
region = CreateRectRgn(left, top, right, bottom);
@@ -80,497 +78,73 @@ HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right,
return 0;
}
-#ifndef Q_OS_WINCE
-HRGN qt_tryCreatePolygonRegion(const QPolygon &a, Qt::FillRule fillRule)
-{
- const int tries = 10;
- for (int i = 0; i < tries; ++i) {
- HRGN region = CreatePolygonRgn(reinterpret_cast<const POINT*>(a.data()), a.size(),
- fillRule == Qt::OddEvenFill ? ALTERNATE : WINDING);
- if (region) {
- if (GetRegionData(region, 0, 0))
- return region;
- else
- DeleteObject(region);
- }
- }
- return 0;
-}
-#endif
-
-QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
-
-QRegion::QRegion()
- : d(&shared_empty)
-{
- d->ref.ref();
-}
-
-#ifndef Q_OS_WINCE //implementation for WindowsCE in qregion_wce.cpp
-QRegion::QRegion(const QRect &r, RegionType t)
-{
- if (r.isEmpty()) {
- d = &shared_empty;
- d->ref.ref();
- } else {
- d = new QRegionData;
- d->ref = 1;
- if (t == Rectangle)
- d->rgn = qt_tryCreateRegion(t, r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
- else if (t == Ellipse) {
- // need to add 1 to width/height for the ellipse to have correct boundingrect.
- d->rgn = qt_tryCreateRegion(t, r.x(), r.y(), r.x() + r.width() + 1, r.y() + r.height() + 1);
- }
- }
-}
-#endif
-
-#ifndef Q_OS_WINCE //implementation for WindowsCE in qregion_wce.cpp
-QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)
-{
- if (a.size() < 3) {
- d = &shared_empty;
- d->ref.ref();
- } else {
- d = new QRegionData;
- d->ref = 1;
- d->rgn = qt_tryCreatePolygonRegion(a, fillRule);
- }
-}
-#endif
-
-QRegion::QRegion(const QRegion &r)
-{
- d = r.d;
- d->ref.ref();
-}
-
-HRGN qt_win_bitmapToRegion(const QBitmap& bitmap)
-{
- HRGN region=0;
- QImage image = bitmap.toImage();
- const int MAXRECT = 256;
- struct RData {
- RGNDATAHEADER header;
- RECT rect[MAXRECT];
- };
- RData data;
-
-#define FlushSpans \
- { \
- data.header.dwSize = sizeof(RGNDATAHEADER); \
- data.header.iType = RDH_RECTANGLES; \
- data.header.nCount = n; \
- data.header.nRgnSize = 0; \
- data.header.rcBound.bottom = y; \
- HRGN r = ExtCreateRegion(0, \
- sizeof(RGNDATAHEADER)+n*sizeof(RECT),(RGNDATA*)&data); \
- if (region) { \
- CombineRgn(region, region, r, RGN_OR); \
- DeleteObject(r); \
- } else { \
- region = r; \
- } \
- data.header.rcBound.top = y; \
- }
-
-#define AddSpan \
- { \
- data.rect[n].left=prev1; \
- data.rect[n].top=y; \
- data.rect[n].right=x-1+1; \
- data.rect[n].bottom=y+1; \
- n++; \
- if (n == MAXRECT) { \
- FlushSpans \
- n=0; \
- } \
- }
-
- data.header.rcBound.top = 0;
- data.header.rcBound.left = 0;
- data.header.rcBound.right = image.width()-1;
- int n = 0;
-
- int zero = 0x00;
-
- int x, y;
- for (y = 0; y < image.height(); ++y) {
- uchar *line = image.scanLine(y);
- int w = image.width();
- uchar all=zero;
- int prev1 = -1;
- for (x = 0; x < w;) {
- uchar byte = line[x/8];
- if (x > w - 8 || byte != all) {
- for (int b = 8; b > 0 && x < w; --b) {
- if (!(byte & 0x01) == !all) {
- // More of the same
- } else {
- // A change.
- if (all != zero) {
- AddSpan;
- all = zero;
- } else {
- prev1 = x;
- all = ~zero;
- }
- }
- byte >>= 1;
- ++x;
- }
- } else {
- x += 8;
- }
- }
- if (all != zero) {
- AddSpan;
- }
- }
- if (n) {
- FlushSpans;
- }
-
- if (!region) {
- // Surely there is some better way.
- region = qt_tryCreateRegion(QRegion::Rectangle, 0,0,1,1);
- CombineRgn(region, region, region, RGN_XOR);
- }
- return region;
-}
-
-#ifndef Q_OS_WINCE //implementation for WindowsCE in qregion_wce.cpp
-QRegion::QRegion(const QBitmap &bm)
-{
- if (bm.isNull()) {
- d = &shared_empty;
- d->ref.ref();
- } else {
- d = new QRegionData;
- d->ref = 1;
- d->rgn = qt_win_bitmapToRegion(bm);
- }
-}
-#endif
-
-void QRegion::cleanUp(QRegion::QRegionData *x)
-{
- if (x->rgn)
- DeleteObject(x->rgn);
- delete x;
-}
-
-QRegion::~QRegion()
-{
- if (!d->ref.deref())
- cleanUp(d);
-}
-
-QRegion &QRegion::operator=(const QRegion &r)
-{
- r.d->ref.ref();
- if (!d->ref.deref())
- cleanUp(d);
- d = r.d;
- return *this;
-}
-
-
-QRegion QRegion::copy() const
-{
- QRegion r;
- QRegionData *x = new QRegionData;
- x->ref = 1;
- if (d->rgn) {
- x->rgn = qt_tryCreateRegion(QRegion::Rectangle, 0, 0, 2, 2);
- CombineRgn(x->rgn, d->rgn, 0, RGN_COPY);
- } else {
- x->rgn = 0;
- }
- if (!r.d->ref.deref())
- cleanUp(r.d);
- r.d = x;
- return r;
-}
-
-bool QRegion::isEmpty() const
-{
- return (d == &shared_empty || boundingRect().isEmpty());
-}
-
-
-bool QRegion::contains(const QPoint &p) const
-{
- return d->rgn ? PtInRegion(d->rgn, p.x(), p.y()) : false;
-}
-
-bool QRegion::contains(const QRect &r) const
-{
- if (!d->rgn)
- return false;
- RECT rect;
- SetRect(&rect, r.left(), r.top(), r.right(), r.bottom());
- return RectInRegion(d->rgn, &rect);
-}
-
-
-void QRegion::translate(int dx, int dy)
-{
- if (!d->rgn || (dx == 0 && dy == 0))
- return;
- detach();
- OffsetRgn(d->rgn, dx, dy);
-}
-
-
-#define RGN_NOP -1
-
-// Duplicates of those in qregion.cpp
-#define QRGN_OR 6
-#define QRGN_AND 7
-#define QRGN_SUB 8
-#define QRGN_XOR 9
-
-/*
- Performs the actual OR, AND, SUB and XOR operation between regions.
- Sets the resulting region handle to 0 to indicate an empty region.
-*/
-
-QRegion QRegion::winCombine(const QRegion &r, int op) const
+QRegion qt_region_from_HRGN(HRGN rgn)
{
- int both=RGN_NOP,
- left=RGN_NOP,
- right=RGN_NOP;
- switch (op) {
- case QRGN_OR:
- both = RGN_OR;
- left = right = RGN_COPY;
- break;
- case QRGN_AND:
- both = RGN_AND;
- break;
- case QRGN_SUB:
- both = RGN_DIFF;
- left = RGN_COPY;
- break;
- case QRGN_XOR:
- both = RGN_XOR;
- left = right = RGN_COPY;
- break;
- default:
- qWarning("QRegion: Internal error in winCombine");
- }
-
- int allCombineRgnResults = NULLREGION;
- QRegion result;
- result.detach();
- result.d->rgn = qt_tryCreateRegion(QRegion::Rectangle, 0, 0, 0, 0);
- if (d->rgn && r.d->rgn)
- allCombineRgnResults = CombineRgn(result.d->rgn, d->rgn, r.d->rgn, both);
- else if (d->rgn && left != RGN_NOP)
- allCombineRgnResults = CombineRgn(result.d->rgn, d->rgn, d->rgn, left);
- else if (r.d->rgn && right != RGN_NOP)
- allCombineRgnResults = CombineRgn(result.d->rgn, r.d->rgn, r.d->rgn, right);
-
- if (allCombineRgnResults == NULLREGION || allCombineRgnResults == ERROR)
- result = QRegion();
-
- //##### do not delete this. A null pointer is different from an empty region in SelectClipRgn in qpainter_win! (M)
-// if (allCombineRgnResults == NULLREGION) {
-// if (result.data->rgn)
-// DeleteObject(result.data->rgn);
-// result.data->rgn = 0; // empty region
-// }
- return result;
-}
-
-QRegion QRegion::unite(const QRegion &r) const
-{
- if (!d->rgn)
- return r;
- if (!r.d->rgn)
- return *this;
- return winCombine(r, QRGN_OR);
-}
-
-QRegion QRegion::unite(const QRect &r) const
-{
- return unite(QRegion(r));
-}
-
-QRegion QRegion::intersect(const QRegion &r) const
-{
- if (!r.d->rgn || !d->rgn)
- return QRegion();
- return winCombine(r, QRGN_AND);
-}
-
-QRegion QRegion::subtract(const QRegion &r) const
-{
- if (!r.d->rgn || !d->rgn)
- return *this;
- return winCombine(r, QRGN_SUB);
-}
-
-QRegion QRegion::eor(const QRegion &r) const
-{
- if (!d->rgn)
- return r;
- if (!r.d->rgn)
- return *this;
- return winCombine(r, QRGN_XOR);
-}
-
-
-QRect QRegion::boundingRect() const
-{
- if (!d->rgn)
- return QRect();
- RECT r;
- if (GetRgnBox(d->rgn, &r) == NULLREGION)
- return QRect();
- else
- return QRect(r.left, r.top, r.right - r.left, r.bottom - r.top);
-}
-
-QVector<QRect> QRegion::rects() const
-{
- if (d->rgn == 0)
- return QVector<QRect>();
-
- int numBytes = GetRegionData(d->rgn, 0, 0);
+ int numBytes = GetRegionData(rgn, 0, 0);
if (numBytes == 0)
- return QVector<QRect>();
+ return QRegion();
char *buf = new char[numBytes];
if (buf == 0)
- return QVector<QRect>();
+ return QRegion();
RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf);
- if (GetRegionData(d->rgn, numBytes, rd) == 0) {
+ if (GetRegionData(rgn, numBytes, rd) == 0) {
delete [] buf;
- return QVector<QRect>();
+ return QRegion();
}
- QVector<QRect> a(rd->rdh.nCount);
+ QRegion region;
RECT *r = reinterpret_cast<RECT*>(rd->Buffer);
- for (int i = 0; i < a.size(); ++i) {
- a[i].setCoords(r->left, r->top, r->right - 1, r->bottom - 1);
+ for (int i = 0; i < rd->rdh.nCount; ++i) {
+ QRect rect;
+ rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1);
++r;
+ region |= rect;
}
delete [] buf;
- return a;
-}
-
-void QRegion::setRects(const QRect *rects, int num)
-{
- *this = QRegion();
- if (!rects || num == 0 || (num == 1 && rects->isEmpty()))
- return;
- for (int i = 0; i < num; ++i)
- *this |= rects[i];
-}
-
-int QRegion::numRects() const
-{
- if (d->rgn == 0)
- return 0;
-
- const int numBytes = GetRegionData(d->rgn, 0, 0);
- if (numBytes == 0)
- return 0;
-
- char *buf = new char[numBytes];
- if (buf == 0)
- return 0;
-
- RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf);
- if (GetRegionData(d->rgn, numBytes, rd) == 0) {
- delete[] buf;
- return 0;
- }
-
- const int n = rd->rdh.nCount;
- delete[] buf;
- return n;
+ return region;
}
-bool QRegion::operator==(const QRegion &r) const
+void qt_win_dispose_rgn(HRGN r)
{
- if (d == r.d)
- return true;
- if ((d->rgn == 0) ^ (r.d->rgn == 0)) // one is empty, not both
- return false;
- return d->rgn == 0 ? true // both empty
- : EqualRgn(d->rgn, r.d->rgn); // both non-empty
+ if (r)
+ DeleteObject(r);
}
-QRegion& QRegion::operator+=(const QRegion &r)
+static void qt_add_rect(HRGN &winRegion, QRect r)
{
- if (!r.d->rgn)
- return *this;
-
- if (!d->rgn) {
- *this = r;
- return *this;
+ HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
+ if (rgn) {
+ HRGN dest = CreateRectRgn(0,0,0,0);
+ int result = CombineRgn(dest, winRegion, rgn, RGN_OR);
+ if (result) {
+ DeleteObject(winRegion);
+ winRegion = dest;
+ }
+ DeleteObject(rgn);
}
-
- detach();
-
- int result;
- result = CombineRgn(d->rgn, d->rgn, r.d->rgn, RGN_OR);
- if (result == NULLREGION || result == ERROR)
- *this = QRegion();
-
- return *this;
-}
-
-QRegion& QRegion::operator-=(const QRegion &r)
-{
- if (!r.d->rgn || !d->rgn)
- return *this;
-
- detach();
-
- int result;
- result = CombineRgn(d->rgn, d->rgn, r.d->rgn, RGN_DIFF);
- if (result == NULLREGION || result == ERROR)
- *this = QRegion();
-
- return *this;
}
-QRegion& QRegion::operator&=(const QRegion &r)
+void QRegion::ensureHandle() const
{
- if (!d->rgn)
- return *this;
-
- if (!r.d->rgn) {
- *this = QRegion();
- return *this;
+ if (d->rgn)
+ DeleteObject(d->rgn);
+ d->rgn = CreateRectRgn(0,0,0,0);
+ if (d->qt_rgn) {
+ if (d->qt_rgn->numRects == 1) {
+ QRect r = d->qt_rgn->extents;
+ qt_add_rect(d->rgn, r);
+ return;
+ }
+ for (int i = 0;i < d->qt_rgn->numRects;i++) {
+ QRect r = d->qt_rgn->rects.at(i);
+ qt_add_rect(d->rgn, r);
+ }
}
-
- detach();
-
- int result;
- result = CombineRgn(d->rgn, d->rgn, r.d->rgn, RGN_AND);
- if (result == NULLREGION || result == ERROR)
- *this = QRegion();
-
- return *this;
-}
-
-bool qt_region_strictContains(const QRegion &region, const QRect &rect)
-{
- Q_UNUSED(region);
- Q_UNUSED(rect);
- return false;
}
-void QRegion::ensureHandle() const
-{
-}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qregion_wince.cpp b/src/gui/painting/qregion_wince.cpp
deleted file mode 100644
index 9c33123..0000000
--- a/src/gui/painting/qregion_wince.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://www.qtsoftware.com/contact.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qatomic.h"
-#include "qbitmap.h"
-#include "qbuffer.h"
-#include "qimage.h"
-#include "qpolygon.h"
-#include "qregion.h"
-#include "qt_windows.h"
-#include "qpainterpath.h"
-#include "qguifunctions_wince.h"
-
-QT_BEGIN_NAMESPACE
-
-QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 };
-
-HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom)
-{
- const int tries = 10;
- for (int i = 0; i < tries; ++i) {
- HRGN region;
- switch (type) {
- case QRegion::Rectangle:
- region = CreateRectRgn(left, top, right, bottom);
- break;
- case QRegion::Ellipse:
-#ifndef Q_OS_WINCE
- region = CreateEllipticRgn(left, top, right, bottom);
-#endif
- break;
- }
- if (region) {
- if (GetRegionData(region, 0, 0))
- return region;
- else
- DeleteObject(region);
- }
- }
- return 0;
-}
-
-void qt_win_dispose_rgn(HRGN r)
-{
- if (r)
- DeleteObject(r);
-}
-
-static void qt_add_rect(HRGN &winRegion, QRect r)
-{
- HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
- if (rgn) {
- HRGN dest = CreateRectRgn(0,0,0,0);
- int result = CombineRgn(dest, winRegion, rgn, RGN_OR);
- if (result) {
- DeleteObject(winRegion);
- winRegion = dest;
- }
- }
-}
-
-void QRegion::ensureHandle() const
-{
- if (d->rgn)
- DeleteObject(d->rgn);
- d->rgn = CreateRectRgn(0,0,0,0);
- if (d->qt_rgn) {
- if (d->qt_rgn->numRects == 1) {
- QRect r = d->qt_rgn->extents;
- qt_add_rect(d->rgn, r);
- return;
- }
- for (int i = 0;i < d->qt_rgn->numRects;i++) {
- QRect r = d->qt_rgn->rects.at(i);
- qt_add_rect(d->rgn, r);
- }
- }
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 6968f4e..a34c354 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -60,6 +60,10 @@
#include <private/qfontengineglyphcache_p.h>
+#if defined(Q_OS_VXWORKS) && defined(m_type)
+# undef m_type
+#endif
+
struct glyph_metrics_t;
typedef unsigned int glyph_t;
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index a322fe4..0a64e4e 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -48,6 +48,8 @@
#include "qvariant.h"
#include <qmath.h>
+#include <private/qbezier_p.h>
+
QT_BEGIN_NAMESPACE
#define Q_NEAR_CLIP 0.000001
@@ -1492,27 +1494,12 @@ static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transfor
static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo)
{
- const QHomogeneousCoordinate ha = mapHomogeneous(transform, a);
- const QHomogeneousCoordinate hb = mapHomogeneous(transform, b);
- const QHomogeneousCoordinate hc = mapHomogeneous(transform, c);
- const QHomogeneousCoordinate hd = mapHomogeneous(transform, d);
-
- if (ha.w < Q_NEAR_CLIP && hb.w < Q_NEAR_CLIP && hc.w < Q_NEAR_CLIP && hd.w < Q_NEAR_CLIP)
- return false;
+ // Convert projective xformed curves to line
+ // segments so they can be transformed more accurately
+ QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon();
- if (ha.w >= Q_NEAR_CLIP && hb.w >= Q_NEAR_CLIP && hc.w >= Q_NEAR_CLIP && hd.w >= Q_NEAR_CLIP) {
- if (needsMoveTo)
- path.moveTo(ha.toPoint());
-
- path.cubicTo(hb.toPoint(), hc.toPoint(), hd.toPoint());
- return true;
- }
-
- if (lineTo_clipped(path, transform, a, b, needsMoveTo))
- needsMoveTo = false;
- if (lineTo_clipped(path, transform, b, c, needsMoveTo))
- needsMoveTo = false;
- if (lineTo_clipped(path, transform, c, d, needsMoveTo))
+ for (int i = 0; i < segment.size() - 1; ++i)
+ if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo))
needsMoveTo = false;
return !needsMoveTo;
@@ -1793,6 +1780,14 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13,
m_dirty = TxProject;
}
+static inline bool needsPerspectiveClipping(const QRectF &rect, const QTransform &transform)
+{
+ const qreal wx = qMin(transform.m13() * rect.left(), transform.m13() * rect.right());
+ const qreal wy = qMin(transform.m23() * rect.top(), transform.m23() * rect.bottom());
+
+ return wx + wy + transform.m33() < Q_NEAR_CLIP;
+}
+
QRect QTransform::mapRect(const QRect &rect) const
{
TransformationType t = inline_type();
@@ -1813,7 +1808,7 @@ QRect QTransform::mapRect(const QRect &rect) const
y -= h;
}
return QRect(x, y, w, h);
- } else {
+ } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) {
// see mapToPolygon for explanations of the algorithm.
qreal x = 0, y = 0;
MAP(rect.left(), rect.top(), x, y);
@@ -1837,6 +1832,10 @@ QRect QTransform::mapRect(const QRect &rect) const
xmax = qMax(xmax, x);
ymax = qMax(ymax, y);
return QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
+ } else {
+ QPainterPath path;
+ path.addRect(rect);
+ return map(path).boundingRect().toRect();
}
}
@@ -1879,7 +1878,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const
y -= h;
}
return QRectF(x, y, w, h);
- } else {
+ } else if (t < TxProject || !needsPerspectiveClipping(rect, *this)) {
qreal x = 0, y = 0;
MAP(rect.x(), rect.y(), x, y);
qreal xmin = x;
@@ -1902,6 +1901,10 @@ QRectF QTransform::mapRect(const QRectF &rect) const
xmax = qMax(xmax, x);
ymax = qMax(ymax, y);
return QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
+ } else {
+ QPainterPath path;
+ path.addRect(rect);
+ return map(path).boundingRect();
}
}
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index 291d35c..69d4de2 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -50,6 +50,10 @@
#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
+#if defined(Q_OS_VXWORKS) && defined(m_type)
+# undef m_type
+#endif
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index e3cb333..df49500 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.h
@@ -130,6 +130,8 @@ public:
static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode);
+ QPainterPath convertToPainterPath() const;
+
private:
Q_DISABLE_COPY(QVectorPath)
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 63b39b2..863237b 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -116,7 +116,7 @@ QPaintDevice *QRasterWindowSurface::paintDevice()
void QRasterWindowSurface::beginPaint(const QRegion &rgn)
{
#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE))
- if (!qt_widget_private(window())->isOpaque) {
+ if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) {
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied)
prepareBuffer(QImage::Format_ARGB32_Premultiplied, window());
@@ -147,7 +147,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
QRect br = rgn.boundingRect();
#ifndef Q_WS_WINCE
- if (!qt_widget_private(window())->isOpaque) {
+ if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) {
QRect r = window()->frameGeometry();
QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft();
QRect dirtyRect = br.translated(offset + frameOffset);
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
index d8b0d9e..95f6ce3 100644
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ b/src/gui/painting/qwindowsurface_x11.cpp
@@ -154,7 +154,7 @@ void QX11WindowSurface::setGeometry(const QRect &rect)
QX11PixmapData *oldData = static_cast<QX11PixmapData *>(d_ptr->device.pixmapData());
Q_ASSERT(oldData);
- if (!oldData->uninit && hasStaticContents()) {
+ if (!(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) {
// Copy the content of the old pixmap into the new one.
QX11PixmapData *newData = new QX11PixmapData(QPixmapData::PixmapType);
newData->resize(size.width(), size.height());
@@ -175,7 +175,7 @@ void QX11WindowSurface::setGeometry(const QRect &rect)
dx, dy, qMin(boundingRect.width(), size.width()),
qMin(boundingRect.height(), size.height()), dx, dy);
XFreeGC(X11->display, tmpGc);
- newData->uninit = false;
+ newData->flags &= ~QX11PixmapData::Uninitialized;
d_ptr->device = QPixmap(newData);
} else {