summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-11-06 11:27:37 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-11-06 11:27:37 (GMT)
commit7515e36b6351e588b5324fe7be9bf4505b156793 (patch)
treea101d874ae1d3e0f219bac393fcbca3f956c8857 /src
parente219feca14eb96a39d38694edfcc810ed94539ff (diff)
parent5ab96eb2df98bf7f0c8e7d7e676e548f15c2f4a3 (diff)
downloadQt-7515e36b6351e588b5324fe7be9bf4505b156793.zip
Qt-7515e36b6351e588b5324fe7be9bf4505b156793.tar.gz
Qt-7515e36b6351e588b5324fe7be9bf4505b156793.tar.bz2
Merge commit 'upstream/4.6' into 4.6
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfile.cpp29
-rw-r--r--src/corelib/io/qfsfileengine.cpp17
-rw-r--r--src/corelib/io/qfsfileengine_p.h10
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp37
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp153
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp82
6 files changed, 181 insertions, 147 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 134c4b8..c9b2603 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -1020,14 +1020,15 @@ bool QFile::open(OpenMode mode)
\bold{Warning:}
\list 1
- \o If \a fh is \c stdin, \c stdout, or \c stderr, you may not be able
- to seek(). See QIODevice::isSequential() for more information.
+ \o If \a fh does not refer to a regular file, e.g., it is \c stdin,
+ \c stdout, or \c stderr, you may not be able to seek(). size()
+ returns \c 0 in those cases. See QIODevice::isSequential() for
+ more information.
\o Since this function opens the file without specifying the file name,
you cannot use this QFile with a QFileInfo.
\endlist
- \note For Windows CE you may not be able to call seek() and resize().
- Also, size() is set to \c 0.
+ \note For Windows CE you may not be able to call resize().
\sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
@@ -1064,7 +1065,7 @@ bool QFile::open(FILE *fh, OpenMode mode)
if (mode & Append) {
seek(size());
} else {
- long pos = ftell(fh);
+ qint64 pos = (qint64)QT_FTELL(fh);
if (pos != -1)
seek(pos);
}
@@ -1081,7 +1082,7 @@ bool QFile::open(FILE *fh, OpenMode mode)
/*!
\overload
- Opens the existing file descripter \a fd in the given \a mode.
+ Opens the existing file descriptor \a fd in the given \a mode.
Returns true if successful; otherwise returns false.
When a QFile is opened using this function, close() does not
@@ -1092,12 +1093,13 @@ bool QFile::open(FILE *fh, OpenMode mode)
are slow. If you run into performance issues, you should try to
use one of the other open functions.
- \warning If \a fd is 0 (\c stdin), 1 (\c stdout), or 2 (\c
- stderr), you may not be able to seek(). size() is set to \c
- LLONG_MAX (in \c <climits>).
+ \warning If \a fd is not a regular file, e.g, it is 0 (\c stdin),
+ 1 (\c stdout), or 2 (\c stderr), you may not be able to seek(). In
+ those cases, size() returns \c 0. See QIODevice::isSequential()
+ for more information.
\warning For Windows CE you may not be able to call seek(), setSize(),
- fileTime(). size() is set to \c 0.
+ fileTime(). size() returns \c 0.
\warning Since this function opens the file without specifying the file name,
you cannot use this QFile with a QFileInfo.
@@ -1120,8 +1122,13 @@ bool QFile::open(int fd, OpenMode mode)
}
if(d->openExternalFile(mode, fd)) {
QIODevice::open(mode);
- if (mode & Append)
+ if (mode & Append) {
seek(size());
+ } else {
+ qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR);
+ if (pos != -1)
+ seek(pos);
+ }
return true;
}
return false;
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index b69a5e5..d376dc7 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -132,11 +132,9 @@ void QFSFileEnginePrivate::init()
#ifdef Q_OS_WIN
fileAttrib = INVALID_FILE_ATTRIBUTES;
fileHandle = INVALID_HANDLE_VALUE;
+ mapHandle = INVALID_HANDLE_VALUE;
cachedFd = -1;
#endif
-#ifdef Q_USE_DEPRECATED_MAP_API
- fileMapHandle = INVALID_HANDLE_VALUE;
-#endif
}
/*!
@@ -329,9 +327,9 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
int ret;
do {
ret = QT_FSEEK(fh, 0, SEEK_END);
- } while (ret == -1 && errno == EINTR);
+ } while (ret != 0 && errno == EINTR);
- if (ret == -1) {
+ if (ret != 0) {
q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
qt_error_string(int(errno)));
@@ -576,20 +574,23 @@ bool QFSFileEnginePrivate::seekFdFh(qint64 pos)
if (lastIOCommand != QFSFileEnginePrivate::IOFlushCommand && !q->flush())
return false;
+ if (pos < 0 || pos != qint64(QT_OFF_T(pos)))
+ return false;
+
if (fh) {
// Buffered stdlib mode.
int ret;
do {
ret = QT_FSEEK(fh, QT_OFF_T(pos), SEEK_SET);
- } while (ret == -1 && errno == EINTR);
+ } while (ret != 0 && errno == EINTR);
- if (ret == -1) {
+ if (ret != 0) {
q->setError(QFile::ReadError, qt_error_string(int(errno)));
return false;
}
} else {
// Unbuffered stdio mode.
- if (QT_LSEEK(fd, pos, SEEK_SET) == -1) {
+ if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) {
qWarning() << "QFile::at: Cannot set file position" << pos;
q->setError(QFile::PositionError, qt_error_string(errno));
return false;
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 66e0219..87f0737 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -110,20 +110,16 @@ public:
FILE *fh;
#ifdef Q_WS_WIN
HANDLE fileHandle;
- QHash<uchar *, QPair<int /*offset*/, HANDLE /*handle*/> > maps;
+ HANDLE mapHandle;
+ QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps;
mutable int cachedFd;
mutable DWORD fileAttrib;
#else
- QHash<uchar *, QPair<int /*offset*/, int /*handle|len*/> > maps;
+ QHash<uchar *, QPair<int /*offset % PageSize*/, size_t /*length + offset % PageSize*/> > maps;
mutable QT_STATBUF st;
#endif
int fd;
-#ifdef Q_USE_DEPRECATED_MAP_API
- void mapHandleClose();
- HANDLE fileMapHandle;
-#endif
-
enum LastIOCommand
{
IOFlushCommand,
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index b0cddaa..7824520 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -1243,34 +1243,51 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
q->setError(QFile::PermissionsError, qt_error_string(int(EACCES)));
return 0;
}
- if (offset < 0) {
+
+ if (offset < 0 || offset != qint64(QT_OFF_T(offset))
+ || size < 0 || size > (size_t)-1) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;
}
+
+ // If we know the mapping will extend beyond EOF, fail early to avoid
+ // undefined behavior. Otherwise, let mmap have its say.
+ if (doStat()
+ && (QT_OFF_T(size) > st.st_size - QT_OFF_T(offset)))
+ return 0;
+
int access = 0;
if (openMode & QIODevice::ReadOnly) access |= PROT_READ;
if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE;
- int pagesSize = getpagesize();
- int realOffset = offset / pagesSize;
- int extra = offset % pagesSize;
+ int pageSize = getpagesize();
+ int extra = offset % pageSize;
+
+ if (size + extra > (size_t)-1) {
+ q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
+ return 0;
+ }
+
+ size_t realSize = (size_t)size + extra;
+ QT_OFF_T realOffset = QT_OFF_T(offset);
+ realOffset &= ~(QT_OFF_T(pageSize - 1));
#ifdef Q_OS_SYMBIAN
void *mapAddress;
- TRAPD(err, mapAddress = mmap((void*)0, (size_t)size + extra,
- access, MAP_SHARED, nativeHandle(), realOffset * pagesSize));
+ TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize,
+ access, MAP_SHARED, nativeHandle(), realOffset));
if (err != KErrNone) {
qWarning("OpenC bug: leave from mmap %d", err);
mapAddress = MAP_FAILED;
errno = EINVAL;
}
#else
- void *mapAddress = mmap((void*)0, (size_t)size + extra,
- access, MAP_SHARED, nativeHandle(), realOffset * pagesSize);
+ void *mapAddress = QT_MMAP((void*)0, realSize,
+ access, MAP_SHARED, nativeHandle(), realOffset);
#endif
if (MAP_FAILED != mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
- maps[address] = QPair<int,int>(extra, size);
+ maps[address] = QPair<int,size_t>(extra, realSize);
return address;
}
@@ -1300,7 +1317,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
}
uchar *start = ptr - maps[ptr].first;
- int len = maps[ptr].second;
+ size_t len = maps[ptr].second;
if (-1 == munmap(start, len)) {
q->setError(QFile::UnspecifiedError, qt_error_string(errno));
return false;
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 898447c..a6cb5a9 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -455,17 +455,10 @@ bool QFSFileEnginePrivate::nativeClose()
// Windows native mode.
bool ok = true;
- if ((fileHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileHandle))
-#ifdef Q_USE_DEPRECATED_MAP_API
- && (fileMapHandle == INVALID_HANDLE_VALUE || !CloseHandle(fileMapHandle))
-#endif
- ) {
+ if ((fileHandle == INVALID_HANDLE_VALUE || !::CloseHandle(fileHandle))) {
q->setError(QFile::UnspecifiedError, qt_error_string());
ok = false;
}
-#ifdef Q_USE_DEPRECATED_MAP_API
- fileMapHandle = INVALID_HANDLE_VALUE;
-#endif
fileHandle = INVALID_HANDLE_VALUE;
cachedFd = -1; // gets closed by CloseHandle above
@@ -504,14 +497,30 @@ qint64 QFSFileEnginePrivate::nativeSize() const
// ### Don't flush; for buffered files, we should get away with ftell.
thatQ->flush();
+#if !defined(Q_OS_WINCE)
+ // stdlib/stdio mode.
+ if (fh || fd != -1) {
+ qint64 fileSize = _filelengthi64(fh ? QT_FILENO(fh) : fd);
+ if (fileSize == -1) {
+ fileSize = 0;
+ thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno));
+ }
+ return fileSize;
+ }
+#else // Q_OS_WINCE
// Buffered stdlib mode.
if (fh) {
QT_OFF_T oldPos = QT_FTELL(fh);
QT_FSEEK(fh, 0, SEEK_END);
- QT_OFF_T fileSize = QT_FTELL(fh);
+ qint64 fileSize = (qint64)QT_FTELL(fh);
QT_FSEEK(fh, oldPos, SEEK_SET);
- return qint64(fileSize);
+ if (fileSize == -1) {
+ fileSize = 0;
+ thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno));
+ }
+ return fileSize;
}
+#endif
// Not-open mode, where the file name is known: We'll check the
// file system directly.
@@ -551,23 +560,13 @@ qint64 QFSFileEnginePrivate::nativeSize() const
return 0;
}
- // Unbuffed stdio mode.
- if(fd != -1) {
-#if !defined(Q_OS_WINCE)
- HANDLE handle = (HANDLE)_get_osfhandle(fd);
- if (handle != INVALID_HANDLE_VALUE) {
- BY_HANDLE_FILE_INFORMATION fileInfo;
- if (GetFileInformationByHandle(handle, &fileInfo)) {
- qint64 size = fileInfo.nFileSizeHigh;
- size <<= 32;
- size += fileInfo.nFileSizeLow;
- return size;
- }
- }
-#endif
- thatQ->setError(QFile::UnspecifiedError, qt_error_string());
+#if defined(Q_OS_WINCE)
+ // Unbuffed stdio mode
+ if (fd != -1) {
+ thatQ->setError(QFile::UnspecifiedError, QLatin1String("Not implemented!"));
return 0;
}
+#endif
// Windows native mode.
if (fileHandle == INVALID_HANDLE_VALUE)
@@ -799,27 +798,18 @@ int QFSFileEnginePrivate::nativeHandle() const
bool QFSFileEnginePrivate::nativeIsSequential() const
{
#if !defined(Q_OS_WINCE)
- // stdlib / Windows native mode.
- if (fh || fileHandle != INVALID_HANDLE_VALUE) {
- if (fh == stdin || fh == stdout || fh == stderr)
- return true;
-
- HANDLE handle = fileHandle;
- if (fileHandle == INVALID_HANDLE_VALUE) {
- // Rare case: using QFile::open(FILE*) to open a pipe.
- handle = (HANDLE)_get_osfhandle(QT_FILENO(fh));
- return false;
- }
-
- DWORD fileType = GetFileType(handle);
- return fileType == FILE_TYPE_PIPE;
- }
+ HANDLE handle = fileHandle;
+ if (fh || fd != -1)
+ handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
+ if (handle == INVALID_HANDLE_VALUE)
+ return false;
- // stdio mode.
- if (fd != -1)
- return isSequentialFdFh();
-#endif
+ DWORD fileType = GetFileType(handle);
+ return (fileType == FILE_TYPE_CHAR)
+ || (fileType == FILE_TYPE_PIPE);
+#else
return false;
+#endif
}
bool QFSFileEngine::remove()
@@ -1931,42 +1921,42 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
return 0;
}
+ if (mapHandle == INVALID_HANDLE_VALUE) {
+ // get handle to the file
+ HANDLE handle = fileHandle;
- // get handle to the file
- HANDLE handle = fileHandle;
#ifndef Q_OS_WINCE
- if (handle == INVALID_HANDLE_VALUE && fh)
- handle = (HANDLE)_get_osfhandle(QT_FILENO(fh));
+ if (handle == INVALID_HANDLE_VALUE && fh)
+ handle = (HANDLE)::_get_osfhandle(QT_FILENO(fh));
#endif
#ifdef Q_USE_DEPRECATED_MAP_API
- if (fileMapHandle == INVALID_HANDLE_VALUE) {
nativeClose();
- fileMapHandle = CreateFileForMapping((const wchar_t*)nativeFilePath.constData(),
+ // handle automatically closed by kernel with mapHandle (below).
+ handle = ::CreateFileForMapping((const wchar_t*)nativeFilePath.constData(),
GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0),
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
- }
- handle = fileMapHandle;
#endif
- if (handle == INVALID_HANDLE_VALUE) {
- q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
- return 0;
- }
+ if (handle == INVALID_HANDLE_VALUE) {
+ q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
+ return 0;
+ }
- // first create the file mapping handle
- DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
- HANDLE mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
- if (mapHandle == NULL) {
- q->setError(QFile::PermissionsError, qt_error_string());
+ // first create the file mapping handle
+ DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
+ mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
+ if (mapHandle == INVALID_HANDLE_VALUE) {
+ q->setError(QFile::PermissionsError, qt_error_string());
#ifdef Q_USE_DEPRECATED_MAP_API
- mapHandleClose();
+ ::CloseHandle(handle);
#endif
- return 0;
+ return 0;
+ }
}
// setup args to map
@@ -1978,17 +1968,17 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
SYSTEM_INFO sysinfo;
::GetSystemInfo(&sysinfo);
- int mask = sysinfo.dwAllocationGranularity - 1;
- int extra = offset & mask;
+ DWORD mask = sysinfo.dwAllocationGranularity - 1;
+ DWORD extra = offset & mask;
if (extra)
offsetLo &= ~mask;
// attempt to create the map
- LPVOID mapAddress = MapViewOfFile(mapHandle, access,
+ LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
offsetHi, offsetLo, size + extra);
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
- maps[address] = QPair<int, HANDLE>(extra, mapHandle);
+ maps[address] = extra;
return address;
}
@@ -2001,10 +1991,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
default:
q->setError(QFile::UnspecifiedError, qt_error_string());
}
- CloseHandle(mapHandle);
-#ifdef Q_USE_DEPRECATED_MAP_API
- mapHandleClose();
-#endif
+
+ ::CloseHandle(mapHandle);
return 0;
}
@@ -2015,32 +2003,19 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
return false;
}
- uchar *start = ptr - maps[ptr].first;
+ uchar *start = ptr - maps[ptr];
if (!UnmapViewOfFile(start)) {
q->setError(QFile::PermissionsError, qt_error_string());
return false;
}
- if (!CloseHandle((HANDLE)maps[ptr].second)) {
- q->setError(QFile::UnspecifiedError, qt_error_string());
- return false;
- }
maps.remove(ptr);
-
-#ifdef Q_USE_DEPRECATED_MAP_API
- mapHandleClose();
-#endif
- return true;
-}
-
-#ifdef Q_USE_DEPRECATED_MAP_API
-void QFSFileEnginePrivate::mapHandleClose()
-{
if (maps.isEmpty()) {
- CloseHandle(fileMapHandle);
- fileMapHandle = INVALID_HANDLE_VALUE;
+ ::CloseHandle(mapHandle);
+ mapHandle = INVALID_HANDLE_VALUE;
}
+
+ return true;
}
-#endif
QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index dd6b0d3..c86af73 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -68,9 +68,11 @@ public:
};
enum CompositionModeStatus {
- PorterDuff_None = 0x0,
- PorterDuff_SupportedBlits = 0x1,
- PorterDuff_SupportedPrimitives = 0x2
+ PorterDuff_None = 0x00,
+ PorterDuff_SupportedBlits = 0x01,
+ PorterDuff_SupportedPrimitives = 0x02,
+ PorterDuff_SupportedOpaquePrimitives = 0x04,
+ PorterDuff_Dirty = 0x10
};
enum ClipType {
@@ -95,6 +97,7 @@ public:
inline void unlock();
static inline void unlock(QDirectFBPaintDevice *device);
+ inline bool testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color = 0) const;
inline bool isSimpleBrush(const QBrush &brush) const;
void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos);
@@ -404,11 +407,11 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
return;
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+ if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
|| !d->simplePen
|| d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)) {
+ || !d->isSimpleBrush(brush)
+ || !d->testCompositionMode(&pen, &brush)) {
RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
@@ -434,11 +437,11 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
return;
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+ if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
|| !d->simplePen
|| d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)) {
+ || !d->isSimpleBrush(brush)
+ || !d->testCompositionMode(&pen, &brush)) {
RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
d->lock();
QRasterPaintEngine::drawRects(rects, rectCount);
@@ -460,16 +463,16 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+ const QPen &pen = state()->pen;
+ if (!d->simplePen
+ || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+ || !d->testCompositionMode(&pen, 0)) {
RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
}
- const QPen &pen = state()->pen;
if (pen.style() != Qt::NoPen) {
d->setDFBColor(pen.color());
CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
@@ -480,16 +483,16 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+ const QPen &pen = state()->pen;
+ if (!d->simplePen
+ || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+ || !d->testCompositionMode(&pen, 0)) {
RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
d->lock();
QRasterPaintEngine::drawLines(lines, lineCount);
return;
}
- const QPen &pen = state()->pen;
if (pen.style() != Qt::NoPen) {
d->setDFBColor(pen.color());
CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
@@ -714,8 +717,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
switch (brush.style()) {
case Qt::SolidPattern: {
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)) {
+ if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
+ || !d->testCompositionMode(0, &brush)) {
break;
}
const QColor color = brush.color();
@@ -753,9 +756,9 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
if (!color.isValid())
return;
Q_D(QDirectFBPaintEngine);
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) {
+ if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
+ || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
+ || !d->testCompositionMode(0, 0, &color)) {
RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
d->lock();
QRasterPaintEngine::fillRect(rect, color);
@@ -815,6 +818,36 @@ bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const
return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
}
+bool QDirectFBPaintEnginePrivate::testCompositionMode(const QPen *pen, const QBrush *brush, const QColor *color) const
+{
+ Q_ASSERT(!pen || pen->style() == Qt::NoPen || pen->style() == Qt::SolidLine);
+ Q_ASSERT(!brush || brush->style() == Qt::NoBrush || brush->style() == Qt::SolidPattern);
+ switch (compositionModeStatus & (QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives
+ |QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)) {
+ case QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives:
+ return true;
+ case QDirectFBPaintEnginePrivate::PorterDuff_SupportedOpaquePrimitives:
+ if (pen && pen->style() == Qt::SolidLine && pen->color().alpha() != 255)
+ return false;
+ if (brush) {
+ if (brush->style() == Qt::SolidPattern && brush->color().alpha() != 255) {
+ return false;
+ }
+ } else if (color && color->alpha() != 255) {
+ return false;
+ }
+ return true;
+ case QDirectFBPaintEnginePrivate::PorterDuff_None:
+ return false;
+ default:
+ // ### PorterDuff_SupportedOpaquePrimitives|PorterDuff_SupportedPrimitives can't be combined
+ break;
+ }
+ Q_ASSERT(0);
+ return false;
+}
+
+
void QDirectFBPaintEnginePrivate::lock()
{
// We will potentially get a new pointer to the buffer after a
@@ -888,6 +921,7 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m
break;
case QPainter::CompositionMode_Source:
surface->SetPorterDuff(surface, DSPD_SRC);
+ compositionModeStatus |= PorterDuff_SupportedOpaquePrimitives;
break;
case QPainter::CompositionMode_SourceOver:
compositionModeStatus |= PorterDuff_SupportedPrimitives;
@@ -945,6 +979,9 @@ void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha)
}
surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
surface->SetBlittingFlags(surface, blittingFlags);
+ if (compositionModeStatus & PorterDuff_Dirty) {
+ setCompositionMode(q->state()->composition_mode);
+ }
}
static inline uint ALPHA_MUL(uint x, uint a)
@@ -962,6 +999,7 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color)
surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha);
surface->SetPorterDuff(surface, DSPD_NONE);
surface->SetDrawingFlags(surface, alpha == 255 ? DSDRAW_NOFX : DSDRAW_BLEND);
+ compositionModeStatus |= PorterDuff_Dirty;
}
IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)