diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-09-03 14:36:15 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-09-03 14:36:15 (GMT) |
commit | f0844f9da7a834c282f6f04b2676f28de444e9dc (patch) | |
tree | 8e121429e25959043cc04c4364adbe8239e44a67 /src | |
parent | fe763ef6cd255ccb54d0de1894c1a772f959585e (diff) | |
parent | f360180890298618ef3284c08789c2a243e1ba9d (diff) | |
download | Qt-f0844f9da7a834c282f6f04b2676f28de444e9dc.zip Qt-f0844f9da7a834c282f6f04b2676f28de444e9dc.tar.gz Qt-f0844f9da7a834c282f6f04b2676f28de444e9dc.tar.bz2 |
Merge commit 'qt/4.6' into kinetic-declarativeui
Diffstat (limited to 'src')
147 files changed, 4946 insertions, 943 deletions
diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index e42dff9..250b94a 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -21,7 +21,9 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <QtCore/QTime> #include <QtCore/QLibrary> +#ifndef Q_CC_MSVC #include <dshow.h> +#endif #include <objbase.h> #include <initguid.h> #include <qnetwork.h> diff --git a/src/corelib/arch/alpha/qatomic_alpha.s b/src/corelib/arch/alpha/qatomic_alpha.s index 9363b35..44fa932 100644 --- a/src/corelib/arch/alpha/qatomic_alpha.s +++ b/src/corelib/arch/alpha/qatomic_alpha.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .set noreorder .set volatile .set noat diff --git a/src/corelib/arch/i386/qatomic_i386.s b/src/corelib/arch/i386/qatomic_i386.s index 08158f9..63facc1 100644 --- a/src/corelib/arch/i386/qatomic_i386.s +++ b/src/corelib/arch/i386/qatomic_i386.s @@ -1,3 +1,43 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! +!! 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 Technology Preview License Agreement accompanying +!! this package. +!! +!! 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.1, included in the file LGPL_EXCEPTION.txt in this +!! package. +!! +!! If you have questions regarding the use of this file, please contact +!! Nokia at qt-info@nokia.com. +!! +!! +!! +!! +!! +!! +!! +!! +!! $QT_END_LICENSE$ +!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .text .align 4,0x90 diff --git a/src/corelib/arch/ia64/qatomic_ia64.s b/src/corelib/arch/ia64/qatomic_ia64.s index 6b8a204..f6be4dd 100644 --- a/src/corelib/arch/ia64/qatomic_ia64.s +++ b/src/corelib/arch/ia64/qatomic_ia64.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .pred.safe_across_calls p1-p5,p16-p63 .text .align 16 diff --git a/src/corelib/arch/macosx/qatomic32_ppc.s b/src/corelib/arch/macosx/qatomic32_ppc.s index 13fff67..f87a152 100644 --- a/src/corelib/arch/macosx/qatomic32_ppc.s +++ b/src/corelib/arch/macosx/qatomic32_ppc.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .section __TEXT,__text,regular,pure_instructions .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 .section __TEXT,__text,regular,pure_instructions diff --git a/src/corelib/arch/mips/qatomic_mips32.s b/src/corelib/arch/mips/qatomic_mips32.s index e7a449b..2bd2dc3 100644 --- a/src/corelib/arch/mips/qatomic_mips32.s +++ b/src/corelib/arch/mips/qatomic_mips32.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .set nobopt .set noreorder .option pic2 diff --git a/src/corelib/arch/mips/qatomic_mips64.s b/src/corelib/arch/mips/qatomic_mips64.s index d2bd8fe..08dc76f 100644 --- a/src/corelib/arch/mips/qatomic_mips64.s +++ b/src/corelib/arch/mips/qatomic_mips64.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .set nobopt .set noreorder .option pic2 diff --git a/src/corelib/arch/parisc/q_ldcw.s b/src/corelib/arch/parisc/q_ldcw.s index f901ad9..99205fc 100644 --- a/src/corelib/arch/parisc/q_ldcw.s +++ b/src/corelib/arch/parisc/q_ldcw.s @@ -1,3 +1,43 @@ +;/**************************************************************************** +;** +;** 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 Technology Preview License Agreement accompanying +;** this package. +;** +;** 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.1, included in the file LGPL_EXCEPTION.txt in this +;** package. +;** +;** If you have questions regarding the use of this file, please contact +;** Nokia at qt-info@nokia.com. +;** +;** +;** +;** +;** +;** +;** +;** +;** $QT_END_LICENSE$ +;** +;****************************************************************************/ .SPACE $PRIVATE$ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 diff --git a/src/corelib/arch/powerpc/qatomic32.s b/src/corelib/arch/powerpc/qatomic32.s index 811ba84..a84e0a3 100644 --- a/src/corelib/arch/powerpc/qatomic32.s +++ b/src/corelib/arch/powerpc/qatomic32.s @@ -1,3 +1,43 @@ +############################################################################ +## +## 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################ .machine "ppc" .toc .csect .text[PR] diff --git a/src/corelib/arch/powerpc/qatomic64.s b/src/corelib/arch/powerpc/qatomic64.s index 88c2bbd..e56a239 100644 --- a/src/corelib/arch/powerpc/qatomic64.s +++ b/src/corelib/arch/powerpc/qatomic64.s @@ -1,3 +1,43 @@ +############################################################################ +## +## 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################ .machine "ppc64" .toc .csect .text[PR] diff --git a/src/corelib/arch/qatomic_windows.h b/src/corelib/arch/qatomic_windows.h index 9b7ff5d..6082d0b 100644 --- a/src/corelib/arch/qatomic_windows.h +++ b/src/corelib/arch/qatomic_windows.h @@ -144,7 +144,6 @@ extern "C" { #endif // QT_INTERLOCKED_DECLARE_PROTOTYPES #undef QT_INTERLOCKED_PROTOTYPE -#undef QT_INTERLOCKED_VOLATILE //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -215,13 +214,13 @@ extern "C" { # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ QT_INTERLOCKED_FUNCTION(InterlockedCompareExchangePointer)( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ + reinterpret_cast<void * QT_INTERLOCKED_VOLATILE *>( QT_INTERLOCKED_REMOVE_VOLATILE( value ) ), \ newValue, \ expectedValue ) # define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \ QT_INTERLOCKED_FUNCTION(InterlockedExchangePointer)( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ + reinterpret_cast<void * QT_INTERLOCKED_VOLATILE *>( QT_INTERLOCKED_REMOVE_VOLATILE( value ) ), \ newValue ) # define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \ @@ -471,6 +470,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo #undef QT_INTERLOCKED_PREFIX #undef QT_INTERLOCKED_NO_VOLATILE +#undef QT_INTERLOCKED_VOLATILE #undef QT_INTERLOCKED_REMOVE_VOLATILE #undef QT_INTERLOCKED_INCREMENT diff --git a/src/corelib/arch/sparc/qatomic32.s b/src/corelib/arch/sparc/qatomic32.s index f0ab0d1..6e6b199 100644 --- a/src/corelib/arch/sparc/qatomic32.s +++ b/src/corelib/arch/sparc/qatomic32.s @@ -1,3 +1,43 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! +!! 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 Technology Preview License Agreement accompanying +!! this package. +!! +!! 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.1, included in the file LGPL_EXCEPTION.txt in this +!! package. +!! +!! If you have questions regarding the use of this file, please contact +!! Nokia at qt-info@nokia.com. +!! +!! +!! +!! +!! +!! +!! +!! +!! $QT_END_LICENSE$ +!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .section ".text" .align 4 diff --git a/src/corelib/arch/sparc/qatomic64.s b/src/corelib/arch/sparc/qatomic64.s index edd1716..64560a0 100644 --- a/src/corelib/arch/sparc/qatomic64.s +++ b/src/corelib/arch/sparc/qatomic64.s @@ -1,3 +1,43 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! +!! 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 Technology Preview License Agreement accompanying +!! this package. +!! +!! 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.1, included in the file LGPL_EXCEPTION.txt in this +!! package. +!! +!! If you have questions regarding the use of this file, please contact +!! Nokia at qt-info@nokia.com. +!! +!! +!! +!! +!! +!! +!! +!! +!! $QT_END_LICENSE$ +!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .section ".text" .align 4 diff --git a/src/corelib/arch/x86_64/qatomic_sun.s b/src/corelib/arch/x86_64/qatomic_sun.s index 37969e6..4517fe4 100644 --- a/src/corelib/arch/x86_64/qatomic_sun.s +++ b/src/corelib/arch/x86_64/qatomic_sun.s @@ -1,3 +1,43 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! +!! 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 Technology Preview License Agreement accompanying +!! this package. +!! +!! 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.1, included in the file LGPL_EXCEPTION.txt in this +!! package. +!! +!! If you have questions regarding the use of this file, please contact +!! Nokia at qt-info@nokia.com. +!! +!! +!! +!! +!! +!! +!! +!! +!! $QT_END_LICENSE$ +!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .code64 .globl q_atomic_increment diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 935c99b..787eba7 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1189,6 +1189,7 @@ bool qSharedBuild() \value SV_S60_3_2 S60 3rd Edition Feature Pack 2 \value SV_S60_5_0 S60 5th Edition \value SV_S60_Unknown An unknown and currently unsupported platform + \omitvalue SV_S60_None \sa SymbianVersion, WinVersion, MacVersion */ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index ed403cb..68246f2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2172,7 +2172,7 @@ public: inline bool operator!() const { return !i; } - inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == f ); } + inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == int(f) ); } }; #define Q_DECLARE_FLAGS(Flags, Enum)\ diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index a6f5907..8f34e30 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -501,6 +501,8 @@ public: WA_WState_AcceptedTouchBeginEvent = 122, WA_TouchPadAcceptSingleTouchEvents = 123, + WA_DontUseStandardGestures = 124, + // Add new attributes before this line WA_AttributeCount }; @@ -1652,7 +1654,8 @@ public: Pbuffer = 0x06, // GL pbuffer FramebufferObject = 0x07, // GL framebuffer object CustomRaster = 0x08, - MacQuartz = 0x09 + MacQuartz = 0x09, + PaintBuffer = 0x0a }; enum RelayoutType { RelayoutNormal, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index ace70ff..06eea68 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -612,6 +612,12 @@ */ /*! + \enum Qt::CoordinateSystem + \value DeviceCoordinates + \value LogicalCoordinates + */ + +/*! \enum Qt::CaseSensitivity \value CaseInsensitive @@ -1216,6 +1222,8 @@ \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single touch events to be sent to the widget. + \value WA_DontUseStandardGestures Disables standard gestures on Qt widgets. + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/corelib/io/qfile_p.h b/src/corelib/io/qfile_p.h index f35cdeb..781c6d5 100644 --- a/src/corelib/io/qfile_p.h +++ b/src/corelib/io/qfile_p.h @@ -72,7 +72,6 @@ protected: QString fileName; mutable QAbstractFileEngine *fileEngine; - bool isOpen; bool lastWasWrite; QRingBuffer writeBuffer; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 5ff0716..a5ed95c 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -89,7 +89,8 @@ typedef INT_PTR intptr_t; # define INVALID_FILE_ATTRIBUTES (DWORD (-1)) #endif -#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) && !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) +# if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; @@ -115,8 +116,9 @@ typedef struct _REPARSE_DATA_BUFFER { } GenericReparseBuffer; }; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) +# endif // !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) -# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) # ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE # define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 # endif @@ -126,7 +128,7 @@ typedef struct _REPARSE_DATA_BUFFER { # ifndef FSCTL_GET_REPARSE_POINT # define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) # endif -#endif +#endif // !defined(Q_OS_WINCE) QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 5b6830c..1e3b6eb 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1572,7 +1572,7 @@ void QProcess::setProcessEnvironment(const QProcessEnvironment &environment) \note The environment settings are ignored on Windows CE, as there is no concept of an environment. - \sa setProcessEnvironment(), setEnvironment(), QProcessEnvironment::isValid() + \sa setProcessEnvironment(), setEnvironment(), QProcessEnvironment::isEmpty() */ QProcessEnvironment QProcess::processEnvironment() const { diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 72388b5..c70804a 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -937,7 +937,7 @@ inline bool QTextStreamPrivate::putString(const QString &s, bool number) // handle padding int padSize = fieldWidth - s.size(); if (padSize > 0) { - QString pad(padSize > 0 ? padSize : 0, padChar); + QString pad(padSize, padChar); if (fieldAlignment == QTextStream::AlignLeft) { tmp.append(QString(padSize, padChar)); } else if (fieldAlignment == QTextStream::AlignRight diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index c922833..d83455a 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -274,7 +274,7 @@ class Q_CORE_EXPORT QTextStreamManipulator { public: QTextStreamManipulator(QTSMFI m, int a) { mf = m; mc = 0; arg = a; } - QTextStreamManipulator(QTSMFC m, QChar c) { mf = 0; mc = m; ch = c; } + QTextStreamManipulator(QTSMFC m, QChar c) { mf = 0; mc = m; ch = c; arg = -1; } void exec(QTextStream &s) { if (mf) { (s.*mf)(arg); } else { (s.*mc)(ch); } } private: diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index e411681..f62577e 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -283,7 +283,6 @@ bool QSharedMemoryPrivate::detach() // If there are no attachments then remove it. if (shmid_ds.shm_nattch == 0) { // mark for removal - struct shmid_ds shmid_ds; if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) { setErrorString(QLatin1String("QSharedMemory::remove")); switch (errno) { diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index ac2aac8..2fc6a58 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -249,17 +249,15 @@ void QSignalTransitionPrivate::callOnTransition(QEvent *e) { Q_Q(QSignalTransition); - QSignalEvent *se = static_cast<QSignalEvent *>(e); - int savedSignalIndex; if (e->type() == QEvent::Signal) { - savedSignalIndex = se->m_signalIndex; + QSignalEvent *se = static_cast<QSignalEvent *>(e); + int savedSignalIndex = se->m_signalIndex; se->m_signalIndex = originalSignalIndex; - } - - q->onTransition(e); - - if (e->type() == QEvent::Signal) + q->onTransition(e); se->m_signalIndex = savedSignalIndex; + } else { + q->onTransition(e); + } } QT_END_NAMESPACE diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 840f6a5..145b631 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1467,8 +1467,19 @@ QByteArray &QByteArray::prepend(const QByteArray &ba) QByteArray &QByteArray::prepend(const char *str) { + return prepend(str, qstrlen(str)); +} + +/*! + \overload + \since 4.6 + + Prepends \a len bytes of the string \a str to this byte array. +*/ + +QByteArray &QByteArray::prepend(const char *str, int len) +{ if (str) { - int len = qstrlen(str); if (d->ref != 1 || d->size + len > d->alloc) realloc(qAllocMore(d->size + len, sizeof(Data))); memmove(d->data+len, d->data, d->size); @@ -1679,6 +1690,22 @@ QByteArray &QByteArray::insert(int i, const char *str) /*! \overload + \since 4.6 + + Inserts \a len bytes of the string \a str at position + \a i in the byte array. + + If \a i is greater than size(), the array is first extended using + resize(). +*/ + +QByteArray &QByteArray::insert(int i, const char *str, int len) +{ + return qbytearray_insert(this, i, str, len); +} + +/*! + \overload Inserts character \a ch at index position \a i in the byte array. If \a i is greater than size(), the array is first extended using @@ -4099,6 +4126,10 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA \internal */ +/*! \typedef QByteArray::value_type + \internal + */ + /*! \fn QByteArray::QByteArray(int size) diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index f7e790d..34dd44f 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -224,6 +224,7 @@ public: QByteArray &prepend(char c); QByteArray &prepend(const char *s); + QByteArray &prepend(const char *s, int len); QByteArray &prepend(const QByteArray &a); QByteArray &append(char c); QByteArray &append(const char *s); @@ -231,6 +232,7 @@ public: QByteArray &append(const QByteArray &a); QByteArray &insert(int i, char c); QByteArray &insert(int i, const char *s); + QByteArray &insert(int i, const char *s, int len); QByteArray &insert(int i, const QByteArray &a); QByteArray &remove(int index, int len); QByteArray &replace(int index, int len, const char *s); diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index b369e53..8621908 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.h @@ -131,7 +131,7 @@ private: template <class Key, class T> inline QCache<Key, T>::QCache(int amaxCost) - : f(0), l(0), mx(amaxCost), total(0) {} + : f(0), l(0), unused(0), mx(amaxCost), total(0) {} template <class Key, class T> inline void QCache<Key,T>::clear() diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ded36c2..623d63e 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -636,6 +636,9 @@ static QString winSystemPMText() return QString(); } +/*! + Returns the fallback locale obtained from the system. + */ QLocale QSystemLocale::fallbackLocale() const { return QLocale(QString::fromLatin1(getWinLocaleName())); diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 44238a8..7dcac71 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -219,4 +219,8 @@ QT_BEGIN_NAMESPACE \sa isNull() */ +/*! \fn void QScopedPointer::swap(QScopedPointer<T, Cleanup> &other) + Swap this pointer with \a other. + */ + QT_END_NAMESPACE diff --git a/src/corelib/xml/make-parser.sh b/src/corelib/xml/make-parser.sh index 0e2cbe1..e18dda3 100755 --- a/src/corelib/xml/make-parser.sh +++ b/src/corelib/xml/make-parser.sh @@ -1,4 +1,44 @@ #!/bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# me=$(dirname $0) mkdir -p $me/out diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g index b9659ba..39edcbc 100644 --- a/src/corelib/xml/qxmlstream.g +++ b/src/corelib/xml/qxmlstream.g @@ -37,9 +37,6 @@ -- -- $QT_END_LICENSE$ -- --- This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE --- WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. --- ---------------------------------------------------------------------------- %parser QXmlStreamReader_Table diff --git a/src/gui/accessible/qaccessible_mac_cocoa.mm b/src/gui/accessible/qaccessible_mac_cocoa.mm index dd02f6c..9a50036 100644 --- a/src/gui/accessible/qaccessible_mac_cocoa.mm +++ b/src/gui/accessible/qaccessible_mac_cocoa.mm @@ -1,4 +1,3 @@ - /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). @@ -40,6 +39,7 @@ ** ****************************************************************************/ + #include "qaccessible.h" #include "qaccessible_mac_p.h" #include "qdebug.h" diff --git a/src/gui/dialogs/qfiledialog_embedded.ui b/src/gui/dialogs/qfiledialog_embedded.ui index 454af4b..1bd189e 100644 --- a/src/gui/dialogs/qfiledialog_embedded.ui +++ b/src/gui/dialogs/qfiledialog_embedded.ui @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** *********************************************************************</comment> <class>QFileDialog</class> <widget class="QDialog" name="QFileDialog" > diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index f60e80e..6629a6d 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -256,7 +256,8 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse } /*! - Constructs a new QGraphicsEffect instance. + Constructs a new QGraphicsEffect instance having the + specified \a parent. */ QGraphicsEffect::QGraphicsEffect(QObject *parent) : QObject(*new QGraphicsEffectPrivate, parent) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8065526..871f009 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -525,23 +525,33 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP endOfSequence = true; } } - if (endOfSequence && candidates.count() >= 2) { + if (endOfSequence && candidates.count() >= 1) { int i; AnchorVertex *afterSequence= 0; - QList<AnchorVertex *> adjacentOfSecondLastVertex = g.adjacentVertices(candidates.last()); - Q_ASSERT(adjacentOfSecondLastVertex.count() == 2); - if (adjacentOfSecondLastVertex.first() == candidates.at(candidates.count() - 2)) - afterSequence = adjacentOfSecondLastVertex.last(); - else - afterSequence = adjacentOfSecondLastVertex.first(); - AnchorVertex *beforeSequence = 0; - QList<AnchorVertex *> adjacentOfSecondVertex = g.adjacentVertices(candidates.first()); - Q_ASSERT(adjacentOfSecondVertex.count() == 2); - if (adjacentOfSecondVertex.first() == candidates.at(1)) - beforeSequence = adjacentOfSecondVertex.last(); - else - beforeSequence = adjacentOfSecondVertex.first(); + // find the items before and after the valid sequence + if (candidates.count() == 1) { + QList<AnchorVertex *> beforeAndAfterVertices = g.adjacentVertices(candidates.at(0)); + Q_ASSERT(beforeAndAfterVertices.count() == 2); + // Since we only have one vertex, we can pick + // any of the two vertices to become before/after. + afterSequence = beforeAndAfterVertices.last(); + beforeSequence = beforeAndAfterVertices.first(); + } else { + QList<AnchorVertex *> adjacentOfSecondLastVertex = g.adjacentVertices(candidates.last()); + Q_ASSERT(adjacentOfSecondLastVertex.count() == 2); + if (adjacentOfSecondLastVertex.first() == candidates.at(candidates.count() - 2)) + afterSequence = adjacentOfSecondLastVertex.last(); + else + afterSequence = adjacentOfSecondLastVertex.first(); + + QList<AnchorVertex *> adjacentOfSecondVertex = g.adjacentVertices(candidates.first()); + Q_ASSERT(adjacentOfSecondVertex.count() == 2); + if (adjacentOfSecondVertex.first() == candidates.at(1)) + beforeSequence = adjacentOfSecondVertex.last(); + else + beforeSequence = adjacentOfSecondVertex.first(); + } // The complete path of the sequence to simplify is: beforeSequence, <candidates>, afterSequence // where beforeSequence and afterSequence are the endpoints where the anchor is inserted // between. @@ -583,34 +593,37 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP // start and the end of the sequence. We never want to simplify internal // center anchors where there is an external anchor connected to the center. AnchorVertex *intervalVertexFrom = intervalFrom == 0 ? beforeSequence : candidates.at(intervalFrom - 1); + int effectiveIntervalFrom = intervalFrom; if (intervalVertexFrom->m_edge == centerEdge - && intervalVertexFrom->m_item == candidates.at(intervalFrom)->m_item) { - ++intervalFrom; - intervalVertexFrom = candidates.at(intervalFrom - 1); + && intervalVertexFrom->m_item == candidates.at(effectiveIntervalFrom)->m_item) { + ++effectiveIntervalFrom; + intervalVertexFrom = candidates.at(effectiveIntervalFrom - 1); } AnchorVertex *intervalVertexTo = intervalTo <= candidates.count() ? candidates.at(intervalTo - 1) : afterSequence; + int effectiveIntervalTo = intervalTo; if (intervalVertexTo->m_edge == centerEdge - && intervalVertexTo->m_item == candidates.at(intervalTo - 2)->m_item) { - --intervalTo; - intervalVertexTo = candidates.at(intervalTo - 1); - } - - QVector<AnchorVertex*> subCandidates; - if (forward) { - subCandidates = candidates.mid(intervalFrom, intervalTo - intervalFrom - 1); - } else { - // reverse the order of the candidates. - qSwap(intervalVertexFrom, intervalVertexTo); - do { - ++intervalFrom; - subCandidates.prepend(candidates.at(intervalFrom - 1)); - } while (intervalFrom < intervalTo - 1); + && intervalVertexTo->m_item == candidates.at(effectiveIntervalTo - 2)->m_item) { + --effectiveIntervalTo; + intervalVertexTo = candidates.at(effectiveIntervalTo - 1); } - if (simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo)) { - dirty = true; - break; + if (effectiveIntervalTo - effectiveIntervalFrom >= 2) { + QVector<AnchorVertex*> subCandidates; + if (forward) { + subCandidates = candidates.mid(effectiveIntervalFrom, effectiveIntervalTo - effectiveIntervalFrom - 1); + } else { + // reverse the order of the candidates. + qSwap(intervalVertexFrom, intervalVertexTo); + do { + ++effectiveIntervalFrom; + subCandidates.prepend(candidates.at(effectiveIntervalFrom - 1)); + } while (effectiveIntervalFrom < effectiveIntervalTo - 1); + } + if (simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo)) { + dirty = true; + break; + } + // finished simplification of chunk with same direction } - // finished simplification of chunk with same direction } if (forward == (prev == data->from)) --intervalTo; diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e931e4c..4cb4dcf 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -10370,10 +10370,14 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP effectRect.setY(0); } // NB! We use +-1 for historical reasons (see QRect documentation). - if (right + 1 > info->widget->width()) - effectRect.setRight(info->widget->width() - 1); - if (bottom + 1 > info->widget->height()) - effectRect.setBottom(info->widget->height() -1); + QPaintDevice *device = info->painter->device(); + const int deviceWidth = device->width(); + const int deviceHeight = device->height(); + if (right + 1 > deviceWidth) + effectRect.setRight(deviceWidth - 1); + if (bottom + 1 > deviceHeight) + effectRect.setBottom(deviceHeight -1); + } if (effectRect.isEmpty()) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index cf34c6e..a1fb7b9 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -556,17 +556,20 @@ struct QGraphicsItemPrivate::TransformData return transform * *postmultiplyTransform; } - QMatrix4x4 x(transform); - for (int i = 0; i < graphicsTransforms.size(); ++i) - graphicsTransforms.at(i)->applyTo(&x); + QTransform x(transform); + if (!graphicsTransforms.isEmpty()) { + QMatrix4x4 m; + for (int i = 0; i < graphicsTransforms.size(); ++i) + graphicsTransforms.at(i)->applyTo(&m); + x *= m.toTransform(); + } x.translate(xOrigin, yOrigin); - x.rotate(rotation, 0, 0, 1); - x.scale(scale); + x.rotate(rotation); + x.scale(scale, scale); x.translate(-xOrigin, -yOrigin); - QTransform t = x.toTransform(); // project the 3D matrix back to 2D. if (postmultiplyTransform) - t *= *postmultiplyTransform; - return t; + x *= *postmultiplyTransform; + return x; } }; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 88aeaf9..56cf83e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4629,7 +4629,8 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b return; } - bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents; + bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents + && !item->d_ptr->graphicsEffect; if (!hasNoContents) { item->d_ptr->dirty = 1; if (fullItemUpdate) @@ -4719,11 +4720,15 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool return; } - const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); + bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); - if (!itemHasContents && !itemHasChildren) { - resetDirtyItem(item); - return; // Item has neither contents nor children!(?) + if (!itemHasContents) { + if (!itemHasChildren) { + resetDirtyItem(item); + return; // Item has neither contents nor children!(?) + } + if (item->d_ptr->graphicsEffect) + itemHasContents = true; } const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp index 8c3b9be..b5ffeed 100644 --- a/src/gui/image/qbitmap.cpp +++ b/src/gui/image/qbitmap.cpp @@ -92,13 +92,15 @@ QT_BEGIN_NAMESPACE \sa QPixmap, QImage, QImageReader, QImageWriter */ +/*! \typedef QBitmap::DataPtr + \internal + */ /*! Constructs a null bitmap. \sa QPixmap::isNull() */ - QBitmap::QBitmap() : QPixmap(QSize(0, 0), QPixmapData::BitmapType) { diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index e23677f..1140cd8 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -879,20 +879,20 @@ void QIcon::setThemeSearchPaths(const QStringList &paths) } /*! - \since 4.6 + \since 4.6 - Returns the search paths for icon themes. + Returns the search paths for icon themes. - The default value will depend on the platform: + The default value will depend on the platform: - On X11, the search path will use the XDG_DATA_DIRS environment - variable if available. + On X11, the search path will use the XDG_DATA_DIRS environment + variable if available. - By default all platforms will have the resource directory - ":\icons" as their fallback. You can use "rcc -project" - to generate a resource file from your icon theme. + By default all platforms will have the resource directory + \c{:\icons} as a fallback. You can use "rcc -project" to generate a + resource file from your icon theme. - \sa setThemeSearchPaths(), fromTheme(), setThemeName() + \sa setThemeSearchPaths(), fromTheme(), setThemeName() */ QStringList QIcon::themeSearchPaths() { diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp index 2422355..ed30810 100644 --- a/src/gui/inputmethod/qinputcontext.cpp +++ b/src/gui/inputmethod/qinputcontext.cpp @@ -176,7 +176,7 @@ QWidget *QInputContext::focusWidget() const /*! - Sets the widget that has an input focus for this input context. + Sets the \a widget that has an input focus for this input context. \warning Ordinary input methods must not call this function directly. diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp index 7d6439f..6a7b27c 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -622,6 +622,10 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order, QTreeWidgetItem *item = lst.takeAt(oldRow); lit = sortedInsertionIterator(lit, lst.end(), order, item); int newRow = qMax(lit - lst.begin(), 0); + + if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1))) + newRow = oldRow; + lit = lst.insert(lit, item); if (newRow != oldRow) { // we are going to change the persistent indexes, so we need to prepare @@ -2074,7 +2078,7 @@ void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool { QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0); if (!model) - return; + return; model->sortItems(&q->children, column, order); if (climb) { QList<QTreeWidgetItem*>::iterator it = q->children.begin(); diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index d2a25fd..2a28c71 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -269,6 +269,26 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map) MenuRole for the actions in that submenu have no effect. They will never be moved. */ +/*! \enum QAction::SoftKeyRole + \value OptionsSoftKey + \value SelectSoftKey + \value BackSoftKey + \value NextSoftKey + \value PreviousSoftKey + \value OkSoftKey + \value CancelSoftKey + \value EditSoftKey + \value ViewSoftKey + \value BackSpaceSoftKey + \value EndEditSoftKey + \value RevertEditSoftKey + \value DeselectSoftKey + \value FinishSoftKey + \value MenuSoftKey + \value ContextMenuSoftKey + \value ExitSoftKey + */ + /*! Constructs an action with \a parent. If \a parent is an action group the action will be automatically inserted into the group. diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index f049a58..511c797 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -3625,6 +3625,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: d->toolTipFallAsleep.stop(); + // fall-through case QEvent::Leave: d->toolTipWakeUp.stop(); default: diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 1bbf332..8561045 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -347,21 +347,21 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | Qt::RightButton; QMouseEvent mEvent(QEvent::MouseButtonPress, alienWidget->mapFrom(qwidget, widgetPos), globalPos, Qt::RightButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier); - + bool res = sendMouseEvent(alienWidget, &mEvent); #if !defined(QT_NO_CONTEXTMENU) QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, mEvent.modifiers()); qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent); -#endif - +#endif + m_previousEventLongTap = true; } void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent) { m_longTapDetector->PointerEventL(pEvent); - QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); + QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent)); } void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) @@ -396,15 +396,6 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) if (!alienWidget) alienWidget = qwidget; S60->mousePressTarget = alienWidget; - //pointer grab - SetGloballyCapturing(ETrue); - SetPointerCapture(ETrue); - } - else if (type == QEvent::MouseButtonRelease) - { - //release pointer grab - SetGloballyCapturing(EFalse); - SetPointerCapture(EFalse); } alienWidget = S60->mousePressTarget; @@ -801,14 +792,27 @@ bool QApplicationPrivate::modalState() void QApplicationPrivate::enterModal_sys(QWidget *widget) { + if (widget) { + widget->effectiveWinId()->DrawableWindow()->FadeBehind(ETrue); + // Modal partial screen dialogs (like queries) capture pointer events. + // ### FixMe: Add specialized behaviour for fullscreen modal dialogs + widget->effectiveWinId()->SetGloballyCapturing(ETrue); + widget->effectiveWinId()->SetPointerCapture(ETrue); + } if (!qt_modal_stack) qt_modal_stack = new QWidgetList; qt_modal_stack->insert(0, widget); - app_do_modal = true; + app_do_modal = true; } void QApplicationPrivate::leaveModal_sys(QWidget *widget) { + if (widget) { + widget->effectiveWinId()->DrawableWindow()->FadeBehind(EFalse); + // ### FixMe: Add specialized behaviour for fullscreen modal dialogs + widget->effectiveWinId()->SetGloballyCapturing(EFalse); + widget->effectiveWinId()->SetPointerCapture(EFalse); + } if (qt_modal_stack && qt_modal_stack->removeAll(widget)) { if (qt_modal_stack->isEmpty()) { delete qt_modal_stack; @@ -824,18 +828,31 @@ void QApplicationPrivate::openPopup(QWidget *popup) QApplicationPrivate::popupWidgets = new QWidgetList; QApplicationPrivate::popupWidgets->append(popup); - if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) { + + // Cancel focus widget pointer capture and long tap timer + if (QApplication::focusWidget()) { + static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer(); + QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false); + } + + if (!qt_nograb()) { + // Cancel pointer capture and long tap timer for earlier popup + int popupCount = QApplicationPrivate::popupWidgets->count(); + if (popupCount > 1) { + QWidget* prevPopup = QApplicationPrivate::popupWidgets->at(popupCount-2); + static_cast<QSymbianControl*>(prevPopup->effectiveWinId())->CancelLongTapTimer(); + prevPopup->effectiveWinId()->SetPointerCapture(false); + } + + // Enable pointer capture for this (topmost) popup Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); WId id = popup->effectiveWinId(); id->SetPointerCapture(true); - id->SetGloballyCapturing(true); } // popups are not focus-handled by the window system (the first // popup grabbed the keyboard), so we have to do that manually: A // new popup gets the focus - if (QApplication::focusWidget()) - static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer(); QWidget *fw = popup->focusWidget(); if (fw) { fw->setFocus(Qt::PopupFocusReason); @@ -854,14 +871,16 @@ void QApplicationPrivate::closePopup(QWidget *popup) return; QApplicationPrivate::popupWidgets->removeAll(popup); + // Cancel pointer capture and long tap for this popup + WId id = popup->effectiveWinId(); + id->SetPointerCapture(false); + static_cast<QSymbianControl*>(id)->CancelLongTapTimer(); + if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup delete QApplicationPrivate::popupWidgets; QApplicationPrivate::popupWidgets = 0; if (!qt_nograb()) { // grabbing not disabled Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created)); - WId id = popup->effectiveWinId(); - id->SetPointerCapture(false); - id->SetGloballyCapturing(false); if (QWidgetPrivate::mouseGrabber != 0) QWidgetPrivate::mouseGrabber->grabMouse(); @@ -880,6 +899,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) } } } else { + // popups are not focus-handled by the window system (the // first popup grabbed the keyboard), so we have to do that // manually: A popup was closed, so the previous popup gets @@ -889,6 +909,11 @@ void QApplicationPrivate::closePopup(QWidget *popup) QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); q_func()->sendEvent(fw, &e); } + + // Enable pointer capture for previous popup + if (aw) { + aw->effectiveWinId()->SetPointerCapture(true); + } } } @@ -972,11 +997,14 @@ void QApplication::beep() beep=NULL; } -/*! \fn int QApplication::s60ProcessEvent(TWsEvent *event) - This function does the core processing of individual s60 - \a{event}s. It returns 1 if the event was handled, 0 if +/*! + \warning This function is only available on Symbian. + + This function processes an individual Symbian window server + \a event. It returns 1 if the event was handled, 0 if the \a event was not handled, and -1 if the event was - not handled because the event handle was not in the map. + not handled because the event handle (\c{TWsEvent::Handle()}) + is not known to Qt. */ int QApplication::s60ProcessEvent(TWsEvent *event) { @@ -1065,7 +1093,16 @@ int QApplication::s60ProcessEvent(TWsEvent *event) } /*! - Returns false. Does nothing with the TWsEvent \a aEvent. + \warning This virtual function is only available on Symbian. + + If you create an application that inherits QApplication and reimplement + this function, you get direct access to events that the are received + from the Symbian window server. The events are passed in the TWsEvent + \a aEvent parameter. + + Return true if you want to stop the event from being processed. Return + false for normal event dispatching. The default implementation + false, and does nothing with \a aEvent. */ bool QApplication::s60EventFilter(TWsEvent * /* aEvent */) { @@ -1073,9 +1110,11 @@ bool QApplication::s60EventFilter(TWsEvent * /* aEvent */) } /*! + \warning This function is only available on Symbian. + Handles \a{command}s which are typically handled by CAknAppUi::HandleCommandL(). Qts Ui integration into Symbian is - partially achieved by deriving from CAknAppUi. Currently, exit, + partially achieved by deriving from CAknAppUi. Currently, exit, menu and softkey commands are handled. \sa s60EventFilter(), s60ProcessEvent() @@ -1107,7 +1146,12 @@ void QApplication::symbianHandleCommand(int command) } /*! + \warning This function is only available on Symbian. + Handles the resource change specified by \a type. + + Currently, KEikDynamicLayoutVariantSwitch and + KAknsMessageSkinChange are handled. */ void QApplication::symbianResourceChange(int type) { diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index a3de120..84edf1f 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1903,11 +1903,9 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam QHideEvent e; qt_sendSpontaneousEvent(widget, &e); widget->hideChildren(true); -#ifndef Q_WS_WINCE const QString title = widget->windowIconText(); if (!title.isEmpty()) widget->setWindowTitle_helper(title); -#endif } result = false; break; @@ -1926,11 +1924,9 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam widget->showChildren(true); QShowEvent e; qt_sendSpontaneousEvent(widget, &e); -#ifndef Q_WS_WINCE const QString title = widget->windowTitle(); if (!title.isEmpty()) widget->setWindowTitle_helper(title); -#endif } result = false; break; @@ -1943,7 +1939,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam QWindowStateChangeEvent e(oldstate); qt_sendSpontaneousEvent(widget, &e); } -#endif +#endif // #ifndef Q_OS_WINCE break; } @@ -2030,13 +2026,16 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application // loses focus. Doing it here would result in the widget getting focus to not know // where it got it from; it would simply get a 0 value as the old focus widget. -#ifndef Q_WS_WINCE_WM - if (!(widget->windowState() & Qt::WindowMinimized)) { - // Ignore the activate message send by WindowsXP to a minimized window -#else +#ifdef Q_WS_WINCE { if (widget->windowState() & Qt::WindowMinimized) widget->dataPtr()->window_state &= ~Qt::WindowMinimized; +#else + if (!(widget->windowState() & Qt::WindowMinimized)) { +#endif + // Ignore the activate message send by WindowsXP to a minimized window +#ifdef Q_WS_WINCE_WM + { if (widget->windowState() & Qt::WindowFullScreen) qt_wince_hide_taskbar(widget->winId()); #endif diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 0056b9e..a7a6504 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -79,6 +79,7 @@ #include <private/qcolor_p.h> #include <private/qcursor_p.h> #include <private/qiconloader_p.h> +#include <private/gtksymbols_p.h> #include "qstyle.h" #include "qmetaobject.h" #include "qtimer.h" @@ -2287,6 +2288,12 @@ void qt_init(QApplicationPrivate *priv, int, if (X11->desktopEnvironment == DE_KDE) X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); +#if !defined(QT_NO_STYLE_GTK) + if (X11->desktopEnvironment == DE_GNOME) { + static bool menusHaveIcons = QGtk::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true); + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons); + } +#endif qt_set_input_encoding(); qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol); diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm index ed62d02..2f1d88d 100644 --- a/src/gui/kernel/qcocoaapplication_mac.mm +++ b/src/gui/kernel/qcocoaapplication_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ /**************************************************************************** diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index cbf5cb6..b6aa454 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ /**************************************************************************** diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 1bdb123..14e4510 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #include "qmacdefines_mac.h" diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index bc32078..59494a7 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -201,7 +201,6 @@ extern "C" { composingText = new QString(); composing = false; sendKeyEvents = true; - inKeyDown = false; currentCustomTypes = 0; [self setHidden:YES]; return self; @@ -1037,7 +1036,6 @@ extern "C" { - (void)keyDown:(NSEvent *)theEvent { - inKeyDown = true; sendKeyEvents = true; QWidget *widgetToGetKey = qwidget; @@ -1057,7 +1055,6 @@ extern "C" { if (!keyOK && !sendToPopup) [super keyDown:theEvent]; } - inKeyDown = false; } @@ -1104,13 +1101,7 @@ extern "C" { }; } - if ([aString length] && !inKeyDown) { - // Handle the case where insertText is called from somewhere else than the keyDown - // implementation, for example when inserting text from the character palette. - QInputMethodEvent e; - e.setCommitString(commitText); - qt_sendSpontaneousEvent(qwidget, &e); - } else if ([aString length] && composing) { + if ([aString length] && composing) { // Send the commit string to the widget. composing = false; sendKeyEvents = false; diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 9d4e3d0..3810a2b 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -86,7 +86,6 @@ Q_GUI_EXPORT bool composing; int composingLength; bool sendKeyEvents; - bool inKeyDown; QString *composingText; QStringList *currentCustomTypes; NSInteger dragEnterSequence; diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 59e8254..57dca6d 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #include "qmacdefines_mac.h" diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 0a7a00f..6704fda 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #import "private/qcocoawindowdelegate_mac_p.h" diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index d5e7167..7831893 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -133,21 +133,22 @@ private: /*! \fn void QGesture::cancelled() - The signal is emitted when the gesture is cancelled, for example the reset() - function is called while the gesture was in the process of emitting a - triggered() signal. Extended information about the gesture is contained in - the sender object. + The signal is emitted when the gesture is cancelled, for example the + reset() function is called while the gesture was in the process of + emitting a triggered() signal. Extended information about the + gesture is contained in the sender object. */ - /*! - Creates a new gesture handler object and marks it as a child of \a parent. + Creates a new gesture handler object and marks it as a child of \a + parent. \a gestureTarget is the object that the gesture will watch + for events. - The \a parent object is also the default event source for the gesture, - meaning that the gesture installs itself as an event filter for the \a - parent. + The \a parent object is also the default event source for the + gesture, meaning that the gesture installs itself as an event filter + for the \a parent. - \sa setGraphicsItem() + \sa setGraphicsItem() */ QGesture::QGesture(QObject *gestureTarget, QObject *parent) : QObject(*new QGesturePrivate, parent) @@ -173,7 +174,7 @@ QGesture::~QGesture() /*! \property QGesture::gestureTarget - Gesture target is the object that the gesture will observe for events. + Gesture target is the object that the gesture will watch for events. Typically this means that the gesture installs an event filter on the target object. */ @@ -240,15 +241,18 @@ void QGesture::updateState(Qt::GestureState state) return; } const Qt::GestureState oldState = d->state; - d->state = state; if (state != Qt::NoGesture && oldState > state) { // comparing the state as ints: state should only be changed from // started to (optionally) updated and to finished. + d->state = state; qWarning("QGesture::updateState: incorrect new state"); return; } - if (oldState == Qt::NoGesture) + if (oldState == Qt::NoGesture) { + d->state = Qt::GestureStarted; emit started(); + } + d->state = state; if (state == Qt::GestureUpdated) emit triggered(); else if (state == Qt::GestureFinished) diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 2cfabef..ddca79e 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -70,7 +70,7 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0), - state(Qt::NoGesture) + state(Qt::NoGesture), implicitGesture(false) { } @@ -81,6 +81,9 @@ public: QGraphicsItem *eventFilterProxyGraphicsItem; Qt::GestureState state; + + // the flag specifies if the gesture was created implicitely by Qt. + bool implicitGesture; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index cc30049..8e76715 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -47,6 +47,7 @@ #include <private/qapplication_p.h> #include <private/qevent_p.h> #include <private/qwidget_p.h> +#include <qmath.h> QT_BEGIN_NAMESPACE @@ -90,9 +91,12 @@ QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent) void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPanGesture); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); + if (gestureTarget && gestureTarget->isWidgetType()) { QWidget *w = static_cast<QWidget*>(gestureTarget.data()); - QApplicationPrivate::instance()->widgetGestures[w].pan = 0; + if (qAppPriv->widgetGestures[w].pan == q) + qAppPriv->widgetGestures[w].pan = 0; #if defined(Q_WS_WIN) qt_widget_private(w)->winSetupGestures(); #elif defined(Q_WS_MAC) @@ -103,7 +107,7 @@ void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) if (newGestureTarget && newGestureTarget->isWidgetType()) { QWidget *w = static_cast<QWidget*>(newGestureTarget); - QApplicationPrivate::instance()->widgetGestures[w].pan = q; + qAppPriv->widgetGestures[w].pan = q; #if defined(Q_WS_WIN) qt_widget_private(w)->winSetupGestures(); #elif defined(Q_WS_MAC) @@ -133,8 +137,13 @@ bool QPanGesture::event(QEvent *event) bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) { -#ifdef Q_WS_WIN Q_D(QPanGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#ifdef Q_WS_WIN if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); @@ -164,11 +173,12 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) return false; } if (state() == Qt::NoGesture) { - d->lastOffset = d->totalOffset = QSize(); + d->lastOffset = d->totalOffset = d->offset = QSize(); } else { - d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), - ev->position.y() - d->lastPosition.y()); - d->totalOffset += d->lastOffset; + d->lastOffset = d->offset; + d->offset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->offset; } d->lastPosition = ev->position; updateState(nextState); @@ -181,23 +191,29 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) /*! \internal */ bool QPanGesture::filterEvent(QEvent *event) { -#if defined(Q_WS_WIN) Q_D(QPanGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#if defined(Q_WS_WIN) const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); if (event->type() == QEvent::TouchBegin) { QTouchEvent::TouchPoint p = ev->touchPoints().at(0); d->lastPosition = p.pos().toPoint(); - d->lastOffset = d->totalOffset = QSize(); + d->lastOffset = d->totalOffset = d->offset = QSize(); } else if (event->type() == QEvent::TouchEnd) { if (state() != Qt::NoGesture) { if (ev->touchPoints().size() == 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); - d->lastOffset = + d->lastOffset = d->offset; + d->offset = QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(), p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2; - d->totalOffset += d->lastOffset; + d->totalOffset += d->offset; } updateState(Qt::GestureFinished); } @@ -206,10 +222,11 @@ bool QPanGesture::filterEvent(QEvent *event) if (ev->touchPoints().size() == 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); - d->lastOffset = + d->lastOffset = d->offset; + d->offset = QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(), p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2; - d->totalOffset += d->lastOffset; + d->totalOffset += d->offset; if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { updateState(Qt::GestureUpdated); @@ -219,7 +236,6 @@ bool QPanGesture::filterEvent(QEvent *event) #elif defined(QT_MAC_USE_COCOA) // The following implements single touch // panning on Mac: - Q_D(QPanGesture); const int panBeginDelay = 300; const int panBeginRadius = 3; const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); @@ -252,8 +268,9 @@ bool QPanGesture::filterEvent(QEvent *event) QPointF mousePos = QCursor::pos(); QPointF dist = mousePos - d->lastPosition; d->lastPosition = mousePos; - d->lastOffset = QSizeF(dist.x(), dist.y()); - d->totalOffset += d->lastOffset; + d->lastOffset = d->offset; + d->offset = QSizeF(dist.x(), dist.y()); + d->totalOffset += d->offset; updateState(Qt::GestureUpdated); } } else if (state() == Qt::NoGesture) { @@ -273,7 +290,7 @@ bool QPanGesture::filterEvent(QEvent *event) void QPanGesture::reset() { Q_D(QPanGesture); - d->lastOffset = d->totalOffset = QSize(0, 0); + d->lastOffset = d->totalOffset = d->offset = QSize(0, 0); d->lastPosition = QPoint(0, 0); #if defined(QT_MAC_USE_COCOA) @@ -298,8 +315,7 @@ QSizeF QPanGesture::totalOffset() const /*! \property QPanGesture::lastOffset - Specifies a pan offset since the last time the gesture was - triggered. + Specifies a pan offset the last time the gesture was triggered. */ QSizeF QPanGesture::lastOffset() const { @@ -307,6 +323,18 @@ QSizeF QPanGesture::lastOffset() const return d->lastOffset; } +/*! + \property QPanGesture::offset + + Specifies the current pan offset since the last time the gesture was + triggered. +*/ +QSizeF QPanGesture::offset() const +{ + Q_D(const QPanGesture); + return d->offset; +} + ////////////////////////////////////////////////////////////////////////////// /*! @@ -360,8 +388,13 @@ bool QPinchGesture::event(QEvent *event) bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) { -#if defined(Q_WS_WIN) || defined(Q_WS_MAC) Q_D(QPinchGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); #if defined(Q_WS_WIN) @@ -380,39 +413,80 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) // next we might receive the first gesture update event, so we // prepare for it. d->state = Qt::NoGesture; - d->scaleFactor = d->lastScaleFactor = 1; - d->rotationAngle = d->lastRotationAngle = 0; + d->changes = 0; + d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; + d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); #if defined(Q_WS_WIN) d->initialDistance = 0; + d->lastSequenceId = ev->sequenceId; #endif return false; - case QNativeGestureEvent::Rotate: - d->scaleFactor = 0; + case QNativeGestureEvent::Rotate: { + d->lastScaleFactor = d->scaleFactor; d->lastRotationAngle = d->rotationAngle; -#if defined(Q_WS_WIN) - d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument); -#elif defined(Q_WS_MAC) - d->rotationAngle = ev->percentage; -#endif +#if defined(Q_WS_MAC) + d->rotationAngle += ev->percentage; nextState = Qt::GestureUpdated; +#elif defined(Q_WS_WIN) + // This is a workaround for an issue with the native rotation + // gesture on Windows 7. For some reason the rotation angle in the + // first WM_GESTURE message in a sequence contains value that is + // off a little bit and causes the rotating item to "jump", so + // we just ignore the first WM_GESTURE in every sequence. + bool windowsRotateWorkaround = false; + if (!d->lastSequenceId) { + windowsRotateWorkaround = true; + d->lastSequenceId = ev->sequenceId; + } + if (d->lastSequenceId > 0 && d->lastSequenceId != (ulong)-1 && ev->sequenceId != d->lastSequenceId) { + // this is the first WM_GESTURE message in a sequence. + d->totalRotationAngle += d->rotationAngle; + windowsRotateWorkaround = true; + // a magic value to mark that the next WM_GESTURE message is + // the second message in a sequence and we should clear the + // lastRotationAngle + d->lastSequenceId = (ulong)-1; + } + if (!windowsRotateWorkaround) { + d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument) * 180. / M_PI; + if (d->lastSequenceId == (ulong)-1) { + // a special case since we need to set the lastRotationAngle to + // rotationAngle when the first WM_GESTURE is received in each + // sequence. + d->lastRotationAngle = d->rotationAngle; + } + d->lastSequenceId = ev->sequenceId; + } + if (!windowsRotateWorkaround) + nextState = Qt::GestureUpdated; +#endif + d->changes = QPinchGesture::RotationAngleChanged; event->accept(); break; + } case QNativeGestureEvent::Zoom: - d->rotationAngle = 0; + d->lastRotationAngle = d->rotationAngle; + d->lastScaleFactor = d->scaleFactor; #if defined(Q_WS_WIN) if (d->initialDistance != 0) { - d->lastScaleFactor = d->scaleFactor; int distance = int(qint64(ev->argument)); - d->scaleFactor = (qreal) distance / d->initialDistance; + if (d->lastSequenceId && ev->sequenceId != d->lastSequenceId) { + d->totalScaleFactor *= d->scaleFactor; + d->initialDistance = int(qint64(ev->argument)); + d->lastScaleFactor = d->scaleFactor = (qreal) distance / d->initialDistance; + } else { + d->scaleFactor = (qreal) distance / d->initialDistance; + } + d->lastSequenceId = ev->sequenceId; } else { d->initialDistance = int(qint64(ev->argument)); } #elif defined(Q_WS_MAC) - d->lastScaleFactor = d->scaleFactor; - d->scaleFactor = ev->percentage; + d->scaleFactor += ev->percentage; #endif nextState = Qt::GestureUpdated; + d->changes = QPinchGesture::ScaleFactorChanged; event->accept(); break; case QNativeGestureEvent::GestureEnd: @@ -427,6 +501,8 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) d->startCenterPoint = d->centerPoint; d->lastCenterPoint = d->centerPoint; d->centerPoint = static_cast<QWidget*>(receiver)->mapFromGlobal(ev->position); + if (d->lastCenterPoint != d->centerPoint) + d->changes |= QPinchGesture::CenterPointChanged; updateState(nextState); return true; } @@ -438,6 +514,12 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) /*! \internal */ bool QPinchGesture::filterEvent(QEvent *event) { + Q_D(QPinchGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + Q_UNUSED(event); return false; } @@ -446,16 +528,44 @@ bool QPinchGesture::filterEvent(QEvent *event) void QPinchGesture::reset() { Q_D(QPinchGesture); - d->scaleFactor = d->lastScaleFactor = 0; - d->rotationAngle = d->lastRotationAngle = 0; + d->changes = 0; + d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; + d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); QGesture::reset(); } /*! + \property QPinchGesture::whatChanged + + Specifies which values were changed in the gesture. +*/ +QPinchGesture::WhatChanged QPinchGesture::whatChanged() const +{ + return d_func()->changes; +} + +/*! + \property QPinchGesture::totalScaleFactor + + Specifies a total scale factor of the pinch gesture since the gesture + started. +*/ +qreal QPinchGesture::totalScaleFactor() const +{ + Q_D(const QPinchGesture); + return d->totalScaleFactor * d->scaleFactor; +} + +/*! \property QPinchGesture::scaleFactor Specifies a scale factor of the pinch gesture. + + If the gesture consists of several pinch sequences (i.e. zoom and rotate + sequences), then this property specifies the scale factor in the current + sequence. When pinching changes the rotation angle only, the value of this + property is 1. */ qreal QPinchGesture::scaleFactor() const { @@ -473,9 +583,29 @@ qreal QPinchGesture::lastScaleFactor() const } /*! + \property QPinchGesture::totalRotationAngle + + Specifies a total rotation angle of the gesture since the gesture started. + + The angle is specified in degrees. +*/ +qreal QPinchGesture::totalRotationAngle() const +{ + Q_D(const QPinchGesture); + return d->totalRotationAngle + d->rotationAngle; +} + +/*! \property QPinchGesture::rotationAngle Specifies a rotation angle of the gesture. + + If the gesture consists of several pinch sequences (i.e. zoom and rotate + sequences), then this property specifies the rotation angle in the current + sequence. When pinching changes the scale factor only, the value of this + property is 0. + + The angle is specified in degrees. */ qreal QPinchGesture::rotationAngle() const { @@ -486,6 +616,8 @@ qreal QPinchGesture::rotationAngle() const \property QPinchGesture::lastRotationAngle Specifies a previous rotation angle of the gesture. + + The angle is specified in degrees. */ qreal QPinchGesture::lastRotationAngle() const { diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index bb6f3b6..53c4416 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -61,6 +61,7 @@ class Q_GUI_EXPORT QPanGesture : public QGesture Q_PROPERTY(QSizeF totalOffset READ totalOffset) Q_PROPERTY(QSizeF lastOffset READ lastOffset) + Q_PROPERTY(QSizeF offset READ offset) public: QPanGesture(QWidget *gestureTarget, QObject *parent = 0); @@ -69,6 +70,7 @@ public: QSizeF totalOffset() const; QSizeF lastOffset() const; + QSizeF offset() const; protected: void reset(); @@ -78,6 +80,7 @@ private: bool eventFilter(QObject *receiver, QEvent *event); friend class QWidget; + friend class QAbstractScrollAreaPrivate; }; class QPinchGesturePrivate; @@ -86,31 +89,48 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) - Q_PROPERTY(qreal scaleFactor READ scaleFactor) +public: + enum WhatChange { + ScaleFactorChanged = 0x1, + RotationAngleChanged = 0x2, + CenterPointChanged = 0x4 + }; + Q_DECLARE_FLAGS(WhatChanged, WhatChange) + + Q_PROPERTY(WhatChanged whatChanged READ whatChanged) + + Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor) Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor) + Q_PROPERTY(qreal scaleFactor READ scaleFactor) - Q_PROPERTY(qreal rotationAngle READ rotationAngle) + Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle) Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle) + Q_PROPERTY(qreal rotationAngle READ rotationAngle) Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint) Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint) Q_PROPERTY(QPointF centerPoint READ centerPoint) public: + QPinchGesture(QWidget *gestureTarget, QObject *parent = 0); bool filterEvent(QEvent *event); void reset(); + WhatChanged whatChanged() const; + QPointF startCenterPoint() const; QPointF lastCenterPoint() const; QPointF centerPoint() const; - qreal scaleFactor() const; + qreal totalScaleFactor() const; qreal lastScaleFactor() const; + qreal scaleFactor() const; - qreal rotationAngle() const; + qreal totalRotationAngle() const; qreal lastRotationAngle() const; + qreal rotationAngle() const; private: bool event(QEvent *event); diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 270f307..354ebee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -74,6 +74,7 @@ public: QSizeF totalOffset; QSizeF lastOffset; + QSizeF offset; QPointF lastPosition; #if defined(QT_MAC_USE_COCOA) @@ -88,25 +89,32 @@ class QPinchGesturePrivate : public QGesturePrivate public: QPinchGesturePrivate() - : scaleFactor(0), lastScaleFactor(0), - rotationAngle(0), lastRotationAngle(0) + : changes(0), totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.), + totalRotationAngle(0.), lastRotationAngle(0.), rotationAngle(0.) #ifdef Q_WS_WIN - ,initialDistance(0) + ,initialDistance(0), lastSequenceId(0) #endif { } void setupGestureTarget(QObject *o); - qreal scaleFactor; + QPinchGesture::WhatChanged changes; + + qreal totalScaleFactor; // total scale factor, excluding the current sequence. qreal lastScaleFactor; - qreal rotationAngle; + qreal scaleFactor; // scale factor in the current sequence. + + qreal totalRotationAngle; // total rotation angle, excluding the current sequence. qreal lastRotationAngle; + qreal rotationAngle; // rotation angle in the current sequence. + QPointF startCenterPoint; QPointF lastCenterPoint; QPointF centerPoint; #ifdef Q_WS_WIN int initialDistance; + ulong lastSequenceId; #endif }; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 863c43e..44f9db1 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -82,8 +82,6 @@ #include "private/qstyle_p.h" #include "private/qinputcontext_p.h" #include "qfileinfo.h" -#include "qstandardgestures.h" -#include "qstandardgestures_p.h" #if defined (Q_WS_WIN) # include <private/qwininputcontext_p.h> diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 8e60fb3..0ec7e7e 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -2062,29 +2062,21 @@ void QWidgetPrivate::registerTouchWindow() void QWidgetPrivate::winSetupGestures() { Q_Q(QWidget); - if (!q) - return; - if (!q->isVisible()) + if (!q || !q->isVisible()) return; QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - bool needh = false; - bool needv = false; - bool singleFingerPanEnabled = false; QApplicationPrivate::WidgetStandardGesturesMap::const_iterator it = qAppPriv->widgetGestures.find(q); if (it == qAppPriv->widgetGestures.end()) return; const QStandardGestures &gestures = it.value(); - WId winid = 0; + WId winid = q->effectiveWinId(); - if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q)) { - winid = asa->viewport()->internalWinId(); - if (!winid) { - QWidget *nativeParent = asa->viewport()->nativeParentWidget(); - if (!nativeParent) - return; - winid = nativeParent->internalWinId(); - } + bool needh = false; + bool needv = false; + bool singleFingerPanEnabled = false; + + if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q->parent())) { QScrollBar *hbar = asa->horizontalScrollBar(); QScrollBar *vbar = asa->verticalScrollBar(); Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy(); @@ -2094,12 +2086,6 @@ void QWidgetPrivate::winSetupGestures() needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled; - } else { - winid = q->internalWinId(); - if (!winid) { - if (QWidget *nativeParent = q->nativeParentWidget()) - winid = nativeParent->internalWinId(); - } } if (winid && qAppPriv->SetGestureConfig) { GESTURECONFIG gc[3]; diff --git a/src/gui/painting/makepsheader.pl b/src/gui/painting/makepsheader.pl index 30a5eea..de13209 100755 --- a/src/gui/painting/makepsheader.pl +++ b/src/gui/painting/makepsheader.pl @@ -1,4 +1,44 @@ #!/usr/bin/perl +############################################################################# +## +## 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# open(INPUT, 'qpsprinter.ps') or die "Can't open qpsprinter.ps"; diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index feef15a..5abac2f 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -42,6 +42,7 @@ HEADERS += \ painting/qtransform.h \ painting/qwindowsurface_p.h \ painting/qwmatrix.h \ + painting/qpaintbuffer_p.h SOURCES += \ @@ -79,6 +80,7 @@ SOURCES += \ painting/qtextureglyphcache.cpp \ painting/qtransform.cpp \ painting/qwindowsurface.cpp \ + painting/qpaintbuffer.cpp SOURCES += \ painting/qpaintengine_raster.cpp \ diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h index e107c72..68d9ec0 100644 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ b/src/gui/painting/qdrawhelper_mmx_p.h @@ -65,7 +65,7 @@ #define C_80 const m64 mmx_0x0080 = _mm_set1_pi16(0x80) #define C_00 const m64 mmx_0x0000 = _mm_setzero_si64() -#if defined(Q_OS_WIN) +#ifdef Q_CC_MSVC # pragma warning(disable: 4799) // No EMMS at end of function #endif diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 5e8fce5..32a8432 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -183,7 +183,7 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); const __m128i c128 = _mm_set1_epi16(c); -#if defined(Q_OS_WIN) +#if defined(Q_CC_MSVC) # pragma warning(disable: 4309) // truncation of constant value #endif const __m128i maskmask = _mm_set_epi16(0x0101, 0x0202, 0x0404, 0x0808, diff --git a/src/gui/painting/qdrawhelper_sse_p.h b/src/gui/painting/qdrawhelper_sse_p.h index dd75bd9..23b629e 100644 --- a/src/gui/painting/qdrawhelper_sse_p.h +++ b/src/gui/painting/qdrawhelper_sse_p.h @@ -132,7 +132,7 @@ inline void qt_bitmapblit16_sse_template(QRasterBuffer *rasterBuffer, const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); const __m64 c64 = _mm_set1_pi16(c); -#if defined(Q_OS_WIN) +#ifdef Q_CC_MSVC # pragma warning(disable: 4309) // truncation of constant value #endif const __m64 maskmask1 = _mm_set_pi16(0x1010, 0x2020, 0x4040, 0x8080); diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h index 1c3445c..358066e 100644 --- a/src/gui/painting/qemulationpaintengine_p.h +++ b/src/gui/painting/qemulationpaintengine_p.h @@ -92,6 +92,8 @@ public: virtual void setState(QPainterState *s); + virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;} + inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; } inline const QPainterState *state() const { return (const QPainterState *)QPaintEngine::state; } diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 83f1cb9..d89144e 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -1,5 +1,8 @@ /**************************************************************************** ** +** 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$ diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp new file mode 100644 index 0000000..04ddd7d --- /dev/null +++ b/src/gui/painting/qpaintbuffer.cpp @@ -0,0 +1,1745 @@ +/**************************************************************************** +** +** 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qmath.h> +#include <private/qpainterpath_p.h> +#include <private/qpaintbuffer_p.h> +//#include <private/qtextengine_p.h> +#include <private/qfontengine_p.h> +#include <private/qemulationpaintengine_p.h> + +#include <QDebug> + +//#define QPAINTBUFFER_DEBUG_DRAW + +extern int qt_defaultDpiX(); +extern int qt_defaultDpiY(); +extern void qt_format_text(const QFont &font, + const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, + int tabstops, int* tabarray, int tabarraylen, + QPainter *painter); + +QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item) + : m_item(static_cast<const QTextItemInt &>(item)) +{ + QChar *chars = new QChar[m_item.num_chars]; + unsigned short *logClusters = new unsigned short[m_item.num_chars]; + memcpy(chars, m_item.chars, m_item.num_chars * sizeof(QChar)); + memcpy(logClusters, m_item.logClusters, m_item.num_chars * sizeof(unsigned short)); + m_item.chars = chars; + m_item.logClusters = logClusters; + + const int size = QGlyphLayout::spaceNeededForGlyphLayout(m_item.glyphs.numGlyphs); + char *glyphLayoutData = new char[size]; + QGlyphLayout glyphs(glyphLayoutData, m_item.glyphs.numGlyphs); + memcpy(glyphs.offsets, m_item.glyphs.offsets, m_item.glyphs.numGlyphs * sizeof(QFixedPoint)); + memcpy(glyphs.glyphs, m_item.glyphs.glyphs, m_item.glyphs.numGlyphs * sizeof(HB_Glyph)); + memcpy(glyphs.advances_x, m_item.glyphs.advances_x, m_item.glyphs.numGlyphs * sizeof(QFixed)); + memcpy(glyphs.advances_y, m_item.glyphs.advances_y, m_item.glyphs.numGlyphs * sizeof(QFixed)); + memcpy(glyphs.justifications, m_item.glyphs.justifications, m_item.glyphs.numGlyphs * sizeof(QGlyphJustification)); + memcpy(glyphs.attributes, m_item.glyphs.attributes, m_item.glyphs.numGlyphs * sizeof(HB_GlyphAttributes)); + m_item.glyphs = glyphs; + + m_font = *m_item.f; + m_item.f = &m_font; + + m_item.fontEngine->ref.ref(); // Increment reference count. +} + +QTextItemIntCopy::~QTextItemIntCopy() +{ + delete m_item.chars; + delete m_item.logClusters; + delete m_item.glyphs.data(); + if (!m_item.fontEngine->ref.deref()) + delete m_item.fontEngine; +} + +/************************************************************************ + * + * QPaintBufferSignalProxy + * + ************************************************************************/ + +Q_GLOBAL_STATIC(QPaintBufferSignalProxy, theSignalProxy) + +QPaintBufferSignalProxy *QPaintBufferSignalProxy::instance() +{ + return theSignalProxy(); +} + +/************************************************************************ + * + * QPaintBufferPrivate + * + ************************************************************************/ + +QPaintBufferPrivate::QPaintBufferPrivate() + : ref(1), engine(0), penWidthAdjustment(0) + , calculateBoundingRect(true) + , cache(0) +{ +} + +QPaintBufferPrivate::~QPaintBufferPrivate() +{ + QPaintBufferSignalProxy::instance()->emitAboutToDestroy(this); + + for (int i = 0; i < commands.size(); ++i) { + const QPaintBufferCommand &cmd = commands.at(i); + if (cmd.id == QPaintBufferPrivate::Cmd_DrawTextItem) + delete reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(variants.at(cmd.offset))); + } +} + + +inline void QPaintBufferPrivate::updateBoundingRect(const QRectF &br) +{ + // transform to device coords and adjust for pen width + Q_ASSERT(engine && engine->painter()); + QPainter *painter = engine->painter(); + const QTransform transform = painter->transform(); + QRectF devRect = transform.mapRect(br); + if (penWidthAdjustment > 0) { + devRect = devRect.adjusted(-penWidthAdjustment, -penWidthAdjustment, + penWidthAdjustment, penWidthAdjustment); + } + + if (boundingRect.isEmpty()) { + boundingRect = devRect; + } else { + qreal min_x = qMin(devRect.left(), boundingRect.left()); + qreal min_y = qMin(devRect.top(), boundingRect.top()); + qreal max_x = qMax(devRect.right(), boundingRect.right()); + qreal max_y = qMax(devRect.bottom(), boundingRect.bottom()); + boundingRect = QRectF(min_x, min_y, max_x - min_x, max_y - min_y); + } + if (painter->hasClipping()) + boundingRect &= transform.mapRect(painter->clipRegion().boundingRect()); +} + + +/************************************************************************ + * + * QPaintBuffer + * + ************************************************************************/ + + + +QPaintBuffer::QPaintBuffer() + : d_ptr(new QPaintBufferPrivate) +{ +} + +QPaintBuffer::~QPaintBuffer() +{ + if (!d_ptr->ref.deref()) + delete d_ptr; +} + +QPaintBuffer::QPaintBuffer(const QPaintBuffer &other) + : QPaintDevice(), d_ptr(other.d_ptr) +{ + d_ptr->ref.ref(); +} + +QPaintEngine *QPaintBuffer::paintEngine() const +{ + QPaintBufferPrivate *d = const_cast<QPaintBuffer *>(this)->d_ptr; + if (!d->engine) + d->engine = new QPaintBufferEngine(d); + return d->engine; +} + + +int QPaintBuffer::metric(PaintDeviceMetric metric) const +{ + int val = 0; + switch (metric) { + case PdmWidth: + val = qCeil(d_ptr->boundingRect.width()); + break; + case PdmHeight: + val = qCeil(d_ptr->boundingRect.height()); + break; + case PdmDpiX: + case PdmPhysicalDpiX: + val = qt_defaultDpiX(); + break; + case PdmDpiY: + case PdmPhysicalDpiY: + val = qt_defaultDpiY(); + break; + default: + val = QPaintDevice::metric(metric); + } + + return val; +} + +int QPaintBuffer::devType() const +{ + return QInternal::PaintBuffer; +} + +QPaintBuffer &QPaintBuffer::operator=(const QPaintBuffer &other) +{ + if (other.d_ptr != d_ptr) { + QPaintBufferPrivate *data = other.d_ptr; + data->ref.ref(); + if (d_ptr->ref.deref()) + delete d_ptr; + d_ptr = data; + } + return *this; +} + +bool QPaintBuffer::isEmpty() const +{ + return d_ptr->commands.isEmpty(); +} + + + +void QPaintBuffer::draw(QPainter *painter) 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"); +#endif + + if (painter && !painter->isActive()) + return; + + QPaintEngineEx *xengine = painter->paintEngine()->isExtended() + ? (QPaintEngineEx *) painter->paintEngine() : 0; + if (xengine) { + QPaintEngineExReplayer player; + player.draw(*this, painter); + } else { + QPainterReplayer player; + player.draw(*this, painter); + } + +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; +#endif +} + + +QRectF QPaintBuffer::boundingRect() const +{ + return d_ptr->boundingRect; +} + +void QPaintBuffer::setBoundingRect(const QRectF &rect) +{ + d_ptr->boundingRect = rect; + d_ptr->calculateBoundingRect = false; +} + + +class QPaintBufferEnginePrivate : public QPaintEngineExPrivate +{ + Q_DECLARE_PUBLIC(QPaintBufferEngine) +public: + void systemStateChanged() { + Q_Q(QPaintBufferEngine); + q->buffer->addCommand(QPaintBufferPrivate::Cmd_SystemStateChanged, QVariant(systemClip)); + } +}; + + +/************************************************************************ + * + * QPaintBufferEngine + * + ************************************************************************/ + +QPaintBufferEngine::QPaintBufferEngine(QPaintBufferPrivate *b) + : QPaintEngineEx(*(new QPaintBufferEnginePrivate)) + , buffer(b) + , m_begin_detected(false) + , m_save_detected(false) + , m_stream_raw_text_items(false) +{ +} + +bool QPaintBufferEngine::begin(QPaintDevice *) +{ + Q_D(QPaintBufferEngine); + painter()->save(); + d->systemStateChanged(); + return true; +} + +bool QPaintBufferEngine::end() +{ + painter()->restore(); + m_created_state = 0; + return true; +} + +QPainterState *QPaintBufferEngine::createState(QPainterState *orig) const +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: createState, orig=" << orig << ", current=" << state(); +#endif + + Q_ASSERT(!m_begin_detected); + Q_ASSERT(!m_save_detected); + + if (orig == 0) { + m_begin_detected = true; + return new QPainterState(); + } else { + m_save_detected = true; + return new QPainterState(orig); + } +} + +void QPaintBufferEngine::clip(const QVectorPath &path, Qt::ClipOperation op) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: clip vpath:" << path.elementCount() << "op:" << op; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_ClipVectorPath, path); + cmd->extra = op; +} + +void QPaintBufferEngine::clip(const QRect &rect, Qt::ClipOperation op) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: clip rect:" << rect << "op:" << op; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_ClipRect, (int *) &rect, 4, 1); + cmd->extra = op; +} + +void QPaintBufferEngine::clip(const QRegion ®ion, Qt::ClipOperation op) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: clip region br:" << region.boundingRect() << "op:" << op; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_ClipRegion, QVariant(region)); + cmd->extra = op; +} + +void QPaintBufferEngine::clip(const QPainterPath &path, Qt::ClipOperation op) +{ + // ### TODO +// QPaintBufferCommand *cmd = +// buffer->addCommand(QPaintBufferPrivate::Cmd_ClipPath, QVariant(path)); +// cmd->extra = op; + QPaintEngineEx::clip(path, op); +} + +void QPaintBufferEngine::clipEnabledChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: clip enable change" << state()->clipEnabled; +#endif + + buffer->addCommand(QPaintBufferPrivate::Cmd_SetClipEnabled, state()->clipEnabled); +} + +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) { + buffer->variants[buffer->commands.last().offset] = pen; + return; + } + if (buffer->calculateBoundingRect) { + if (pen.style() == Qt::NoPen) { + buffer->penWidthAdjustment = 0; + } else { + qreal penWidth = (pen.widthF() == 0) ? 1 : pen.widthF(); + QPointF transformedWidth(penWidth, penWidth); + if (!pen.isCosmetic()) + transformedWidth = painter()->transform().map(transformedWidth); + buffer->penWidthAdjustment = transformedWidth.x() / 2.0; + } + } + 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) { + buffer->variants[buffer->commands.last().offset] = brush; + return; + } + + buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrush, brush); +} + +void QPaintBufferEngine::brushOriginChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: brush origin changed" << state()->brushOrigin; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrushOrigin, state()->brushOrigin); +} + +void QPaintBufferEngine::opacityChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: opacity changed" << state()->opacity; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_SetOpacity, state()->opacity); +} + +void QPaintBufferEngine::compositionModeChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: composition mode" << state()->composition_mode; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_SetCompositionMode); + cmd->extra = state()->composition_mode; +} + +void QPaintBufferEngine::renderHintsChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: render hints changed" << state()->renderHints; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_SetRenderHints); + cmd->extra = state()->renderHints; +} + +void QPaintBufferEngine::transformChanged() +{ + // ### accumulate, like in QBrush case... + if (!buffer->commands.isEmpty() + && buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetTransform) { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: compressing " << state()->matrix; +#endif + buffer->variants[buffer->commands.last().offset] = state()->matrix; + return; + } + +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: " << state()->matrix; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_SetTransform, state()->matrix); +} + +void QPaintBufferEngine::backgroundModeChanged() +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintEngineBuffer: background mode changed" << state()->bgMode; +#endif + QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_SetBackgroundMode); + cmd->extra = state()->bgMode; +} + +void QPaintBufferEngine::draw(const QVectorPath &path) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: draw vpath:" << path.elementCount(); +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path); +// if (buffer->calculateBoundingRect) { +// QRealRect r = path.controlPointRect(); +// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); +// } +} + +void QPaintBufferEngine::fill(const QVectorPath &path, const QBrush &brush) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: fill vpath:" << path.elementCount() << brush; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_FillVectorPath, path); + cmd->extra = buffer->addData(QVariant(brush)); +// if (buffer->calculateBoundingRect) { +// QRealRect r = path.controlPointRect(); +// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); +// } +} + +void QPaintBufferEngine::stroke(const QVectorPath &path, const QPen &pen) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: stroke vpath:" << path.elementCount() << pen; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_StrokeVectorPath, path); + cmd->extra = buffer->addData(QVariant(pen)); +// if (buffer->calculateBoundingRect) { +// QRealRect r = path.controlPointRect(); +// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); +// } +} + +void QPaintBufferEngine::fillRect(const QRectF &rect, const QBrush &brush) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: fillRect brush:" << rect << brush; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_FillRectBrush, (qreal *) &rect, 4, 1); + cmd->extra = buffer->addData(brush); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(rect); +} + +void QPaintBufferEngine::fillRect(const QRectF &rect, const QColor &color) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: fillRect color:" << rect << color; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_FillRectColor, (qreal *) &rect, 4, 1); + cmd->extra = buffer->addData(color); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(rect); +} + +void QPaintBufferEngine::drawRects(const QRect *rects, int rectCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawRectsI:" << rectCount; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawRectI, (int *) rects, 4 * rectCount, rectCount); + cmd->extra = rectCount; + + if (buffer->calculateBoundingRect) { + if (rectCount == 1) { + buffer->updateBoundingRect(rects[0]); + } else { + int min_x = rects[0].left(); + int min_y = rects[0].top(); + int max_x = rects[0].left() + rects[0].width(); + int max_y = rects[0].top() + rects[0].height(); + for (int i=1; i< rectCount; ++i) { + if (rects[i].left() < min_x) + min_x = rects[i].left(); + if (rects[i].top() < min_y) + min_y = rects[i].top(); + if (rects[i].right() > max_x) + max_x = rects[i].left() + rects[i].width(); + if (rects[i].bottom() > max_y) + max_y = rects[i].top() + rects[i].height(); + + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } + } +} + +void QPaintBufferEngine::drawRects(const QRectF *rects, int rectCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawRectsF:" << rectCount; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawRectF, (qreal *) rects, 4 * rectCount, rectCount); + cmd->extra = rectCount; + + if (buffer->calculateBoundingRect) { + if (rectCount == 1) { + buffer->updateBoundingRect(rects[0]); + } else { + qreal min_x = rects[0].left(); + qreal min_y = rects[0].top(); + qreal max_x = rects[0].right(); + qreal max_y = rects[0].bottom(); + for (int i=1; i< rectCount; ++i) { + if (rects[i].left() < min_x) + min_x = rects[i].left(); + if (rects[i].top() < min_y) + min_y = rects[i].top(); + if (rects[i].right() > max_x) + max_x = rects[i].right(); + if (rects[i].bottom() > max_y) + max_y = rects[i].bottom(); + + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } + } +} + +void QPaintBufferEngine::drawLines(const QLine *lines, int lineCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawLinesI:" << lineCount; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawLineI, (int *) lines, 4 * lineCount, lineCount); + cmd->extra = lineCount; + + if (buffer->calculateBoundingRect) { + int min_x = lines[0].p1().x(); + int min_y = lines[0].p1().y(); + int max_x = lines[0].p2().x(); + int max_y = lines[0].p2().y(); + if (min_x > max_x) + qSwap(min_x, max_x); + if (min_y > max_y) + qSwap(min_y, max_y); + for (int i=1; i < lineCount; ++i) { + int p1_x = lines[i].p1().x(); + int p1_y = lines[i].p1().y(); + int p2_x = lines[i].p2().x(); + int p2_y = lines[i].p2().y(); + if (p1_x > p2_x) { + min_x = qMin(p2_x, min_x); + max_x = qMax(p1_x, max_x); + } else { + min_x = qMin(p1_x, min_x); + max_x = qMax(p2_x, max_x); + } + if (p1_y > p2_y) { + min_y = qMin(p2_y, min_y); + max_y = qMax(p1_y, max_y); + } else { + min_y = qMin(p1_y, min_y); + max_y = qMax(p2_y, max_y); + } + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawLines(const QLineF *lines, int lineCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawLinesF:" << lineCount; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawLineF, (qreal *) lines, 4 * lineCount, lineCount); + cmd->extra = lineCount; + + if (buffer->calculateBoundingRect) { + qreal min_x = lines[0].p1().x(); + qreal min_y = lines[0].p1().y(); + qreal max_x = lines[0].p2().x(); + qreal max_y = lines[0].p2().y(); + if (min_x > max_x) + qSwap(min_x, max_x); + if (min_y > max_y) + qSwap(min_y, max_y); + for (int i=1; i < lineCount; ++i) { + qreal p1_x = lines[i].p1().x(); + qreal p1_y = lines[i].p1().y(); + qreal p2_x = lines[i].p2().x(); + qreal p2_y = lines[i].p2().y(); + if (p1_x > p2_x) { + min_x = qMin(p2_x, min_x); + max_x = qMax(p1_x, max_x); + } else { + min_x = qMin(p1_x, min_x); + max_x = qMax(p2_x, max_x); + } + if (p1_y > p2_y) { + min_y = qMin(p2_y, min_y); + max_y = qMax(p1_y, max_y); + } else { + min_y = qMin(p1_y, min_y); + max_y = qMax(p2_y, max_y); + } + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawEllipse(const QRectF &r) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawEllipseF:" << r; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawEllipseF, (qreal *) &r, 4, 1); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(r); +} + +void QPaintBufferEngine::drawEllipse(const QRect &r) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawEllipseI:" << r; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawEllipseI, (int *) &r, 4, 1); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(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)); + QPaintEngineEx::drawPath(path); + + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(path.boundingRect()); +} + +void QPaintBufferEngine::drawPoints(const QPoint *points, int pointCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPointsI: " << pointCount; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPointsI, (int *) points, 2 * pointCount, pointCount); + + if (buffer->calculateBoundingRect) { + int min_x = points[0].x(); + int min_y = points[0].y(); + int max_x = points[0].x()+1; + int max_y = points[0].y()+1; + for (int i=1; i<pointCount; ++i) { + int x = points[i].x(); + int y = points[i].y(); + min_x = qMin(min_x, x); + min_y = qMin(min_y, y); + max_x = qMax(max_x, x+1); + max_y = qMax(max_y, y+1); + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawPoints(const QPointF *points, int pointCount) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPointsF: " << pointCount; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPointsF, (qreal *) points, 2 * pointCount, pointCount); + + if (buffer->calculateBoundingRect) { + qreal min_x = points[0].x(); + qreal min_y = points[0].y(); + qreal max_x = points[0].x()+1; + qreal max_y = points[0].y()+1; + for (int i=1; i<pointCount; ++i) { + qreal x = points[i].x(); + qreal y = points[i].y(); + min_x = qMin(min_x, x); + min_y = qMin(min_y, y); + max_x = qMax(max_x, x+1); + max_y = qMax(max_y, y+1); + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawPolygon(const QPoint *pts, int count, PolygonDrawMode mode) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPolygonI: size:" << count << ", mode:" << mode; +#endif + if (mode == QPaintEngine::OddEvenMode || mode == QPaintEngine::WindingMode) { + QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolygonI, + (int *) pts, 2 * count, count); + cmd->extra = mode; + } else if (mode == QPaintEngine::PolylineMode) { + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolylineI, (int *) pts, 2 * count, count); + } else { + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawConvexPolygonI, (int *) pts, 2 * count, count); + } + + if (buffer->calculateBoundingRect) { + int min_x = pts[0].x(); + int min_y = pts[0].y(); + int max_x = pts[0].x(); + int max_y = pts[0].y(); + for (int i=1; i<count; ++i) { + int x = pts[i].x(); + int y = pts[i].y(); + min_x = qMin(min_x, x); + min_y = qMin(min_y, y); + max_x = qMax(max_x, x); + max_y = qMax(max_y, y); + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawPolygon(const QPointF *pts, int count, PolygonDrawMode mode) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPolygonF: size:" << count << ", mode:" << mode; +#endif + if (mode == QPaintEngine::OddEvenMode || mode == QPaintEngine::WindingMode) { + QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolygonF, + (qreal *) pts, 2 * count, count); + cmd->extra = mode; + } else if (mode == QPaintEngine::PolylineMode) { + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolylineF, (qreal *) pts, 2 * count, count); + } else { + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawConvexPolygonF, (qreal *) pts, 2 * count, count); + } + + if (buffer->calculateBoundingRect) { + qreal min_x = pts[0].x(); + qreal min_y = pts[0].y(); + qreal max_x = pts[0].x(); + qreal max_y = pts[0].y(); + for (int i=1; i<count; ++i) { + qreal x = pts[i].x(); + qreal y = pts[i].y(); + min_x = qMin(min_x, x); + min_y = qMin(min_y, y); + max_x = qMax(max_x, x); + max_y = qMax(max_y, y); + } + buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); + } +} + +void QPaintBufferEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPixmap: src/dest rects " << r << sr; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapRect, QVariant(pm)); + cmd->extra = buffer->addData((qreal *) &r, 4); + buffer->addData((qreal *) &sr, 4); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(r); +} + +void QPaintBufferEngine::drawPixmap(const QPointF &pos, const QPixmap &pm) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawPixmap: pos:" << pos; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapPos, QVariant(pm)); + cmd->extra = buffer->addData((qreal *) &pos, 2); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(QRectF(pos, pm.size())); +} + +void QPaintBufferEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, + Qt::ImageConversionFlags /*flags */) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawImage: src/dest rects " << r << sr; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapRect, QVariant(image)); + cmd->extra = buffer->addData((qreal *) &r, 4); + buffer->addData((qreal *) &sr, 4); + // ### flags... + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(r); +} + +void QPaintBufferEngine::drawImage(const QPointF &pos, const QImage &image) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawImage: pos:" << pos; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawImagePos, QVariant(image)); + cmd->extra = buffer->addData((qreal *) &pos, 2); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(QRectF(pos, image.size())); +} + +void QPaintBufferEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &s) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawTiledPixmap: src rect/offset:" << r << s; +#endif + QPaintBufferCommand *cmd = + buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTiledPixmap, QVariant(pm)); + cmd->extra = buffer->addData((qreal *) &r, 4); + buffer->addData((qreal *) &s, 2); + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(r); +} + +void QPaintBufferEngine::drawTextItem(const QPointF &pos, const QTextItem &ti) +{ +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: drawTextItem: pos:" << pos << ti.text(); +#endif + if (m_stream_raw_text_items) { + QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTextItem, qVariantFromValue<void *>(new QTextItemIntCopy(ti))); + + QFont font(ti.font()); + font.setUnderline(false); + font.setStrikeOut(false); + font.setOverline(false); + + const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); + qreal justificationWidth = 0; + if (si.justified) + justificationWidth = si.width.toReal(); + int renderFlags = ti.renderFlags(); + qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY()); + + buffer->addData(QVariant(font)); + cmd->extra = buffer->addData((qreal *) &pos, 2); + buffer->addData((qreal *) &justificationWidth, 1); + buffer->addData((qreal *) &scaleFactor, 1); + cmd->offset2 = buffer->addData((int *) &renderFlags, 1); + } else { + QList<QVariant> variants; + variants << QVariant(ti.font()) << QVariant(ti.text()); + QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawText, QVariant(variants)); + cmd->extra = buffer->addData((qreal *) &pos, 2); + } + + if (buffer->calculateBoundingRect) + buffer->updateBoundingRect(QRectF(pos, QSize(ti.width(), ti.ascent() + ti.descent() + 1))); +} + + +void QPaintBufferEngine::setState(QPainterState *s) +{ + if (m_begin_detected) { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: setState: begin, ignoring."; +#endif + m_begin_detected = false; + } else if (m_save_detected) { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: setState: save."; +#endif + m_save_detected = false; + buffer->addCommand(QPaintBufferPrivate::Cmd_Save); + } else { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << "QPaintBufferEngine: setState: restore."; +#endif + buffer->addCommand(QPaintBufferPrivate::Cmd_Restore); + } + + QPaintEngineEx::setState(s); +} + + +/*********************************************************************** + * + * class QPaintBufferPlayback_Painter + * + */ + +// QFakeDevice is used to create fonts with a custom DPI +// +class QFakeDevice : public QPaintDevice +{ +public: + QFakeDevice() { dpi_x = qt_defaultDpiX(); dpi_y = qt_defaultDpiY(); } + void setDpiX(int dpi) { dpi_x = dpi; } + void setDpiY(int dpi) { dpi_y = dpi; } + QPaintEngine *paintEngine() const { return 0; } + int metric(PaintDeviceMetric m) const + { + switch(m) { + case PdmPhysicalDpiX: + case PdmDpiX: + return dpi_x; + case PdmPhysicalDpiY: + case PdmDpiY: + return dpi_y; + default: + return QPaintDevice::metric(m); + } + } + +private: + int dpi_x; + int dpi_y; +}; + + +void QPainterReplayer::setupTransform(QPainter *_painter) +{ + painter = _painter; + m_world_matrix = painter->transform(); + m_world_matrix.scale(qreal(painter->device()->logicalDpiX()) / qreal(qt_defaultDpiX()), + qreal(painter->device()->logicalDpiY()) / qreal(qt_defaultDpiY())); + painter->setTransform(m_world_matrix); +} + +void QPainterReplayer::draw(const QPaintBuffer &buffer, QPainter *_painter) +{ + d = buffer.d_ptr; + setupTransform(_painter); + + for (int cmdIndex=0; cmdIndex<d->commands.size(); ++cmdIndex) { + const QPaintBufferCommand &cmd = d->commands.at(cmdIndex); + process(cmd); + } +} + +void QPainterReplayer::process(const QPaintBufferCommand &cmd) +{ + switch (cmd.id) { + case QPaintBufferPrivate::Cmd_Save: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_Save"; +#endif + painter->save(); + break; } + + case QPaintBufferPrivate::Cmd_Restore: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_Restore"; +#endif + painter->restore(); + break; } + + case QPaintBufferPrivate::Cmd_SetPen: { + QPen pen = qVariantValue<QPen>(d->variants.at(cmd.offset)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetPen: " << pen; +#endif + painter->setPen(pen); + break; } + + case QPaintBufferPrivate::Cmd_SetBrush: { + QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.offset)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetBrush: " << brush; +#endif + painter->setBrush(brush); + break; } + + case QPaintBufferPrivate::Cmd_SetBrushOrigin: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetBrushOrigin: " << d->variants.at(cmd.offset).toPointF(); +#endif + painter->setBrushOrigin(d->variants.at(cmd.offset).toPointF()); + break; } + + case QPaintBufferPrivate::Cmd_SetTransform: { + QTransform xform = qVariantValue<QTransform>(d->variants.at(cmd.offset)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetTransform, offset: " << cmd.offset << xform; +#endif + painter->setTransform(xform * m_world_matrix); + break; } + + case QPaintBufferPrivate::Cmd_SetCompositionMode: { + QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetCompositionMode, mode: " << mode; +#endif + painter->setCompositionMode(mode); + break; } + + case QPaintBufferPrivate::Cmd_SetRenderHints: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetRenderHints, hints: " << cmd.extra; +#endif + QPainter::RenderHints ph = painter->renderHints(); + QPainter::RenderHints nh = (QPainter::RenderHints) cmd.extra; + QPainter::RenderHints xored = ph ^ nh; + if (xored & QPainter::Antialiasing) + painter->setRenderHint(QPainter::Antialiasing, nh & QPainter::Antialiasing); + if (xored & QPainter::HighQualityAntialiasing) + painter->setRenderHint(QPainter::HighQualityAntialiasing, nh & QPainter::HighQualityAntialiasing); + if (xored & QPainter::TextAntialiasing) + painter->setRenderHint(QPainter::TextAntialiasing, nh & QPainter::TextAntialiasing); + if (xored & QPainter::SmoothPixmapTransform) + painter->setRenderHint(QPainter::SmoothPixmapTransform, nh & QPainter::SmoothPixmapTransform); + if (xored & QPainter::NonCosmeticDefaultPen) + painter->setRenderHint(QPainter::NonCosmeticDefaultPen, nh & QPainter::NonCosmeticDefaultPen); + break; } + + case QPaintBufferPrivate::Cmd_SetOpacity: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetOpacity: " << d->variants.at(cmd.offset).toDouble(); +#endif + painter->setOpacity(d->variants.at(cmd.offset).toDouble()); + break; } + + case QPaintBufferPrivate::Cmd_SetBackgroundMode: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetBackgroundMode: " << cmd.extra; +#endif + painter->setBackgroundMode((Qt::BGMode)cmd.extra); + break; } + + case QPaintBufferPrivate::Cmd_DrawVectorPath: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2; +#endif + QVectorPathCmd path(d, cmd); + painter->drawPath(path().convertToPainterPath()); + break; } + + case QPaintBufferPrivate::Cmd_StrokeVectorPath: { + QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_StrokeVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2; +#endif + QVectorPathCmd path(d, cmd); + painter->strokePath(path().convertToPainterPath(), pen); + break; } + + case QPaintBufferPrivate::Cmd_FillVectorPath: { + QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_FillVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2 << brush; +#endif + QVectorPathCmd path(d, cmd); + painter->fillPath(path().convertToPainterPath(), brush); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d->floats.at(cmd.offset) + << d->floats.at(cmd.offset+1); +#endif + Qt::FillRule fill = (QPaintEngine::PolygonDrawMode) cmd.extra == QPaintEngine::OddEvenMode + ? Qt::OddEvenFill : Qt::WindingFill; + painter->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, fill); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d->ints.at(cmd.offset) + << d->ints.at(cmd.offset+1); +#endif + Qt::FillRule fill = (QPaintEngine::PolygonDrawMode) cmd.extra == QPaintEngine::OddEvenMode + ? Qt::OddEvenFill : Qt::WindingFill; + painter->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, fill); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawPolyline((QPointF *) (d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawPolyline((QPoint *) (d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawConvexPolygonF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawConvexPolygonF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawConvexPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawConvexPolygonI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawConvexPolygonI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawConvexPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawEllipseF, offset: " << cmd.offset; +#endif + painter->drawEllipse(*(QRectF *)(d->floats.constData() + cmd.offset)); + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawEllipseI, offset: " << cmd.offset; +#endif + painter->drawEllipse(*(QRect *)(d->ints.constData() + cmd.offset)); + break; } + + case QPaintBufferPrivate::Cmd_DrawLineF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawLines((QLineF *)(d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawLineI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawLines((QLine *)(d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawPoints((QPointF *)(d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + painter->drawPoints((QPoint *)(d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPixmapRect: { + QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); + QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), + d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); + + QRectF sr(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5), + d->floats.at(cmd.extra+6), d->floats.at(cmd.extra+7)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPixmapRect:" << r << sr; +#endif + painter->drawPixmap(r, pm, sr); + break; } + + case QPaintBufferPrivate::Cmd_DrawPixmapPos: { + QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); + QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawPixmapPos:" << pos; +#endif + painter->drawPixmap(pos, pm); + break; } + + case QPaintBufferPrivate::Cmd_DrawTiledPixmap: { + QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); + QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), + d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); + + QPointF offset(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawTiledPixmap:" << r << offset; +#endif + painter->drawTiledPixmap(r, pm, offset); + break; } + + case QPaintBufferPrivate::Cmd_DrawImageRect: { + QImage image(d->variants.at(cmd.offset).value<QImage>()); + QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), + d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); + QRectF sr(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5), + d->floats.at(cmd.extra+6), d->floats.at(cmd.extra+7)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawImageRect:" << r << sr; +#endif + painter->drawImage(r, image, sr); + break; } + + case QPaintBufferPrivate::Cmd_DrawImagePos: { + QImage image(d->variants.at(cmd.offset).value<QImage>()); + QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawImagePos:" << pos; +#endif + painter->drawImage(pos, image); + break; } + + case QPaintBufferPrivate::Cmd_DrawRectF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawRectF, offset: " << cmd.offset; +#endif + painter->drawRects((QRectF *)(d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawRectI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_DrawRectI, offset: " << cmd.offset; +#endif + painter->drawRects((QRect *)(d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_FillRectBrush: { + QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; +#endif + painter->fillRect(*rect, brush); + break; } + + case QPaintBufferPrivate::Cmd_FillRectColor: { + QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; +#endif + painter->fillRect(*rect, color); + break; } + + case QPaintBufferPrivate::Cmd_SetClipEnabled: { + bool clipEnabled = d->variants.at(cmd.offset).toBool(); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SetClipEnabled:" << clipEnabled; +#endif + painter->setClipping(clipEnabled); + break; } + + case QPaintBufferPrivate::Cmd_ClipVectorPath: { + QVectorPathCmd path(d, cmd); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_ClipVectorPath:" << path().elementCount(); +#endif + painter->setClipPath(path().convertToPainterPath(), Qt::ClipOperation(cmd.extra)); + break; } + + + case QPaintBufferPrivate::Cmd_ClipRect: { + QRect rect(QPoint(d->ints.at(cmd.offset), d->ints.at(cmd.offset + 1)), + QPoint(d->ints.at(cmd.offset + 2), d->ints.at(cmd.offset + 3))); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_ClipRect:" << rect << cmd.extra; +#endif + painter->setClipRect(rect, Qt::ClipOperation(cmd.extra)); + break; } + + case QPaintBufferPrivate::Cmd_ClipRegion: { + QRegion region(d->variants.at(cmd.offset).value<QRegion>()); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_ClipRegion:" << region.boundingRect() << cmd.extra; +#endif + painter->setClipRegion(region, Qt::ClipOperation(cmd.extra)); + break; } + + case QPaintBufferPrivate::Cmd_DrawText: { + QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); + QList<QVariant> variants(d->variants.at(cmd.offset).value<QList<QVariant> >()); + + QFont font(variants.at(0).value<QFont>()); + QString text(variants.at(1).value<QString>()); + + painter->setFont(font); + painter->drawText(pos, text); + break; } + + case QPaintBufferPrivate::Cmd_DrawTextItem: { + QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); + QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(d->variants.at(cmd.offset))); + 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); + font.setOverline(false); + + const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); + qreal justificationWidth = 0; + if (si.justified) + justificationWidth = si.width.toReal(); + qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY()); + + if (scaleFactor != 1.0) { + QFont fnt(font); + QFakeDevice fake; + fake.setDpiX(qRound(scaleFactor*qt_defaultDpiX())); + fake.setDpiY(qRound(scaleFactor*qt_defaultDpiY())); + font = QFont(fnt, &fake); + } + + int flags = Qt::TextSingleLine | Qt::TextDontClip | Qt::TextForceLeftToRight; + QSizeF size(1, 1); + if (justificationWidth > 0) { + size.setWidth(justificationWidth); + flags |= Qt::TextJustificationForced; + flags |= Qt::AlignJustify; + } + + QFontMetrics fm(font); + QPointF pt(pos.x(), pos.y() - fm.ascent()); + qt_format_text(font, QRectF(pt, size), flags, /*opt*/0, + text, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter); + break; } + case QPaintBufferPrivate::Cmd_SystemStateChanged: { + QRegion systemClip(d->variants.at(cmd.offset).value<QRegion>()); + +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> Cmd_SystemStateChanged:" << systemClip; +#endif + + painter->paintEngine()->setSystemClip(systemClip); + painter->paintEngine()->d_ptr->systemStateChanged(); + break; } + } +} + +void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd) +{ + Q_ASSERT(painter->paintEngine()->isExtended()); + QPaintEngineEx *xengine = static_cast<QPaintEngineEx *>(painter->paintEngine()); + + switch (cmd.id) { + case QPaintBufferPrivate::Cmd_SetBrushOrigin: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_SetBrushOrigin: " << d->variants.at(cmd.offset).toPointF(); +#endif + xengine->state()->brushOrigin = d->variants.at(cmd.offset).toPointF(); + xengine->brushOriginChanged(); + break; } + + case QPaintBufferPrivate::Cmd_SetCompositionMode: { + QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_SetCompositionMode, mode: " << mode; +#endif + xengine->state()->composition_mode = mode; + xengine->compositionModeChanged(); + break; } + + case QPaintBufferPrivate::Cmd_SetOpacity: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_SetOpacity: " << d->variants.at(cmd.offset).toDouble(); +#endif + xengine->state()->opacity = d->variants.at(cmd.offset).toDouble(); + xengine->opacityChanged(); + break; } + + case QPaintBufferPrivate::Cmd_DrawVectorPath: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2; +#endif + QVectorPathCmd path(d, cmd); + xengine->draw(path()); + break; } + + case QPaintBufferPrivate::Cmd_StrokeVectorPath: { + QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_StrokeVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2; +#endif + QVectorPathCmd path(d, cmd); + xengine->stroke(path(), pen); + break; } + + case QPaintBufferPrivate::Cmd_FillVectorPath: { + QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_FillVectorPath: size: " << cmd.size +// << ", hints:" << d->ints[cmd.offset2+cmd.size] + << "pts/elms:" << cmd.offset << cmd.offset2 << brush; +#endif + QVectorPathCmd path(d, cmd); + xengine->fill(path(), brush); + break; } + + case QPaintBufferPrivate::Cmd_FillRectBrush: { + QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; +#endif + xengine->fillRect(*rect, brush); + break; } + + case QPaintBufferPrivate::Cmd_FillRectColor: { + QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra)); + QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; +#endif + xengine->fillRect(*rect, color); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d->floats.at(cmd.offset) + << d->floats.at(cmd.offset+1); +#endif + xengine->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, + (QPaintEngine::PolygonDrawMode) cmd.extra); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolygonI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size + << " mode: " << cmd.extra + << d->ints.at(cmd.offset) + << d->ints.at(cmd.offset+1); +#endif + xengine->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, + (QPaintEngine::PolygonDrawMode) cmd.extra); + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawEllipseF, offset: " << cmd.offset; +#endif + xengine->drawEllipse(*(QRectF *)(d->floats.constData() + cmd.offset)); + break; } + + case QPaintBufferPrivate::Cmd_DrawEllipseI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawEllipseI, offset: " << cmd.offset; +#endif + xengine->drawEllipse(*(QRect *)(d->ints.constData() + cmd.offset)); + break; } + + case QPaintBufferPrivate::Cmd_DrawLineF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawLines((QLineF *)(d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawLineI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawLines((QLine *)(d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawPoints((QPointF *)(d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPointsI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawPoints((QPoint *)(d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, QPaintEngine::PolylineMode); + break; } + + case QPaintBufferPrivate::Cmd_DrawPolylineI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, QPaintEngine::PolylineMode); + break; } + + case QPaintBufferPrivate::Cmd_DrawRectF: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawRectF, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawRects((QRectF *) (d->floats.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_DrawRectI: { +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_DrawRectI, offset: " << cmd.offset << " size: " << cmd.size; +#endif + xengine->drawRects((QRect *) (d->ints.constData() + cmd.offset), cmd.size); + break; } + + case QPaintBufferPrivate::Cmd_SetClipEnabled: { + bool clipEnabled = d->variants.at(cmd.offset).toBool(); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_SetClipEnabled:" << clipEnabled; +#endif + xengine->state()->clipEnabled = clipEnabled; + xengine->clipEnabledChanged(); + break; } + + case QPaintBufferPrivate::Cmd_ClipVectorPath: { + QVectorPathCmd path(d, cmd); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_ClipVectorPath:" << path().elementCount(); +#endif + xengine->clip(path(), Qt::ClipOperation(cmd.extra)); + break; } + + + case QPaintBufferPrivate::Cmd_ClipRect: { + QRect rect(QPoint(d->ints.at(cmd.offset), d->ints.at(cmd.offset + 1)), + QPoint(d->ints.at(cmd.offset + 2), d->ints.at(cmd.offset + 3))); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_ClipRect:" << rect << cmd.extra; +#endif + xengine->clip(rect, Qt::ClipOperation(cmd.extra)); + break; } + + case QPaintBufferPrivate::Cmd_ClipRegion: { + QRegion region(d->variants.at(cmd.offset).value<QRegion>()); +#ifdef QPAINTBUFFER_DEBUG_DRAW + qDebug() << " -> ExCmd_ClipRegion:" << region.boundingRect() << cmd.extra; +#endif + xengine->clip(region, Qt::ClipOperation(cmd.extra)); + break; } + + default: + QPainterReplayer::process(cmd); + break; + } +} + +QPaintBufferResource::QPaintBufferResource(FreeFunc f, QObject *parent) : QObject(parent), free(f) +{ + connect(QPaintBufferSignalProxy::instance(), SIGNAL(aboutToDestroy(const QPaintBufferPrivate *)), this, SLOT(remove(const QPaintBufferPrivate *))); +} + +QPaintBufferResource::~QPaintBufferResource() +{ + for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) + free(it.value()); +} + +void QPaintBufferResource::insert(const QPaintBufferPrivate *key, void *value) +{ + Cache::iterator it = m_cache.find(key); + if (it != m_cache.end()) { + free(it.value()); + it.value() = value; + } else { + m_cache.insert(key, value); + } +} + +void *QPaintBufferResource::value(const QPaintBufferPrivate *key) +{ + Cache::iterator it = m_cache.find(key); + if (it != m_cache.end()) + return it.value(); + return 0; +} + +void QPaintBufferResource::remove(const QPaintBufferPrivate *key) +{ + Cache::iterator it = m_cache.find(key); + if (it != m_cache.end()) { + free(it.value()); + m_cache.erase(it); + } +} + +QDataStream &operator<<(QDataStream &stream, const QPaintBufferCommand &command) +{ + quint32 id = command.id; + quint32 size = command.size; + stream << id << size; + stream << command.offset << command.offset2 << command.extra; + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QPaintBufferCommand &command) +{ + quint32 id; + quint32 size; + stream >> id >> size; + stream >> command.offset >> command.offset2 >> command.extra; + command.id = id; + command.size = size; + return stream; +} + +QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer) +{ + stream << buffer.d_ptr->ints; + stream << buffer.d_ptr->floats; + stream << buffer.d_ptr->variants; + stream << buffer.d_ptr->commands; + stream << buffer.d_ptr->boundingRect; + + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer) +{ + stream >> buffer.d_ptr->ints; + stream >> buffer.d_ptr->floats; + stream >> buffer.d_ptr->variants; + stream >> buffer.d_ptr->commands; + stream >> buffer.d_ptr->boundingRect; + + return stream; +} + diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h new file mode 100644 index 0000000..b360279 --- /dev/null +++ b/src/gui/painting/qpaintbuffer_p.h @@ -0,0 +1,439 @@ +/**************************************************************************** +** +** 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAINTBUFFER_P_H +#define QPAINTBUFFER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qpaintdevice.h> + +#include <private/qpaintengineex_p.h> +#include <private/qtextengine_p.h> +#include <QDebug> + +class QPaintBufferPrivate; +class QPaintBufferPlayback; + +class Q_GUI_EXPORT QPaintBuffer : public QPaintDevice +{ +public: + QPaintBuffer(); + QPaintBuffer(const QPaintBuffer &other); + ~QPaintBuffer(); + + bool isEmpty() const; + + void draw(QPainter *painter) const; + void setBoundingRect(const QRectF &rect); + QRectF boundingRect() const; + + virtual QPaintEngine *paintEngine() const; + virtual int metric(PaintDeviceMetric m) const; + virtual int devType() const; + + QPaintBuffer &operator=(const QPaintBuffer &other); + +private: + friend class QPainterReplayer; + friend class QOpenGLReplayer; + + friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer); + friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer); + + QPaintBufferPrivate *d_ptr; +}; + +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer); + +class QPaintBufferEngine; + +class QTextItemIntCopy +{ +public: + QTextItemIntCopy(const QTextItem &item); + ~QTextItemIntCopy(); + QTextItemInt &operator () () {return m_item;} +private: + QTextItemInt m_item; + QFont m_font; +}; + +struct QPaintBufferCommand +{ + uint id : 8; + uint size : 24; + + int offset; + int offset2; + int extra; +}; + +QDataStream &operator<<(QDataStream &stream, const QPaintBufferCommand &command); +QDataStream &operator>>(QDataStream &stream, QPaintBufferCommand &command); + +Q_DECLARE_TYPEINFO(QPaintBufferCommand, Q_MOVABLE_TYPE); + +class QPaintBufferPrivate +{ +public: + enum Command { + Cmd_Save, + Cmd_Restore, + + Cmd_SetBrush, + Cmd_SetBrushOrigin, + Cmd_SetClipEnabled, + Cmd_SetCompositionMode, + Cmd_SetOpacity, + Cmd_SetPen, + Cmd_SetRenderHints, + Cmd_SetTransform, + Cmd_SetBackgroundMode, + + Cmd_ClipPath, + Cmd_ClipRect, + Cmd_ClipRegion, + Cmd_ClipVectorPath, + + Cmd_DrawVectorPath, + Cmd_FillVectorPath, + Cmd_StrokeVectorPath, + + Cmd_DrawConvexPolygonF, + Cmd_DrawConvexPolygonI, + Cmd_DrawEllipseF, + Cmd_DrawEllipseI, + Cmd_DrawLineF, + Cmd_DrawLineI, + Cmd_DrawPath, + Cmd_DrawPointsF, + Cmd_DrawPointsI, + Cmd_DrawPolygonF, + Cmd_DrawPolygonI, + Cmd_DrawPolylineF, + Cmd_DrawPolylineI, + Cmd_DrawRectF, + Cmd_DrawRectI, + + Cmd_FillRectBrush, + Cmd_FillRectColor, + + Cmd_DrawText, + Cmd_DrawTextItem, + + Cmd_DrawImagePos, + Cmd_DrawImageRect, + Cmd_DrawPixmapPos, + Cmd_DrawPixmapRect, + Cmd_DrawTiledPixmap, + + Cmd_SystemStateChanged, + + Cmd_LastCommand + }; + + QPaintBufferPrivate(); + ~QPaintBufferPrivate(); + + int addData(const int *data, int count) { + if (count <= 0) + return 0; + int pos = ints.size(); + ints.resize(pos + count); + memcpy(ints.data() + pos, data, count * sizeof(int)); + return pos; + } + + int addData(const qreal *data, int count) { + if (count <= 0) + return 0; + int pos = floats.size(); + floats.resize(pos + count); + memcpy(floats.data() + pos, data, count * sizeof(qreal)); + return pos; + } + + int addData(const QVariant &var) { + variants << var; + return variants.size() - 1; + } + + QPaintBufferCommand *addCommand(Command command) { + QPaintBufferCommand cmd; + cmd.id = command; + cmd.size = cmd.offset = cmd.offset2 = cmd.extra = 0; + commands << cmd; + return &commands.last(); + } + + QPaintBufferCommand *addCommand(Command command, const QVariant &var) { + QPaintBufferCommand cmd; + cmd.id = command; + cmd.offset = addData(var); + cmd.size = cmd.offset2 = cmd.extra = 0; + commands << cmd; + return &commands.last(); + } + + QPaintBufferCommand *addCommand(Command command, const QVectorPath &path) { + QPaintBufferCommand cmd; + cmd.id = command; + cmd.offset = addData(path.points(), path.elementCount() * 2); + cmd.offset2 = ints.size(); + ints << path.hints(); + // The absence of path elements is indicated by setting the highest bit in 'cmd.offset2'. + if (path.elements()) + addData((const int *) path.elements(), path.elementCount()); + else + cmd.offset2 |= 0x80000000; + cmd.size = path.elementCount(); + cmd.extra = 0; + commands << cmd; + return &commands.last(); + } + + QPaintBufferCommand *addCommand(Command command , const qreal *pts, int arrayLength, int elementCount) { + QPaintBufferCommand cmd; + cmd.id = command; + cmd.offset = addData(pts, arrayLength); + cmd.size = elementCount; + cmd.offset2 = cmd.extra = 0; + commands << cmd; + return &commands.last(); + } + + QPaintBufferCommand *addCommand(Command command , const int *pts, int arrayLength, int elementCount) { + QPaintBufferCommand cmd; + cmd.id = command; + cmd.offset = addData(pts, arrayLength); + cmd.size = elementCount; + cmd.offset2 = cmd.extra = 0; + commands << cmd; + return &commands.last(); + } + + inline void updateBoundingRect(const QRectF &rect); + + QAtomicInt ref; + + QVector<int> ints; + QVector<qreal> floats; + QVector<QVariant> variants; + + QVector<QPaintBufferCommand> commands; + + QPaintBufferEngine *engine; + QRectF boundingRect; + qreal penWidthAdjustment; + uint calculateBoundingRect : 1; + + void *cache; +}; + + +struct QVectorPathCmd +{ + // The absence of path elements is indicated by setting the highest bit in 'cmd.offset2'. + QVectorPathCmd(QPaintBufferPrivate *d, const QPaintBufferCommand &cmd) + : vectorPath(d->floats.constData() + cmd.offset, + cmd.size, + cmd.offset2 & 0x80000000 + ? 0 + : (const QPainterPath::ElementType *) (d->ints.constData() + cmd.offset2 + 1), + *(d->ints.constData() + (cmd.offset2 & 0x7fffffff))) {} + + inline const QVectorPath &operator()() const { return vectorPath; } + + QVectorPath vectorPath; +}; + + +class Q_GUI_EXPORT QPainterReplayer +{ +public: + QPainterReplayer() { } + + virtual ~QPainterReplayer() { } + + void setupTransform(QPainter *painter); + void process(const QPaintBufferCommand &cmd); + void draw(const QPaintBuffer &buffer, QPainter *painter); + +protected: + QPaintBufferPrivate *d; + QTransform m_world_matrix; + + QPainter *painter; +}; + +class Q_GUI_EXPORT QPaintEngineExReplayer : public QPainterReplayer +{ +public: + QPaintEngineExReplayer() { } + + void process(const QPaintBufferCommand &cmd); +}; + +class QPaintBufferEnginePrivate; + +class QPaintBufferEngine : public QPaintEngineEx +{ + Q_DECLARE_PRIVATE(QPaintBufferEngine) +public: + QPaintBufferEngine(QPaintBufferPrivate *buffer); + + virtual bool begin(QPaintDevice *device); + virtual bool end(); + + virtual Type type() const { return QPaintEngine::PaintBuffer; } + + virtual QPainterState *createState(QPainterState *orig) const; + + virtual void draw(const QVectorPath &path); + virtual void fill(const QVectorPath &path, const QBrush &brush); + virtual void stroke(const QVectorPath &path, const QPen &pen); + + virtual void clip(const QVectorPath &path, Qt::ClipOperation op); + virtual void clip(const QRect &rect, Qt::ClipOperation op); + virtual void clip(const QRegion ®ion, Qt::ClipOperation op); + virtual void clip(const QPainterPath &path, Qt::ClipOperation op); + + virtual void clipEnabledChanged(); + virtual void penChanged(); + virtual void brushChanged(); + virtual void brushOriginChanged(); + virtual void opacityChanged(); + virtual void compositionModeChanged(); + virtual void renderHintsChanged(); + virtual void transformChanged(); + virtual void backgroundModeChanged(); + + virtual void fillRect(const QRectF &rect, const QBrush &brush); + virtual void fillRect(const QRectF &rect, const QColor &color); + + virtual void drawRects(const QRect *rects, int rectCount); + virtual void drawRects(const QRectF *rects, int rectCount); + + virtual void drawLines(const QLine *lines, int lineCount); + virtual void drawLines(const QLineF *lines, int lineCount); + + virtual void drawEllipse(const QRectF &r); + virtual void drawEllipse(const QRect &r); + + virtual void drawPath(const QPainterPath &path); + + virtual void drawPoints(const QPointF *points, int pointCount); + virtual void drawPoints(const QPoint *points, int pointCount); + + virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode); + virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); + + virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); + virtual void drawPixmap(const QPointF &pos, const QPixmap &pm); + + virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, + Qt::ImageConversionFlags flags = Qt::AutoColor); + virtual void drawImage(const QPointF &pos, const QImage &image); + + virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); + + virtual void drawTextItem(const QPointF &pos, const QTextItem &ti); + + virtual void setState(QPainterState *s); + virtual uint flags() const {return QPaintEngineEx::DoNotEmulate;} + + QPaintBufferPrivate *buffer; + + mutable int m_begin_detected : 1; + mutable int m_save_detected : 1; + mutable int m_stream_raw_text_items : 1; + mutable int m_unused : 29; + + mutable QPainterState *m_created_state; +}; + +class Q_GUI_EXPORT QPaintBufferSignalProxy : public QObject +{ + Q_OBJECT +public: + QPaintBufferSignalProxy() : QObject() {} + void emitAboutToDestroy(const QPaintBufferPrivate *buffer) { + emit aboutToDestroy(buffer); + } + static QPaintBufferSignalProxy *instance(); +Q_SIGNALS: + void aboutToDestroy(const QPaintBufferPrivate *buffer); +}; + +// One resource per paint buffer and vice versa. +class Q_GUI_EXPORT QPaintBufferResource : public QObject +{ + Q_OBJECT +public: + typedef void (*FreeFunc)(void *); + + QPaintBufferResource(FreeFunc f, QObject *parent = 0); + ~QPaintBufferResource(); + // Set resource 'value' for 'key'. + void insert(const QPaintBufferPrivate *key, void *value); + // Return resource for 'key'. + void *value(const QPaintBufferPrivate *key); +public slots: + // Remove entry 'key' from cache and delete resource. + void remove(const QPaintBufferPrivate *key); +private: + typedef QHash<const QPaintBufferPrivate *, void *> Cache; + Cache m_cache; + FreeFunc free; +}; + +#endif // QPAINTBUFFER_P_H diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h index 5cd17fe..921db4f 100644 --- a/src/gui/painting/qpaintengine.h +++ b/src/gui/painting/qpaintengine.h @@ -212,6 +212,7 @@ public: Pdf, OpenVG, OpenGL2, + PaintBuffer, User = 50, // first user type id MaxUser = 100 // last user type id @@ -248,6 +249,7 @@ private: bool autoDestruct() const { return selfDestruct; } Q_DISABLE_COPY(QPaintEngine) + friend class QPainterReplayer; friend class QFontEngineBox; friend class QFontEngineMac; friend class QFontEngineWin; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 86b2d0f..81924ff 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1391,7 +1391,7 @@ void QRasterPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) if (curClip->hasRectClip) newClip->setClipRegion(r & curClip->clipRect); else if (curClip->hasRegionClip) - newClip->setClipRegion(r & clip->clipRegion); + newClip->setClipRegion(r & curClip->clipRegion); qrasterpaintengine_dirty_clip(d, s); } @@ -3079,11 +3079,11 @@ bool QRasterPaintEnginePrivate::isUnclipped_normalized(const QRect &r) const } - // currently all painting functions clips to deviceRect internally - if (cl->clipRect == deviceRect) - return true; - if (cl->hasRectClip) { + // currently all painting functions clips to deviceRect internally + if (cl->clipRect == deviceRect) + return true; + // inline contains() for performance (we know the rects are normalized) const QRect &r1 = cl->clipRect; return (r.left() >= r1.left() && r.right() <= r1.right() @@ -3109,7 +3109,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect, // currently all painting functions that call this function clip to deviceRect internally - if (cl->clipRect == deviceRect) + if (cl->hasRectClip && cl->clipRect == deviceRect) return true; if (s->flags.antialiased) @@ -3123,7 +3123,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect, r.setHeight(r.height() + 2 * penWidth); } - if (!cl->clipRect.isEmpty()) { + if (cl->hasRectClip) { // inline contains() for performance (we know the rects are normalized) const QRect &r1 = cl->clipRect; return (r.left() >= r1.left() && r.right() <= r1.right() diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index c2703bc..4b0f8ae 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -92,40 +92,6 @@ 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()); diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index a252b5e..1fc1bd1 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -209,6 +209,14 @@ public: virtual QPixmapFilter *createPixmapFilter(int /*type*/) const { return 0; } + // These flags are needed in the implementation of paint buffers. + enum Flags + { + DoNotEmulate = 0x01, // If set, QPainter will not wrap this engine in an emulation engine. + IsEmulationEngine = 0x02 // If set, this object is a QEmulationEngine. + }; + virtual uint flags() const {return 0;} + protected: QPaintEngineEx(QPaintEngineExPrivate &data); }; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index d82e7ee..a6bea76 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -162,6 +162,9 @@ static bool qt_painter_thread_test(int devType, const char *what, bool extraCond void QPainterPrivate::checkEmulation() { Q_ASSERT(extended); + if (extended->flags() & QPaintEngineEx::DoNotEmulate) + return; + bool doEmulation = false; if (state->bgMode == Qt::OpaqueMode) doEmulation = true; @@ -1835,11 +1838,6 @@ bool QPainter::end() return true; } - if (d->states.size() > 1) { - qWarning("QPainter::end: Painter ended with %d saved states", - d->states.size()); - } - bool ended = true; if (d->engine->isActive()) { @@ -1853,6 +1851,11 @@ bool QPainter::end() } } + if (d->states.size() > 1) { + qWarning("QPainter::end: Painter ended with %d saved states", + d->states.size()); + } + if (d->engine->autoDestruct()) { delete d->engine; } @@ -7542,9 +7545,10 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, if (!painter) tf |= Qt::TextDontPrint; - uint maxUnderlines = 0; + int maxUnderlines = 0; int numUnderlines = 0; - QVarLengthArray<int, 32> underlinePositions(1); + int underlinePositionStack[32]; + int *underlinePositions = underlinePositionStack; QFontMetricsF fm(fnt); QString text = str; @@ -7553,46 +7557,54 @@ start_lengthVariant: bool hasMoreLengthVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces + QChar *chr = text.data() + offset; + QChar *end = text.data() + text.length(); bool has_tab = false; - int old_offset = offset; - for (; offset < text.length(); offset++) { - QChar chr = text.at(offset); - if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) { - text[offset] = QLatin1Char(' '); - } else if (chr == QLatin1Char('\n')) { - chr = QChar::LineSeparator; - } else if (chr == QLatin1Char('&')) { + while (chr != end) { + if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { + *chr = QLatin1Char(' '); + } else if (*chr == QLatin1Char('\n')) { + *chr = QChar::LineSeparator; + } else if (*chr == QLatin1Char('&')) { ++maxUnderlines; - } else if (chr == QLatin1Char('\t')) { - if (!expandtabs) { - text[offset] = QLatin1Char(' '); - } else if (!tabarraylen && !tabstops) { - tabstops = qRound(fm.width(QLatin1Char('x'))*8); - } + } else if (*chr == QLatin1Char('\t')) { has_tab = true; - } else if (chr == QChar(ushort(0x9c))) { + } else if (*chr == QChar(ushort(0x9c))) { // string with multiple length variants + end = chr; hasMoreLengthVariants = true; break; } + ++chr; + } + if (has_tab) { + if (!expandtabs) { + chr = text.data() + offset; + while (chr != end) { + if (*chr == QLatin1Char('\t')) + *chr = QLatin1Char(' '); + ++chr; + } + } else if (!tabarraylen && !tabstops) { + tabstops = qRound(fm.width(QLatin1Char('x'))*8); + } } - int length = offset - old_offset; - if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { - underlinePositions.resize(maxUnderlines + 1); - - QChar *cout = text.data() + old_offset; + QChar *cout = end; + if (hidemnmemonic || showmnemonic) { + if (maxUnderlines > 32) + underlinePositions = new int[maxUnderlines]; + cout = text.data() + offset; QChar *cin = cout; - int l = length; + int l = end - cout; while (l) { if (*cin == QLatin1Char('&')) { ++cin; - --length; --l; if (!l) break; if (*cin != QLatin1Char('&') && !hidemnmemonic) - underlinePositions[numUnderlines++] = cout - text.data() - old_offset; + underlinePositions[numUnderlines++] = cout - text.unicode(); } *cout = *cin; ++cout; @@ -7609,7 +7621,7 @@ start_lengthVariant: qreal height = 0; qreal width = 0; - QString finalText = text.mid(old_offset, length); + QString finalText = text.mid(offset, cout - (text.data() + offset)); QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; @@ -7628,7 +7640,7 @@ start_lengthVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.engine()->underlinePositions = underlinePositions.data(); + textLayout.engine()->underlinePositions = underlinePositions; if (finalText.isEmpty()) { height = fm.height(); @@ -7697,7 +7709,7 @@ start_lengthVariant: QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { - offset++; + offset = end - text.data() + 1; goto start_lengthVariant; } if (brect) @@ -7726,6 +7738,9 @@ start_lengthVariant: painter->restore(); } } + + if (underlinePositions != underlinePositionStack) + delete [] underlinePositions; } /*! diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index 9d472e8..a0ee749 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -220,6 +220,7 @@ private: friend class QPainterPathStrokerPrivate; friend class QMatrix; friend class QTransform; + friend class QVectorPath; friend Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &); #ifndef QT_NO_DATASTREAM @@ -237,6 +238,7 @@ public: friend class QPainterPathStrokerPrivate; friend class QMatrix; friend class QTransform; + friend class QVectorPath; friend struct QPainterPathPrivateDeleter; #ifndef QT_NO_DATASTREAM friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPainterPath &); diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index bb455cf..94be339 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -176,6 +176,42 @@ public: }; +inline const QPainterPath QVectorPath::convertToPainterPath() const +{ + QPainterPath path; + path.ensureData(); + QPainterPathData *data = path.d_func(); + data->elements.reserve(m_count); + int index = 0; + data->elements[0].x = m_points[index++]; + data->elements[0].y = m_points[index++]; + + if (m_elements) { + data->elements[0].type = m_elements[0]; + for (int i=1; i<m_count; ++i) { + QPainterPath::Element element; + element.x = m_points[index++]; + element.y = m_points[index++]; + element.type = m_elements[i]; + data->elements << element; + } + } else { + data->elements[0].type = QPainterPath::MoveToElement; + for (int i=1; i<m_count; ++i) { + QPainterPath::Element element; + element.x = m_points[index++]; + element.y = m_points[index++]; + element.type = QPainterPath::LineToElement; + data->elements << element; + } + } + + if (m_hints & OddEvenFill) + data->fillRule = Qt::OddEvenFill; + else + data->fillRule = Qt::WindingFill; + return path; +} void Q_GUI_EXPORT qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF* startPoint, QPointF *endPoint); diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index 1e909d4..199d0d6 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -127,11 +127,10 @@ public: inline bool isEmpty() const { return m_points == 0; } inline int elementCount() const { return m_count; } + inline const QPainterPath convertToPainterPath() const; static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode); - QPainterPath convertToPainterPath() const; - private: Q_DISABLE_COPY(QVectorPath) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index 0d34c77..b61675b 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -194,6 +194,7 @@ Ptr_gdk_x11_drawable_get_xdisplay QGtk::gdk_x11_drawable_get_xdisplay = 0; Ptr_gconf_client_get_default QGtk::gconf_client_get_default = 0; Ptr_gconf_client_get_string QGtk::gconf_client_get_string = 0; +Ptr_gconf_client_get_bool QGtk::gconf_client_get_bool = 0; static QString classPath(GtkWidget *widget) { @@ -336,6 +337,7 @@ static bool resolveGConf() if (!QGtk::gconf_client_get_default) { QGtk::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default"); QGtk::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string"); + QGtk::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool"); } return (QGtk::gconf_client_get_default !=0); } @@ -361,6 +363,23 @@ QString QGtk::getGConfString(const QString &value, const QString &fallback) return retVal; } +bool QGtk::getGConfBool(const QString &key, bool fallback) +{ + bool retVal = fallback; + if (resolveGConf()) { + g_type_init(); + GConfClient* client = QGtk::gconf_client_get_default(); + GError *err = 0; + bool result = QGtk::gconf_client_get_bool(client, qPrintable(key), &err); + g_object_unref(client); + if (!err) + retVal = result; + else + g_error_free (err); + } + return retVal; +} + static QString getThemeName() { QString themeName; diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/gtksymbols_p.h index 596a312..fb9d129 100644 --- a/src/gui/styles/gtksymbols_p.h +++ b/src/gui/styles/gtksymbols_p.h @@ -77,6 +77,7 @@ class GConfClient; typedef GConfClient* (*Ptr_gconf_client_get_default)(); typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **); +typedef bool (*Ptr_gconf_client_get_bool)(GConfClient*, const char*, GError **); typedef void (*Ptr_gtk_init)(int *, char ***); typedef GtkWidget* (*Ptr_gtk_window_new) (GtkWindowType); @@ -217,6 +218,7 @@ public: static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); static QString getGConfString(const QString &key, const QString &fallback = QString()); + static bool getGConfBool(const QString &key, bool fallback = 0); static Ptr_gtk_container_forall gtk_container_forall; static Ptr_gtk_init gtk_init; @@ -330,6 +332,7 @@ public: static Ptr_gconf_client_get_default gconf_client_get_default; static Ptr_gconf_client_get_string gconf_client_get_string; + static Ptr_gconf_client_get_bool gconf_client_get_bool; }; // Helper to ensure that we have polished all our gtk widgets diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index c9bdb7f..41f9ec0 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -5219,7 +5219,7 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti Q_UNUSED(sp); #else QPixmap pixmap; - const bool rtl = (option && option->direction == Qt::RightToLeft) || !option && QApplication::isRightToLeft(); + const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft()); if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { switch (sp) { @@ -5509,7 +5509,7 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons const QWidget *widget) const { QIcon icon; - const bool rtl = (option && option->direction == Qt::RightToLeft) || !option && QApplication::isRightToLeft(); + const bool rtl = (option && option->direction == Qt::RightToLeft) || (!option && QApplication::isRightToLeft()); if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty()) { switch (standardIcon) { case SP_DirHomeIcon: diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 87fa322..0ccf219 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -656,6 +656,11 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg return !scrollbars_within_bevel; } + case SH_DialogButtonBox_ButtonsHaveIcons: { + static bool buttonsHaveIcons = QGtk::getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons")); + return buttonsHaveIcons; + } + default: return QCleanlooksStyle::styleHint(hint, option, widget, returnData); } diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index 0500bff..a5d524c 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -1897,7 +1897,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, Returns an integer representing the specified style \a hint for the given \a widget described by the provided style \a option. - \c returnData is used when the querying widget needs more detailed data than + \a returnData is used when the querying widget needs more detailed data than the integer that styleHint() returns. See the QStyleHintReturn class description for details. */ diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 6978b45..f252444 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -2126,6 +2126,7 @@ void Parser::init(const QString &css, bool isFile) hasEscapeSequences = false; symbols.resize(0); + symbols.reserve(8); Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols); index = 0; errorIndex = -1; diff --git a/src/gui/text/qcssscanner.cpp b/src/gui/text/qcssscanner.cpp index 74ab7d9..06a13de 100644 --- a/src/gui/text/qcssscanner.cpp +++ b/src/gui/text/qcssscanner.cpp @@ -73,7 +73,7 @@ int QCssScanner_Generated::lex() int lastAcceptingPos = -1; int token = -1; QChar ch; - + // initial state ch = next(); if (ch.unicode() >= 9 && ch.unicode() <= 10) @@ -146,7 +146,7 @@ int QCssScanner_Generated::lex() } if (ch.unicode() == 95) goto state_24; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_24; if (ch.unicode() == 123) goto state_25; @@ -196,7 +196,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -211,7 +211,7 @@ int QCssScanner_Generated::lex() goto state_34; if (ch.unicode() == 95) goto state_33; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_33; goto out; state_5: @@ -232,7 +232,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -255,7 +255,7 @@ int QCssScanner_Generated::lex() goto state_22; if (ch.unicode() == 95) goto state_24; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_24; goto out; state_12: @@ -290,7 +290,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_17: @@ -310,7 +310,7 @@ int QCssScanner_Generated::lex() goto state_49; if (ch.unicode() == 95) goto state_50; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_50; goto out; state_22: @@ -340,7 +340,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_25: @@ -400,7 +400,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -440,7 +440,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_34: @@ -474,7 +474,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -523,7 +523,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_41: @@ -536,7 +536,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_43: @@ -560,7 +560,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_45: @@ -588,7 +588,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_47: @@ -602,7 +602,7 @@ int QCssScanner_Generated::lex() goto state_49; if (ch.unicode() == 95) goto state_50; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_50; goto out; state_49: @@ -630,7 +630,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_51: @@ -647,7 +647,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_52: @@ -668,7 +668,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_54: @@ -702,7 +702,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -725,7 +725,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -748,7 +748,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -773,7 +773,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -790,7 +790,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_62: @@ -818,7 +818,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_64: @@ -839,7 +839,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -862,7 +862,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -885,7 +885,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -910,7 +910,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -929,7 +929,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_70: @@ -944,7 +944,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_71: @@ -959,7 +959,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_72: @@ -994,7 +994,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_75: @@ -1009,7 +1009,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_76: @@ -1039,7 +1039,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_78: @@ -1060,7 +1060,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -1077,7 +1077,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_80: @@ -1098,7 +1098,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -1115,7 +1115,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_83: @@ -1130,12 +1130,12 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; found: lastAcceptingPos = pos; - + out: if (lastAcceptingPos != -1) { lexemLength = lastAcceptingPos - lexemStart; diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 323a171..9fe660a 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -307,6 +307,8 @@ private: friend class QPainterPath; friend class QTextItemInt; friend class QPicturePaintEngine; + friend class QPainterReplayer; + friend class QPaintBufferEngine; #ifndef QT_NO_DATASTREAM friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &); diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index 6196f0f..87dab42 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -823,12 +823,11 @@ void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted) Q_Q(QCompleter); QString completion; - if (!(index.flags() & Qt::ItemIsEnabled)) - return; - if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) { completion = prefix; } else { + if (!(index.flags() & Qt::ItemIsEnabled)) + return; QModelIndex si = proxy->mapToSource(index); si = si.sibling(si.row(), column); // for clicked() completion = q->pathFromIndex(si); diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 770e769..6de7c10 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -54,6 +54,7 @@ #ifdef Q_WS_WIN #include "qstandardgestures.h" +#include <private/qstandardgestures_p.h> #endif #include "qabstractscrollarea_p.h" @@ -299,8 +300,11 @@ void QAbstractScrollAreaPrivate::init() layoutChildren(); #ifdef Q_WS_WIN - panGesture = new QPanGesture(viewport); + panGesture = new QPanGesture(viewport, q); + panGesture->d_func()->implicitGesture = true; + QObject::connect(panGesture, SIGNAL(started()), q, SLOT(_q_gestureTriggered())); QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); + QObject::connect(panGesture, SIGNAL(finished()), q, SLOT(_q_gestureTriggered())); #endif // Q_WS_WIN } diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index bda9352..5f95b70 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #include "qmacdefines_mac.h" diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 3d1d3b1..3920ae9 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2601,28 +2601,28 @@ void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list, center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep); QSize left_hint = docks[QInternal::LeftDock].size(); - if (!left_hint.isValid()) + if (left_hint.isNull()) left_hint = docks[QInternal::LeftDock].sizeHint(); QSize left_min = docks[QInternal::LeftDock].minimumSize(); QSize left_max = docks[QInternal::LeftDock].maximumSize(); left_hint = left_hint.boundedTo(left_max).expandedTo(left_min); QSize right_hint = docks[QInternal::RightDock].size(); - if (!right_hint.isValid()) + if (right_hint.isNull()) right_hint = docks[QInternal::RightDock].sizeHint(); QSize right_min = docks[QInternal::RightDock].minimumSize(); QSize right_max = docks[QInternal::RightDock].maximumSize(); right_hint = right_hint.boundedTo(right_max).expandedTo(right_min); QSize top_hint = docks[QInternal::TopDock].size(); - if (!top_hint.isValid()) + if (top_hint.isNull()) top_hint = docks[QInternal::TopDock].sizeHint(); QSize top_min = docks[QInternal::TopDock].minimumSize(); QSize top_max = docks[QInternal::TopDock].maximumSize(); top_hint = top_hint.boundedTo(top_max).expandedTo(top_min); QSize bottom_hint = docks[QInternal::BottomDock].size(); - if (!bottom_hint.isValid()) + if (bottom_hint.isNull()) bottom_hint = docks[QInternal::BottomDock].sizeHint(); QSize bottom_min = docks[QInternal::BottomDock].minimumSize(); QSize bottom_max = docks[QInternal::BottomDock].maximumSize(); diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm index 2ed2e5f..a45d992 100644 --- a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #import <Cocoa/Cocoa.h> diff --git a/src/gui/widgets/qmacnativewidget_mac.mm b/src/gui/widgets/qmacnativewidget_mac.mm index 28fa1ec..224a51f 100644 --- a/src/gui/widgets/qmacnativewidget_mac.mm +++ b/src/gui/widgets/qmacnativewidget_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #import <Cocoa/Cocoa.h> diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 2ccd3e7..797c7c5 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -37,9 +37,6 @@ ** ** $QT_END_LICENSE$ ** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** ****************************************************************************/ #include <private/qmainwindowlayout_p.h> diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c79e482..085341c 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -794,10 +794,6 @@ void QPlainTextEditPrivate::init(const QString &txt) viewport->setCursor(Qt::IBeamCursor); #endif originalOffsetY = 0; -#ifdef Q_WS_WIN - panGesture = new QPanGesture(q); - QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); -#endif } void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 7ff0c03..cda1d92 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -182,7 +182,6 @@ public: #ifdef Q_WS_WIN void _q_gestureTriggered(); - QPanGesture *panGesture; #endif }; diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 64e383f..560b76c 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1897,13 +1897,8 @@ void QTabBar::keyPressEvent(QKeyEvent *event) event->ignore(); return; } - int dx = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; - for (int index = d->currentIndex + dx; d->validIndex(index); index += dx) { - if (d->tabList.at(index).enabled) { - setCurrentIndex(index); - break; - } - } + int offset = event->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; + d->setCurrentNextEnabledIndex(offset); } /*!\reimp @@ -1912,15 +1907,23 @@ void QTabBar::keyPressEvent(QKeyEvent *event) void QTabBar::wheelEvent(QWheelEvent *event) { Q_D(QTabBar); - int overIndex = d->indexAtPos(event->pos()); - if (overIndex != -1) { - int offset = event->delta() > 0 ? -1 : 1; - setCurrentIndex(currentIndex() + offset); - } + int offset = event->delta() > 0 ? -1 : 1; + d->setCurrentNextEnabledIndex(offset); QWidget::wheelEvent(event); } #endif //QT_NO_WHEELEVENT +void QTabBarPrivate::setCurrentNextEnabledIndex(int offset) +{ + Q_Q(QTabBar); + for (int index = currentIndex + offset; validIndex(index); index += offset) { + if (tabList.at(index).enabled) { + q->setCurrentIndex(index); + break; + } + } +} + /*!\reimp */ void QTabBar::changeEvent(QEvent *event) diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index 150909e..2ddd8bb 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -159,6 +159,7 @@ public: int indexAtPos(const QPoint &p) const; inline bool validIndex(int index) const { return index >= 0 && index < tabList.count(); } + void setCurrentNextEnabledIndex(int offset); QSize minimumTabSizeHint(int index); diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 547a4fb..cc79464 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -67,8 +67,6 @@ #include <qtexttable.h> #include <qvariant.h> -#include <qstandardgestures.h> - #include <qinputcontext.h> #endif diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index 71bbf83..6ae230f 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -57,10 +57,32 @@ public: sampleType = QAudioFormat::Unknown; } + QAudioFormatPrivate(const QAudioFormatPrivate &other): + QSharedData(other), + codec(other.codec), + byteOrder(other.byteOrder), + sampleType(other.sampleType), + frequency(other.frequency), + channels(other.channels), + sampleSize(other.sampleSize) + { + } + + QAudioFormatPrivate& operator=(const QAudioFormatPrivate &other) + { + codec = other.codec; + byteOrder = other.byteOrder; + sampleType = other.sampleType; + frequency = other.frequency; + channels = other.channels; + sampleSize = other.sampleSize; + + return *this; + } + QString codec; QAudioFormat::Endian byteOrder; QAudioFormat::SampleType sampleType; - int frequency; int channels; int sampleSize; diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index 53fcb49..c729103 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -10,3 +10,5 @@ include(../qbase.pri) include(audio/audio.pri) include(video/video.pri) + +symbian: TARGET.UID3 = 0x2001E627
\ No newline at end of file diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index ec9f103..3df3ab7 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -563,9 +563,12 @@ int QNativeSocketEnginePrivate::nativeAccept() if(acceptedDescriptor > 0) { // Ensure that the socket is closed on exec*() ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC); - } else { + } +#ifdef Q_OS_SYMBIAN + else { qWarning("QNativeSocketEnginePrivate::nativeAccept() - acceptedDescriptor <= 0"); } +#endif return acceptedDescriptor; } diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp index e025736..0b93320 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp @@ -86,9 +86,8 @@ bool QGLCustomShaderStage::setOnPainter(QPainter* p) return false; } - // Might as well go through the paint engine to get to the context - const QGLContext* ctx = static_cast<QGL2PaintEngineEx*>(p->paintEngine())->context(); - d->m_manager = QGLEngineShaderManager::managerForContext(ctx); + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx*>(p->paintEngine()); + d->m_manager = QGL2PaintEngineExPrivate::shaderManagerForEngine(engine); Q_ASSERT(d->m_manager); d->m_manager->setCustomStage(this); @@ -101,9 +100,8 @@ void QGLCustomShaderStage::removeFromPainter(QPainter* p) if (p->paintEngine()->type() != QPaintEngine::OpenGL2) return; - // Might as well go through the paint engine to get to the context - const QGLContext* ctx = static_cast<QGL2PaintEngineEx*>(p->paintEngine())->context(); - d->m_manager = QGLEngineShaderManager::managerForContext(ctx); + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx*>(p->paintEngine()); + d->m_manager = QGL2PaintEngineExPrivate::shaderManagerForEngine(engine); Q_ASSERT(d->m_manager); // Just set the stage to null, don't call removeCustomStage(). diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index d48a7b6..e7c11fd 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -49,47 +49,38 @@ QT_BEGIN_NAMESPACE -static void QGLEngineShaderManager_free(void *ptr) +static void qt_shared_shaders_free(void *data) { - delete reinterpret_cast<QGLEngineShaderManager *>(ptr); + delete reinterpret_cast<QGLEngineSharedShaders *>(data); } -Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shader_managers, (QGLEngineShaderManager_free)) +Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_shaders, (qt_shared_shaders_free)) -QGLEngineShaderManager *QGLEngineShaderManager::managerForContext(const QGLContext *context) +QGLEngineSharedShaders *QGLEngineSharedShaders::shadersForContext(const QGLContext *context) { - QGLEngineShaderManager *p = reinterpret_cast<QGLEngineShaderManager *>(qt_shader_managers()->value(context)); + QGLEngineSharedShaders *p = reinterpret_cast<QGLEngineSharedShaders *>(qt_shared_shaders()->value(context)); if (!p) { QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); if (oldContext != context) const_cast<QGLContext *>(context)->makeCurrent(); - p = new QGLEngineShaderManager(const_cast<QGLContext *>(context)); - qt_shader_managers()->insert(context, p); + qt_shared_shaders()->insert(context, p = new QGLEngineSharedShaders(context)); if (oldContext && oldContext != context) oldContext->makeCurrent(); } return p; } -const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = { +const char* QGLEngineSharedShaders::qglEngineShaderSourceCode[] = { 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0 }; -QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) - : ctx(context), - shaderProgNeedsChanging(true), - srcPixelType(Qt::NoBrush), - useGlobalOpacity(false), - maskType(NoMask), - useTextureCoords(false), - compositionMode(QPainter::CompositionMode_SourceOver), - customSrcStage(0), - blitShaderProg(0), - simpleShaderProg(0), - currentShaderProg(0) +QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) + : ctx(QGLContextPrivate::contextGroup(context)) + , blitShaderProg(0) + , simpleShaderProg(0) { memset(compiledShaders, 0, sizeof(compiledShaders)); @@ -174,7 +165,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) } // Compile up the simple shader: - simpleShaderProg = new QGLShaderProgram(ctx, this); + simpleShaderProg = new QGLShaderProgram(context, this); compileNamedShader(MainVertexShader, QGLShader::PartialVertexShader); compileNamedShader(PositionOnlyVertexShader, QGLShader::PartialVertexShader); compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader); @@ -191,7 +182,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) } // Compile the blit shader: - blitShaderProg = new QGLShaderProgram(ctx, this); + blitShaderProg = new QGLShaderProgram(context, this); compileNamedShader(MainWithTexCoordsVertexShader, QGLShader::PartialVertexShader); compileNamedShader(UntransformedPositionVertexShader, QGLShader::PartialVertexShader); compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader); @@ -209,6 +200,145 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) } } +void QGLEngineSharedShaders::shaderDestroyed(QObject *shader) +{ + // Remove any shader programs which has this as the srcPixel shader: + for (int i = 0; i < cachedPrograms.size(); ++i) { + if (cachedPrograms.at(i).srcPixelFragShader == shader) { + delete cachedPrograms.at(i).program; + cachedPrograms.removeAt(i--); + } + } + + emit shaderProgNeedsChanging(); +} + +QGLShader *QGLEngineSharedShaders::compileNamedShader(ShaderName name, QGLShader::ShaderType type) +{ + Q_ASSERT(name != CustomImageSrcFragmentShader); + if (compiledShaders[name]) + return compiledShaders[name]; + + QByteArray source = qglEngineShaderSourceCode[name]; + QGLShader *newShader = new QGLShader(type, ctx->context(), this); + newShader->compile(source); + +#if defined(QT_DEBUG) + // Name the shader for easier debugging + QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName")); + newShader->setObjectName(QLatin1String(m.valueToKey(name))); +#endif + + compiledShaders[name] = newShader; + return newShader; +} + +QGLShader *QGLEngineSharedShaders::compileCustomShader(QGLCustomShaderStage *stage, QGLShader::ShaderType type) +{ + QByteArray source = stage->source(); + source += qglslCustomSrcFragmentShader; + + QGLShader *newShader = customShaderCache.object(source); + if (newShader) + return newShader; + + newShader = new QGLShader(type, ctx->context(), this); + newShader->compile(source); + customShaderCache.insert(source, newShader); + + connect(newShader, SIGNAL(destroyed(QObject *)), + this, SLOT(shaderDestroyed(QObject *))); + +#if defined(QT_DEBUG) + // Name the shader for easier debugging + QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName")); + newShader->setObjectName(QLatin1String(m.valueToKey(CustomImageSrcFragmentShader))); +#endif + + return newShader; +} + +// The address returned here will only be valid until next time this function is called. +QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog) +{ + for (int i = 0; i < cachedPrograms.size(); ++i) { + if (cachedPrograms[i] == prog) + return &cachedPrograms[i]; + } + + cachedPrograms.append(prog); + QGLEngineShaderProg &cached = cachedPrograms.last(); + + // If the shader program's not found in the cache, create it now. + cached.program = new QGLShaderProgram(ctx->context(), this); + cached.program->addShader(cached.mainVertexShader); + cached.program->addShader(cached.positionVertexShader); + cached.program->addShader(cached.mainFragShader); + cached.program->addShader(cached.srcPixelFragShader); + cached.program->addShader(cached.maskFragShader); + cached.program->addShader(cached.compositionFragShader); + + // We have to bind the vertex attribute names before the program is linked: + cached.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + cached.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + + cached.program->link(); + if (!cached.program->isLinked()) { + QLatin1String none("none"); + QLatin1String br("\n"); + QString error; + error = QLatin1String("Shader program failed to link,") +#if defined(QT_DEBUG) + + br + + QLatin1String(" Shaders Used:\n") + + QLatin1String(" mainVertexShader = ") + + (cached.mainVertexShader ? + cached.mainVertexShader->objectName() : none) + br + + QLatin1String(" positionVertexShader = ") + + (cached.positionVertexShader ? + cached.positionVertexShader->objectName() : none) + br + + QLatin1String(" mainFragShader = ") + + (cached.mainFragShader ? + cached.mainFragShader->objectName() : none) + br + + QLatin1String(" srcPixelFragShader = ") + + (cached.srcPixelFragShader ? + cached.srcPixelFragShader->objectName() : none) + br + + QLatin1String(" maskFragShader = ") + + (cached.maskFragShader ? + cached.maskFragShader->objectName() : none) + br + + QLatin1String(" compositionFragShader = ") + + (cached.compositionFragShader ? + cached.compositionFragShader->objectName() : none) + br +#endif + + QLatin1String(" Error Log:\n") + + QLatin1String(" ") + cached.program->log(); + qWarning() << error; + delete cached.program; + cachedPrograms.removeLast(); + return 0; + } else { + // taking the address here is safe since + // cachePrograms isn't resized anywhere else + return &cached; + } +} + +QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) + : ctx(context), + shaderProgNeedsChanging(true), + srcPixelType(Qt::NoBrush), + useGlobalOpacity(false), + maskType(NoMask), + useTextureCoords(false), + compositionMode(QPainter::CompositionMode_SourceOver), + customSrcStage(0), + currentShaderProg(0), + customShader(0) +{ + sharedShaders = QGLEngineSharedShaders::shadersForContext(context); + connect(sharedShaders, SIGNAL(shaderProgNeedsChanging()), this, SLOT(shaderProgNeedsChangingSlot())); +} + QGLEngineShaderManager::~QGLEngineShaderManager() { //### @@ -312,24 +442,8 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) void QGLEngineShaderManager::setCustomStage(QGLCustomShaderStage* stage) { - // If the custom shader has changed, then destroy the previous compilation. - if (customSrcStage && stage && customSrcStage != stage) - removeCustomStage(customSrcStage); - customSrcStage = stage; - shaderProgNeedsChanging = true; -} - -void QGLEngineShaderManager::shaderDestroyed(QObject *shader) -{ - // Remove any shader programs which has this as the srcPixel shader: - for (int i = 0; i < cachedPrograms.size(); ++i) { - if (cachedPrograms.at(i).srcPixelFragShader == shader) { - delete cachedPrograms.at(i).program; - cachedPrograms.removeAt(i--); - } - } - + customShader = 0; // Will be compiled from 'customSrcStage' later. shaderProgNeedsChanging = true; } @@ -337,13 +451,8 @@ void QGLEngineShaderManager::removeCustomStage(QGLCustomShaderStage* stage) { Q_UNUSED(stage); // Currently we only support one at a time... - QGLShader *compiledShader = compiledShaders[CustomImageSrcFragmentShader]; - - if (!compiledShader) - return; - - compiledShaders[CustomImageSrcFragmentShader] = 0; customSrcStage = 0; + customShader = 0; shaderProgNeedsChanging = true; } @@ -355,12 +464,12 @@ QGLShaderProgram* QGLEngineShaderManager::currentProgram() QGLShaderProgram* QGLEngineShaderManager::simpleProgram() { - return simpleShaderProg; + return sharedShaders->simpleProgram(); } QGLShaderProgram* QGLEngineShaderManager::blitProgram() { - return blitShaderProg; + return sharedShaders->blitProgram(); } @@ -382,26 +491,25 @@ bool QGLEngineShaderManager::useCorrectShaderProg() requiredProgram.program = 0; // Choose vertex shader main function - QGLEngineShaderManager::ShaderName mainVertexShaderName = InvalidShaderName; + QGLEngineSharedShaders::ShaderName mainVertexShaderName = QGLEngineSharedShaders::InvalidShaderName; if (useTextureCoords) - mainVertexShaderName = MainWithTexCoordsVertexShader; + mainVertexShaderName = QGLEngineSharedShaders::MainWithTexCoordsVertexShader; else - mainVertexShaderName = MainVertexShader; - compileNamedShader(mainVertexShaderName, QGLShader::PartialVertexShader); - requiredProgram.mainVertexShader = compiledShaders[mainVertexShaderName]; + mainVertexShaderName = QGLEngineSharedShaders::MainVertexShader; + requiredProgram.mainVertexShader = sharedShaders->compileNamedShader(mainVertexShaderName, QGLShader::PartialVertexShader); // Choose vertex shader shader position function (which typically also sets // varyings) and the source pixel (srcPixel) fragment shader function: - QGLEngineShaderManager::ShaderName positionVertexShaderName = InvalidShaderName; - QGLEngineShaderManager::ShaderName srcPixelFragShaderName = InvalidShaderName; + QGLEngineSharedShaders::ShaderName positionVertexShaderName = QGLEngineSharedShaders::InvalidShaderName; + QGLEngineSharedShaders::ShaderName srcPixelFragShaderName = QGLEngineSharedShaders::InvalidShaderName; bool isAffine = brushTransform.isAffine(); if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) { if (isAffine) - positionVertexShaderName = AffinePositionWithPatternBrushVertexShader; + positionVertexShaderName = QGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader; else - positionVertexShaderName = PositionWithPatternBrushVertexShader; + positionVertexShaderName = QGLEngineSharedShaders::PositionWithPatternBrushVertexShader; - srcPixelFragShaderName = PatternBrushSrcFragmentShader; + srcPixelFragShaderName = QGLEngineSharedShaders::PatternBrushSrcFragmentShader; } else switch (srcPixelType) { default: @@ -409,204 +517,143 @@ bool QGLEngineShaderManager::useCorrectShaderProg() qCritical("QGLEngineShaderManager::useCorrectShaderProg() - I'm scared, Qt::NoBrush style is set"); break; case QGLEngineShaderManager::ImageSrc: - srcPixelFragShaderName = useCustomSrc ? CustomImageSrcFragmentShader : ImageSrcFragmentShader; - positionVertexShaderName = PositionOnlyVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::ImageSrcFragmentShader; + positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader; break; case QGLEngineShaderManager::NonPremultipliedImageSrc: - srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader; - positionVertexShaderName = PositionOnlyVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::NonPremultipliedImageSrcFragmentShader; + positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader; break; case QGLEngineShaderManager::PatternSrc: - srcPixelFragShaderName = ImageSrcWithPatternFragmentShader; - positionVertexShaderName = PositionOnlyVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::ImageSrcWithPatternFragmentShader; + positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader; break; case QGLEngineShaderManager::TextureSrcWithPattern: - srcPixelFragShaderName = TextureBrushSrcWithPatternFragmentShader; - positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader - : PositionWithTextureBrushVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::TextureBrushSrcWithPatternFragmentShader; + positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader + : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader; break; case Qt::SolidPattern: - srcPixelFragShaderName = SolidBrushSrcFragmentShader; - positionVertexShaderName = PositionOnlyVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::SolidBrushSrcFragmentShader; + positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader; break; case Qt::LinearGradientPattern: - srcPixelFragShaderName = LinearGradientBrushSrcFragmentShader; - positionVertexShaderName = isAffine ? AffinePositionWithLinearGradientBrushVertexShader - : PositionWithLinearGradientBrushVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::LinearGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithLinearGradientBrushVertexShader + : QGLEngineSharedShaders::PositionWithLinearGradientBrushVertexShader; break; case Qt::ConicalGradientPattern: - srcPixelFragShaderName = ConicalGradientBrushSrcFragmentShader; - positionVertexShaderName = isAffine ? AffinePositionWithConicalGradientBrushVertexShader - : PositionWithConicalGradientBrushVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::ConicalGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithConicalGradientBrushVertexShader + : QGLEngineSharedShaders::PositionWithConicalGradientBrushVertexShader; break; case Qt::RadialGradientPattern: - srcPixelFragShaderName = RadialGradientBrushSrcFragmentShader; - positionVertexShaderName = isAffine ? AffinePositionWithRadialGradientBrushVertexShader - : PositionWithRadialGradientBrushVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::RadialGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithRadialGradientBrushVertexShader + : QGLEngineSharedShaders::PositionWithRadialGradientBrushVertexShader; break; case Qt::TexturePattern: - srcPixelFragShaderName = TextureBrushSrcFragmentShader; - positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader - : PositionWithTextureBrushVertexShader; + srcPixelFragShaderName = QGLEngineSharedShaders::TextureBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader + : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader; break; }; - compileNamedShader(positionVertexShaderName, QGLShader::PartialVertexShader); - compileNamedShader(srcPixelFragShaderName, QGLShader::PartialFragmentShader); - requiredProgram.positionVertexShader = compiledShaders[positionVertexShaderName]; - requiredProgram.srcPixelFragShader = compiledShaders[srcPixelFragShaderName]; + requiredProgram.positionVertexShader = sharedShaders->compileNamedShader(positionVertexShaderName, QGLShader::PartialVertexShader); + if (useCustomSrc) { + if (!customShader) + customShader = sharedShaders->compileCustomShader(customSrcStage, QGLShader::PartialFragmentShader); + requiredProgram.srcPixelFragShader = customShader; + } else { + requiredProgram.srcPixelFragShader = sharedShaders->compileNamedShader(srcPixelFragShaderName, QGLShader::PartialFragmentShader); + } const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus; const bool hasMask = maskType != QGLEngineShaderManager::NoMask; // Choose fragment shader main function: - QGLEngineShaderManager::ShaderName mainFragShaderName; + QGLEngineSharedShaders::ShaderName mainFragShaderName; if (hasCompose && hasMask && useGlobalOpacity) - mainFragShaderName = MainFragmentShader_CMO; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CMO; if (hasCompose && hasMask && !useGlobalOpacity) - mainFragShaderName = MainFragmentShader_CM; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CM; if (!hasCompose && hasMask && useGlobalOpacity) - mainFragShaderName = MainFragmentShader_MO; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_MO; if (!hasCompose && hasMask && !useGlobalOpacity) - mainFragShaderName = MainFragmentShader_M; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_M; if (hasCompose && !hasMask && useGlobalOpacity) - mainFragShaderName = MainFragmentShader_CO; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CO; if (hasCompose && !hasMask && !useGlobalOpacity) - mainFragShaderName = MainFragmentShader_C; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_C; if (!hasCompose && !hasMask && useGlobalOpacity) - mainFragShaderName = MainFragmentShader_O; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_O; if (!hasCompose && !hasMask && !useGlobalOpacity) - mainFragShaderName = MainFragmentShader; + mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader; - compileNamedShader(mainFragShaderName, QGLShader::PartialFragmentShader); - requiredProgram.mainFragShader = compiledShaders[mainFragShaderName]; + requiredProgram.mainFragShader = sharedShaders->compileNamedShader(mainFragShaderName, QGLShader::PartialFragmentShader); if (hasMask) { - QGLEngineShaderManager::ShaderName maskShaderName = QGLEngineShaderManager::InvalidShaderName; + QGLEngineSharedShaders::ShaderName maskShaderName = QGLEngineSharedShaders::InvalidShaderName; if (maskType == PixelMask) - maskShaderName = MaskFragmentShader; + maskShaderName = QGLEngineSharedShaders::MaskFragmentShader; else if (maskType == SubPixelMask) - maskShaderName = RgbMaskFragmentShader; + maskShaderName = QGLEngineSharedShaders::RgbMaskFragmentShader; else if (maskType == SubPixelWithGammaMask) - maskShaderName = RgbMaskWithGammaFragmentShader; + maskShaderName = QGLEngineSharedShaders::RgbMaskWithGammaFragmentShader; else qCritical("QGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type"); - compileNamedShader(maskShaderName, QGLShader::PartialFragmentShader); - requiredProgram.maskFragShader = compiledShaders[maskShaderName]; - } - else + requiredProgram.maskFragShader = sharedShaders->compileNamedShader(maskShaderName, QGLShader::PartialFragmentShader); + } else { requiredProgram.maskFragShader = 0; + } if (hasCompose) { - QGLEngineShaderManager::ShaderName compositionShaderName = QGLEngineShaderManager::InvalidShaderName; + QGLEngineSharedShaders::ShaderName compositionShaderName = QGLEngineSharedShaders::InvalidShaderName; switch (compositionMode) { case QPainter::CompositionMode_Multiply: - compositionShaderName = MultiplyCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::MultiplyCompositionModeFragmentShader; break; case QPainter::CompositionMode_Screen: - compositionShaderName = ScreenCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::ScreenCompositionModeFragmentShader; break; case QPainter::CompositionMode_Overlay: - compositionShaderName = OverlayCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::OverlayCompositionModeFragmentShader; break; case QPainter::CompositionMode_Darken: - compositionShaderName = DarkenCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::DarkenCompositionModeFragmentShader; break; case QPainter::CompositionMode_Lighten: - compositionShaderName = LightenCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::LightenCompositionModeFragmentShader; break; case QPainter::CompositionMode_ColorDodge: - compositionShaderName = ColorDodgeCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::ColorDodgeCompositionModeFragmentShader; break; case QPainter::CompositionMode_ColorBurn: - compositionShaderName = ColorBurnCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::ColorBurnCompositionModeFragmentShader; break; case QPainter::CompositionMode_HardLight: - compositionShaderName = HardLightCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::HardLightCompositionModeFragmentShader; break; case QPainter::CompositionMode_SoftLight: - compositionShaderName = SoftLightCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::SoftLightCompositionModeFragmentShader; break; case QPainter::CompositionMode_Difference: - compositionShaderName = DifferenceCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::DifferenceCompositionModeFragmentShader; break; case QPainter::CompositionMode_Exclusion: - compositionShaderName = ExclusionCompositionModeFragmentShader; + compositionShaderName = QGLEngineSharedShaders::ExclusionCompositionModeFragmentShader; break; default: qWarning("QGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode"); } - compileNamedShader(compositionShaderName, QGLShader::PartialFragmentShader); - requiredProgram.compositionFragShader = compiledShaders[compositionShaderName]; - } - else + requiredProgram.compositionFragShader = sharedShaders->compileNamedShader(compositionShaderName, QGLShader::PartialFragmentShader); + } else { requiredProgram.compositionFragShader = 0; - - // At this point, requiredProgram is fully populated so try to find the program in the cache - bool foundProgramInCache = false; - for (int i = 0; i < cachedPrograms.size(); ++i) { - if (cachedPrograms[i] == requiredProgram) { - currentShaderProg = &cachedPrograms[i]; - foundProgramInCache = true; - break; - } } - // If the shader program's not found in the cache, create it now. - if (!foundProgramInCache) { - requiredProgram.program = new QGLShaderProgram(ctx, this); - requiredProgram.program->addShader(requiredProgram.mainVertexShader); - requiredProgram.program->addShader(requiredProgram.positionVertexShader); - requiredProgram.program->addShader(requiredProgram.mainFragShader); - requiredProgram.program->addShader(requiredProgram.srcPixelFragShader); - requiredProgram.program->addShader(requiredProgram.maskFragShader); - requiredProgram.program->addShader(requiredProgram.compositionFragShader); - - // We have to bind the vertex attribute names before the program is linked: - requiredProgram.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - if (useTextureCoords) - requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - - requiredProgram.program->link(); - if (!requiredProgram.program->isLinked()) { - QLatin1String none("none"); - QLatin1String br("\n"); - QString error; - error = QLatin1String("Shader program failed to link,") -#if defined(QT_DEBUG) - + br - + QLatin1String(" Shaders Used:\n") - + QLatin1String(" mainVertexShader = ") - + (requiredProgram.mainVertexShader ? - requiredProgram.mainVertexShader->objectName() : none) + br - + QLatin1String(" positionVertexShader = ") - + (requiredProgram.positionVertexShader ? - requiredProgram.positionVertexShader->objectName() : none) + br - + QLatin1String(" mainFragShader = ") - + (requiredProgram.mainFragShader ? - requiredProgram.mainFragShader->objectName() : none) + br - + QLatin1String(" srcPixelFragShader = ") - + (requiredProgram.srcPixelFragShader ? - requiredProgram.srcPixelFragShader->objectName() : none) + br - + QLatin1String(" maskFragShader = ") - + (requiredProgram.maskFragShader ? - requiredProgram.maskFragShader->objectName() : none) + br - + QLatin1String(" compositionFragShader = ") - + (requiredProgram.compositionFragShader ? - requiredProgram.compositionFragShader->objectName() : none) + br -#endif - + QLatin1String(" Error Log:\n") - + QLatin1String(" ") + requiredProgram.program->log(); - qWarning() << error; - delete requiredProgram.program; - } else { - cachedPrograms.append(requiredProgram); - // taking the address here is safe since - // cachePrograms isn't resized anywhere else - currentShaderProg = &cachedPrograms.last(); - } - } + // At this point, requiredProgram is fully populated so try to find the program in the cache + currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); if (currentShaderProg) { currentShaderProg->program->enable(); @@ -618,40 +665,4 @@ bool QGLEngineShaderManager::useCorrectShaderProg() return true; } -void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type) -{ - if (compiledShaders[name]) - return; - - QGLShader *newShader; - - QByteArray source; - if (name == CustomImageSrcFragmentShader) { - source = customSrcStage->source(); - source += qglslCustomSrcFragmentShader; - - newShader = customShaderCache.object(source); - if (!newShader) { - newShader = new QGLShader(type, ctx, this); - newShader->compile(source); - customShaderCache.insert(source, newShader); - - connect(newShader, SIGNAL(destroyed(QObject *)), - this, SLOT(shaderDestroyed(QObject *))); - } - } else { - source = qglEngineShaderSourceCode[name]; - newShader = new QGLShader(type, ctx, this); - newShader->compile(source); - } - -#if defined(QT_DEBUG) - // Name the shader for easier debugging - QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName")); - newShader->setObjectName(QLatin1String(m.valueToKey(name))); -#endif - - compiledShaders[name] = newShader; -} - QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 99cd82e..0cfdcf1 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -275,65 +275,10 @@ struct QGLEngineCachedShaderProg static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; -class Q_OPENGL_EXPORT QGLEngineShaderManager : public QObject +class QGLEngineSharedShaders : public QObject { Q_OBJECT public: - QGLEngineShaderManager(QGLContext* context); - ~QGLEngineShaderManager(); - - enum MaskType {NoMask, PixelMask, SubPixelMask, SubPixelWithGammaMask}; - enum PixelSrcType { - ImageSrc = Qt::TexturePattern+1, - NonPremultipliedImageSrc = Qt::TexturePattern+2, - PatternSrc = Qt::TexturePattern+3, - TextureSrcWithPattern = Qt::TexturePattern+4 - }; - - enum Uniform { - ImageTexture, - PatternColor, - GlobalOpacity, - Depth, - PmvMatrix, - MaskTexture, - FragmentColor, - LinearData, - Angle, - HalfViewportSize, - Fmp, - Fmp2MRadius2, - Inverse2Fmp2MRadius2, - InvertedTextureSize, - BrushTransform, - BrushTexture, - NumUniforms - }; - - // There are optimisations we can do, depending on the brush transform: - // 1) May not have to apply perspective-correction - // 2) Can use lower precision for matrix - void optimiseForBrushTransform(const QTransform &transform); - void setSrcPixelType(Qt::BrushStyle); - void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images - void setTextureCoordsEnabled(bool); // For images & text glyphs - void setUseGlobalOpacity(bool); - void setMaskType(MaskType); - void setCompositionMode(QPainter::CompositionMode); - void setCustomStage(QGLCustomShaderStage* stage); - void removeCustomStage(QGLCustomShaderStage* stage); - - uint getUniformLocation(Uniform id); - - void setDirty(); // someone has manually changed the current shader program - bool useCorrectShaderProg(); // returns true if the shader program needed to be changed - - QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen - QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers - QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer - - static QGLEngineShaderManager *managerForContext(const QGLContext *context); - enum ShaderName { MainVertexShader, MainWithTexCoordsVertexShader, @@ -392,6 +337,92 @@ public: TotalShaderCount, InvalidShaderName }; + QGLEngineSharedShaders(const QGLContext *context); + + QGLShader *compileNamedShader(ShaderName name, QGLShader::ShaderType type); + + QGLShaderProgram *simpleProgram() { return simpleShaderProg; } + QGLShaderProgram *blitProgram() { return blitShaderProg; } + // Compile the program if it's not already in the cache, return the item in the cache. + QGLEngineShaderProg *findProgramInCache(const QGLEngineShaderProg &prog); + // Compile the custom shader if it's not already in the cache, return the item in the cache. + QGLShader *compileCustomShader(QGLCustomShaderStage *stage, QGLShader::ShaderType type); + + static QGLEngineSharedShaders *shadersForContext(const QGLContext *context); + +signals: + void shaderProgNeedsChanging(); + +private slots: + void shaderDestroyed(QObject *shader); + +private: + QGLContextGroup *ctx; + QGLShaderProgram *blitShaderProg; + QGLShaderProgram *simpleShaderProg; + QList<QGLEngineShaderProg> cachedPrograms; + QCache<QByteArray, QGLShader> customShaderCache; + QGLShader* compiledShaders[TotalShaderCount]; + + static const char* qglEngineShaderSourceCode[TotalShaderCount]; +}; + +class Q_OPENGL_EXPORT QGLEngineShaderManager : public QObject +{ + Q_OBJECT +public: + QGLEngineShaderManager(QGLContext* context); + ~QGLEngineShaderManager(); + + enum MaskType {NoMask, PixelMask, SubPixelMask, SubPixelWithGammaMask}; + enum PixelSrcType { + ImageSrc = Qt::TexturePattern+1, + NonPremultipliedImageSrc = Qt::TexturePattern+2, + PatternSrc = Qt::TexturePattern+3, + TextureSrcWithPattern = Qt::TexturePattern+4 + }; + + enum Uniform { + ImageTexture, + PatternColor, + GlobalOpacity, + Depth, + PmvMatrix, + MaskTexture, + FragmentColor, + LinearData, + Angle, + HalfViewportSize, + Fmp, + Fmp2MRadius2, + Inverse2Fmp2MRadius2, + InvertedTextureSize, + BrushTransform, + BrushTexture, + NumUniforms + }; + + // There are optimisations we can do, depending on the brush transform: + // 1) May not have to apply perspective-correction + // 2) Can use lower precision for matrix + void optimiseForBrushTransform(const QTransform &transform); + void setSrcPixelType(Qt::BrushStyle); + void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images + void setTextureCoordsEnabled(bool); // For images & text glyphs + void setUseGlobalOpacity(bool); + void setMaskType(MaskType); + void setCompositionMode(QPainter::CompositionMode); + void setCustomStage(QGLCustomShaderStage* stage); + void removeCustomStage(QGLCustomShaderStage* stage); + + uint getUniformLocation(Uniform id); + + void setDirty(); // someone has manually changed the current shader program + bool useCorrectShaderProg(); // returns true if the shader program needed to be changed + + QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen + QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers + QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer /* // These allow the ShaderName enum to be used as a cache key @@ -408,7 +439,7 @@ public: #endif private slots: - void shaderDestroyed(QObject *shader); + void shaderProgNeedsChangingSlot() { shaderProgNeedsChanging = true; } private: QGLContext* ctx; @@ -423,19 +454,9 @@ private: QPainter::CompositionMode compositionMode; QGLCustomShaderStage* customSrcStage; - QGLShaderProgram* blitShaderProg; - QGLShaderProgram* simpleShaderProg; QGLEngineShaderProg* currentShaderProg; - - // TODO: Possibly convert to a LUT - QList<QGLEngineShaderProg> cachedPrograms; - QCache<QByteArray, QGLShader> customShaderCache; - - QGLShader* compiledShaders[TotalShaderCount]; - - void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type); - - static const char* qglEngineShaderSourceCode[TotalShaderCount]; + QGLEngineSharedShaders *sharedShaders; + QGLShader *customShader; }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 0c01263..e24539b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -316,6 +316,7 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { + delete shaderManager; } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -1330,8 +1331,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_version_2_0_functions(d->ctx); #endif - d->shaderManager = QGLEngineShaderManager::managerForContext(d->ctx); - d->shaderManager->setDirty(); + d->shaderManager = new QGLEngineShaderManager(d->ctx); glViewport(0, 0, d->width, d->height); @@ -1415,6 +1415,9 @@ bool QGL2PaintEngineEx::end() d->resetGLState(); + delete d->shaderManager; + d->shaderManager = 0; + return false; } @@ -1430,11 +1433,13 @@ void QGL2PaintEngineEx::ensureActive() p->transferMode(BrushDrawingMode); p->drawable.doneCurrent(); } + d->drawable.context()->makeCurrent(); d->drawable.makeCurrent(); ctx->d_ptr->active_engine = this; - d->needsSync = true; + } else { + d->drawable.context()->makeCurrent(); } if (d->needsSync) { @@ -1658,10 +1663,16 @@ void QGL2PaintEngineExPrivate::systemStateChanged() { Q_Q(QGL2PaintEngineEx); - if (q->paintDevice()->devType() == QInternal::Widget) + if (systemClip.isEmpty()) { use_system_clip = false; - else - use_system_clip = !systemClip.isEmpty(); + } else { + if (q->paintDevice()->devType() == QInternal::Widget && currentClipWidget) { + QWidgetPrivate *widgetPrivate = qt_widget_private(currentClipWidget->window()); + use_system_clip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter; + } else { + use_system_clip = true; + } + } glDisable(GL_DEPTH_TEST); q->state()->depthTestEnabled = false; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 552e390..cb23b11 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -196,6 +196,8 @@ public: float zValueForRenderText() const; + static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } + QGL2PaintEngineEx* q; QGLDrawable drawable; int width, height; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 8b7674e..dde4eba 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2005,9 +2005,15 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G QImage::Format target_format = img.format(); bool premul = options & QGLContext::PremultipliedAlphaBindOption; - GLenum texture_format = QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 - ? GL_BGRA : GL_RGBA; - GLuint pixel_type = GL_UNSIGNED_BYTE; + GLenum texture_format; + GLuint pixel_type; + if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) { + texture_format = GL_BGRA; + pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } else { + texture_format = GL_RGBA; + pixel_type = GL_UNSIGNED_BYTE; + } switch (target_format) { case QImage::Format_ARGB32: @@ -2034,7 +2040,6 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G if (format == GL_RGBA) format = GL_RGB; break; - default: if (img.hasAlphaChannel()) { img = img.convertToFormat(premul @@ -2062,6 +2067,30 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G } } + if (texture_format == GL_RGBA) { + // The only case where we end up with a depth different from + // 32 in the switch above is for the RGB16 case, where we set + // the format to GL_RGB + Q_ASSERT(img.depth() == 32); + const int width = img.width(); + const int height = img.height(); + + if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV + || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) { + for (int i=0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x=0; x<width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } + } else { + for (int i=0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x=0; x<width; ++x) + p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); + } + } + } + const QImage &constRef = img; // to avoid detach in bits()... glTexImage2D(target, 0, format, img.width(), img.height(), 0, texture_format, pixel_type, constRef.bits()); @@ -3533,12 +3562,7 @@ bool QGLWidget::event(QEvent *e) #elif defined(Q_WS_WIN) if (e->type() == QEvent::ParentChange) { QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this); - QList<const QGLContext *> shares = qgl_share_reg()->shares(d->glcx); - setContext(newContext); - for (int i = 0; i < shares.size(); ++i) { - if (newContext != shares.at(i)) - qgl_share_reg()->addShare(newContext, shares.at(i)); - } + setContext(newContext, d->glcx); // the overlay needs to be recreated as well delete d->olcx; @@ -4922,13 +4946,13 @@ void QGLShareRegister::removeShare(const QGLContext *context) { QGLContextResource::QGLContextResource(FreeFunc f, QObject *parent) : QObject(parent), free(f) { - connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), this, SLOT(aboutToDestroyContext(const QGLContext *))); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), this, SLOT(removeOne(const QGLContext *))); } QGLContextResource::~QGLContextResource() { while (!m_resources.empty()) - remove(m_resources.begin().key()); + removeGroup(m_resources.begin().key()); } void QGLContextResource::insert(const QGLContext *key, void *value) @@ -4976,7 +5000,7 @@ void *QGLContextResource::value(const QGLContext *key) return it.value(); } -void QGLContextResource::remove(const QGLContext *key) +void QGLContextResource::removeGroup(const QGLContext *key) { QList<const QGLContext *> shares = qgl_share_reg()->shares(key); if (shares.size() == 0) @@ -5000,7 +5024,7 @@ void QGLContextResource::remove(const QGLContext *key) } } -void QGLContextResource::aboutToDestroyContext(const QGLContext *key) +void QGLContextResource::removeOne(const QGLContext *key) { ResourceHash::iterator it = m_resources.find(key); if (it == m_resources.end()) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index a39c52c..72ec35e 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -540,10 +540,10 @@ public: // Return resource for 'key' or a shared context. void *value(const QGLContext *key); // Free resource for 'key' and all its shared contexts. - void remove(const QGLContext *key); + void removeGroup(const QGLContext *key); private slots: // Remove entry 'key' from cache and delete resource if there are no shared contexts. - void aboutToDestroyContext(const QGLContext *key); + void removeOne(const QGLContext *key); private: typedef QHash<const QGLContext *, void *> ResourceHash; ResourceHash m_resources; diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 8839f60..b1c9503 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -418,6 +418,10 @@ struct QGLExtensionFuncs #define GL_UNSIGNED_SHORT_5_6_5 33635 #endif +#ifndef GL_UNSIGNED_INT_8_8_8_8_REV +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#endif + #ifndef GL_MULTISAMPLE #define GL_MULTISAMPLE 0x809D #endif diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 427aab3..a03e627 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -109,38 +109,28 @@ public: */ /*! - Creates a QGLFramebufferObjectFormat object with properties specifying + Creates a QGLFramebufferObjectFormat object for specifying the format of an OpenGL framebuffer object. - A multisample framebuffer object is specified by setting \a samples - to a value different from zero. If the desired amount of samples per pixel is - not supported by the hardware then the maximum number of samples per pixel - will be used. Note that multisample framebuffer objects can not be bound as - textures. Also, the \c{GL_EXT_framebuffer_multisample} extension is required - to create a framebuffer with more than one sample per pixel. - - For multisample framebuffer objects a color render buffer is created, - otherwise a texture with the texture target \a target is created. - The color render buffer or texture will have the internal format - \a internalFormat, and will be bound to the \c GL_COLOR_ATTACHMENT0 - attachment in the framebuffer object. - - The \a attachment parameter describes the depth/stencil buffer - configuration. + By default the format specifies a non-multisample framebuffer object with no + attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. \sa samples(), attachment(), target(), internalFormat() */ -QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(int samples, - QGLFramebufferObject::Attachment attachment, - GLenum target, - GLenum internalFormat) +#ifndef QT_OPENGL_ES +#define DEFAULT_FORMAT GL_RGBA8 +#else +#define DEFAULT_FORMAT GL_RGBA +#endif + +QGLFramebufferObjectFormat::QGLFramebufferObjectFormat() { d = new QGLFramebufferObjectFormatPrivate; - d->samples = samples; - d->attachment = attachment; - d->target = target; - d->internal_format = internalFormat; + d->samples = 0; + d->attachment = QGLFramebufferObject::NoAttachment; + d->target = GL_TEXTURE_2D; + d->internal_format = DEFAULT_FORMAT; } /*! @@ -176,6 +166,12 @@ QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat() to \a samples. A sample count of 0 represents a regular non-multisample framebuffer object. + If the desired amount of samples per pixel is not supported by the hardware + then the maximum number of samples per pixel will be used. Note that + multisample framebuffer objects can not be bound as textures. Also, the + \c{GL_EXT_framebuffer_multisample} extension is required to create a + framebuffer with more than one sample per pixel. + \sa samples() */ void QGLFramebufferObjectFormat::setSamples(int samples) @@ -195,7 +191,7 @@ int QGLFramebufferObjectFormat::samples() const } /*! - Sets the attachments a framebuffer object should have to \a attachment. + Sets the attachment configuration of a framebuffer object to \a attachment. \sa attachment() */ @@ -259,6 +255,20 @@ GLenum QGLFramebufferObjectFormat::internalFormat() const return d->internal_format; } +#ifdef Q_MAC_COMPAT_GL_FUNCTIONS +/*! \internal */ +void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target) +{ + d->target = target; +} + +/*! \internal */ +void QGLFramebufferObjectFormat::setInternalFormat(QMacCompatGLenum internalFormat) +{ + d->internal_format = internalFormat; +} +#endif + class QGLFramebufferObjectPrivate { public: @@ -526,6 +536,12 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At the constructors that take a QGLFramebufferObject parameter, and set the QGLFramebufferObject::samples() property to a non-zero value. + For multisample framebuffer objects a color render buffer is created, + otherwise a texture with the specified texture target is created. + The color render buffer or texture will have the specified internal + format, and will be bound to the \c GL_COLOR_ATTACHMENT0 + attachment in the framebuffer object. + If you want to use a framebuffer object with multisampling enabled as a texture, you first need to copy from it to a regular framebuffer object using QGLContext::blitFramebuffer(). @@ -579,12 +595,6 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At \sa size(), texture(), attachment() */ -#ifndef QT_OPENGL_ES -#define DEFAULT_FORMAT GL_RGBA8 -#else -#define DEFAULT_FORMAT GL_RGBA -#endif - QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate) { diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index cfc824b..ad14e50 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -137,18 +137,7 @@ class QGLFramebufferObjectFormatPrivate; class Q_OPENGL_EXPORT QGLFramebufferObjectFormat { public: -#if !defined(QT_OPENGL_ES) || defined(Q_QDOC) - QGLFramebufferObjectFormat(int samples = 0, - QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment, - GLenum target = GL_TEXTURE_2D, - GLenum internalFormat = GL_RGBA8); -#else - QGLFramebufferObjectFormat(int samples = 0, - QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment, - GLenum target = GL_TEXTURE_2D, - GLenum internalFormat = GL_RGBA); -#endif - + QGLFramebufferObjectFormat(); QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other); QGLFramebufferObjectFormat &operator=(const QGLFramebufferObjectFormat &other); ~QGLFramebufferObjectFormat(); @@ -165,6 +154,11 @@ public: void setInternalFormat(GLenum internalFormat); GLenum internalFormat() const; +#ifdef Q_MAC_COMPAT_GL_FUNCTIONS + void setTextureTarget(QMacCompatGLenum target); + void setInternalFormat(QMacCompatGLenum internalFormat); +#endif + private: QGLFramebufferObjectFormatPrivate *d; }; diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 54d54e9..f082ff0 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -110,8 +110,10 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form invalid = false; qctx = new QGLContext(format); qctx->d_func()->sharing = (shareWidget != 0); - if (shareWidget != 0 && shareWidget->d_func()->glcx) + if (shareWidget != 0 && shareWidget->d_func()->glcx) { qgl_share_reg()->addShare(qctx, shareWidget->d_func()->glcx); + shareWidget->d_func()->glcx->d_func()->sharing = true; + } qctx->d_func()->paintDevice = q; qctx->d_func()->valid = true; diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index c51ccc7..56e5baa 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -324,7 +324,7 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const filter->setSource(generateBlurShader(radius(), quality() == Qt::SmoothTransformation)); QGLFramebufferObjectFormat format; - format.setInternalFormat(src.hasAlphaChannel() ? GL_RGBA : GL_RGB); + format.setInternalFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); QGLFramebufferObject *fbo = qgl_fbo_pool()->acquire(src.size(), format); if (!fbo) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 5e87e96..b6f5012 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -467,7 +467,7 @@ QPaintEngine* QGLPixmapData::paintEngine() const QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); format.setSamples(4); - format.setInternalFormat(m_hasAlpha ? GL_RGBA : GL_RGB); + format.setInternalFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB)); m_renderFbo = qgl_fbo_pool()->acquire(size(), format); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index a59501c..f974938 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -569,7 +569,7 @@ void QGLWindowSurface::updateGeometry() QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setInternalFormat(GL_RGBA); + format.setInternalFormat(GLenum(GL_RGBA)); format.setTextureTarget(target); if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) diff --git a/src/opengl/util/glsl_to_include.sh b/src/opengl/util/glsl_to_include.sh index 59d4693..083ad1e 100755 --- a/src/opengl/util/glsl_to_include.sh +++ b/src/opengl/util/glsl_to_include.sh @@ -1,4 +1,44 @@ #! /bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# # Compile a .glsl file to a file that can be included in a C++ program USAGE="Usage: $0 <file.glsl>" diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 2e56b9a..b82433d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -59,13 +59,10 @@ QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr) QDirectFBPaintDevice::~QDirectFBPaintDevice() { - unlockSurface(); if (QDirectFBScreen::instance()) { unlockSurface(); #ifdef QT_DIRECTFB_SUBSURFACE - if (subSurface) { - screen->releaseDFBSurface(subSurface); - } + releaseSubSurface(); #endif if (dfbSurface) { screen->releaseDFBSurface(dfbSurface); @@ -128,6 +125,7 @@ void QDirectFBPaintDevice::unlockSurface() if (surface) { surface->Unlock(surface); lockFlgs = static_cast<DFBSurfaceLockFlags>(0); + mem = 0; } } } @@ -206,6 +204,17 @@ QPaintEngine *QDirectFBPaintDevice::paintEngine() const return engine; } +#ifdef QT_DIRECTFB_SUBSURFACE +void QDirectFBPaintDevice::releaseSubSurface() +{ + Q_ASSERT(QDirectFBScreen::instance()); + if (subSurface) { + screen->releaseDFBSurface(subSurface); + subSurface = 0; + } +} +#endif + QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index cdd2bea..adb80e2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -86,6 +86,7 @@ protected: IDirectFBSurface *dfbSurface; #ifdef QT_DIRECTFB_SUBSURFACE + void releaseSubSurface(); IDirectFBSurface *subSurface; friend class QDirectFBPaintEnginePrivate; bool syncPending; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 5bad4de..6535d65 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -904,10 +904,10 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m case QPainter::CompositionMode_Plus: surface->SetPorterDuff(surface, DSPD_ADD); break; -#endif case QPainter::CompositionMode_Xor: surface->SetPorterDuff(surface, DSPD_XOR); break; +#endif default: compositionModeStatus = 0; break; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 599b2a9..5651506 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1192,6 +1192,33 @@ bool QDirectFBScreen::connect(const QString &displaySpec) lstep = 0; size = 0; + if (result != DFB_OK) { + DirectFBError("QDirectFBScreen::connect: " + "Unable to get screen!", result); + return false; + } + const QString qws_size = qgetenv("QWS_SIZE"); + if (!qws_size.isEmpty()) { + QRegExp rx(QLatin1String("(\\d+)x(\\d+)")); + if (!rx.exactMatch(qws_size)) { + qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size)); + } else { + int *ints[2] = { &w, &h }; + for (int i=0; i<2; ++i) { + *ints[i] = rx.cap(i + 1).toInt(); + if (*ints[i] <= 0) { + qWarning("QDirectFBScreen::connect: %s is not a positive integer", + qPrintable(rx.cap(i + 1))); + w = h = 0; + break; + } + } + } + } + + setIntOption(displayArgs, QLatin1String("width"), &w); + setIntOption(displayArgs, QLatin1String("height"), &h); + #ifndef QT_NO_DIRECTFB_LAYER result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, DLID_PRIMARY, &d_ptr->dfbLayer); @@ -1204,19 +1231,26 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #else result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen); #endif - if (result != DFB_OK) { - DirectFBError("QDirectFBScreen::connect: " - "Unable to get screen!", result); - return false; - } - result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); - if (result != DFB_OK) { - DirectFBError("QDirectFBScreen::connect: " - "Unable to get screen size!", result); + + if (w <= 0 || h <= 0) { +#ifdef QT_NO_DIRECTFB_WM + result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h); +#elif (Q_DIRECTFB_VERSION >= 0x010000) + result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); +#else + qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n" + "query the size of the primary surface in windowed mode. You have to specify\n" + "the size of the display using QWS_SIZE=[0-9]x[0-9] or\n" + "QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]"); return false; +#endif + if (result != DFB_OK) { + DirectFBError("QDirectFBScreen::connect: " + "Unable to get screen size!", result); + return false; + } } - setIntOption(displayArgs, QLatin1String("width"), &w); - setIntOption(displayArgs, QLatin1String("height"), &h); + dw = w; dh = h; @@ -1456,7 +1490,7 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) color.red(), color.green(), color.blue(), color.alpha()); const int n = region.numRects(); - if (n > 1) { + if (n == 1) { const QRect r = region.boundingRect(); d_ptr->primarySurface->FillRectangle(d_ptr->primarySurface, r.x(), r.y(), r.width(), r.height()); } else { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index e288199..9e0691d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -100,6 +100,8 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect QDirectFBWindowSurface::~QDirectFBWindowSurface() { + releaseSurface(); + // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it } bool QDirectFBWindowSurface::isValid() const @@ -117,7 +119,7 @@ void QDirectFBWindowSurface::raise() } } -void QDirectFBWindowSurface::createWindow() +void QDirectFBWindowSurface::createWindow(const QRect &rect) { IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); if (!layer) @@ -125,8 +127,12 @@ void QDirectFBWindowSurface::createWindow() DFBWindowDescription description; description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER; - description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT; + description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY; + description.posx = rect.x(); + description.posy = rect.y(); + description.width = rect.width(); + description.height = rect.height(); description.surface_caps = DSCAPS_NONE; if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) description.surface_caps |= DSCAPS_VIDEOONLY; @@ -202,9 +208,11 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) DFBResult result = DFB_OK; // If we're in a resize, the surface shouldn't be locked #ifdef QT_DIRECTFB_WM - if (!dfbWindow) - createWindow(); - setWindowGeometry(dfbWindow, oldRect, rect); + if (!dfbWindow) { + createWindow(rect); + } else { + setWindowGeometry(dfbWindow, oldRect, rect); + } #else if (mode == Primary) { if (dfbSurface && dfbSurface != primarySurface) @@ -454,6 +462,24 @@ void QDirectFBWindowSurface::updateFormat() imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; } +void QDirectFBWindowSurface::releaseSurface() +{ + if (dfbSurface) { +#ifdef QT_NO_DIRECTFB_SUBSURFACE + if (lockFlgs) + unlockSurface(); +#endif +#ifdef QT_NO_DIRECTFB_WM + Q_ASSERT(screen->primarySurface()); + if (dfbSurface != screen->primarySurface()) +#endif + + dfbSurface->Release(dfbSurface); + dfbSurface = 0; + } +} + + QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index ca76613..7ae9bfe 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -95,10 +95,11 @@ public: IDirectFBSurface *directFBSurface() const; private: void updateFormat(); + void releaseSurface(); QDirectFBWindowSurface *sibling; #ifdef QT_DIRECTFB_WM - void createWindow(); + void createWindow(const QRect &rect); IDirectFBWindow *dfbWindow; #else enum Mode { diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro index bfdec6a..14e3cfc 100644 --- a/src/plugins/graphicssystems/graphicssystems.pro +++ b/src/plugins/graphicssystems/graphicssystems.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs +SUBDIRS += trace contains(QT_CONFIG, opengl):SUBDIRS += opengl contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl):SUBDIRS += openvg diff --git a/src/plugins/graphicssystems/trace/main.cpp b/src/plugins/graphicssystems/trace/main.cpp new file mode 100644 index 0000000..908e3f4 --- /dev/null +++ b/src/plugins/graphicssystems/trace/main.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qgraphicssystemplugin_p.h> +#include "qgraphicssystem_trace_p.h" + +QT_BEGIN_NAMESPACE + +class QTraceGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + QStringList keys() const; + QGraphicsSystem *create(const QString&); +}; + +QStringList QTraceGraphicsSystemPlugin::keys() const +{ + return QStringList(QLatin1String("Trace")); +} + +QGraphicsSystem* QTraceGraphicsSystemPlugin::create(const QString& system) +{ + if (system.toLower() == QLatin1String("trace")) + return new QTraceGraphicsSystem; + + return 0; +} + +Q_EXPORT_PLUGIN2(trace, QTraceGraphicsSystemPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp new file mode 100644 index 0000000..36a8df1 --- /dev/null +++ b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgraphicssystem_trace_p.h" +#include <private/qpixmap_raster_p.h> +#include <private/qpaintbuffer_p.h> +#include <private/qwindowsurface_raster_p.h> + +#include <QFile> +#include <QPainter> +#include <QtDebug> + +QT_BEGIN_NAMESPACE + +class QTraceWindowSurface : public QRasterWindowSurface +{ +public: + QTraceWindowSurface(QWidget *widget); + ~QTraceWindowSurface(); + + QPaintDevice *paintDevice(); + void endPaint(const QRegion &rgn); + +private: + QPaintBuffer *buffer; + + QFile *outputFile; + QDataStream *out; + + int frameId; +}; + +QTraceWindowSurface::QTraceWindowSurface(QWidget *widget) + : QRasterWindowSurface(widget) + , buffer(0) + , outputFile(0) + , out(0) + , frameId(0) +{ +} + +QTraceWindowSurface::~QTraceWindowSurface() +{ + delete out; + delete outputFile; +} + +QPaintDevice *QTraceWindowSurface::paintDevice() +{ + if (!buffer) { + buffer = new QPaintBuffer; + buffer->setBoundingRect(geometry()); + } + return buffer; +} + +void QTraceWindowSurface::endPaint(const QRegion &rgn) +{ + if (!out) { + outputFile = new QFile(QString(QLatin1String("qtgraphics-%0.trace")).arg((qulonglong)window()->winId())); + if (outputFile->open(QIODevice::WriteOnly)) + out = new QDataStream(outputFile); + } + + QPainter p(QRasterWindowSurface::paintDevice()); + buffer->draw(&p); + p.end(); + + if (out) { + *out << frameId++; + *out << (qulonglong)window()->winId(); + *out << geometry(); + *out << rgn; + *out << *buffer; + } + + delete buffer; + buffer = 0; +} + +QTraceGraphicsSystem::QTraceGraphicsSystem() +{ +} + +QPixmapData *QTraceGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ + return new QRasterPixmapData(type); +} + +QWindowSurface *QTraceGraphicsSystem::createWindowSurface(QWidget *widget) const +{ + return new QTraceWindowSurface(widget); +} + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h b/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h new file mode 100644 index 0000000..5deafc9 --- /dev/null +++ b/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSYSTEM_TRACE_P_H +#define QGRAPHICSSYSTEM_TRACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qgraphicssystem_p.h> + +QT_BEGIN_NAMESPACE + +class QTraceGraphicsSystem : public QGraphicsSystem +{ +public: + QTraceGraphicsSystem(); + + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QWindowSurface *createWindowSurface(QWidget *widget) const; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/graphicssystems/trace/trace.pro b/src/plugins/graphicssystems/trace/trace.pro new file mode 100644 index 0000000..d548a6c --- /dev/null +++ b/src/plugins/graphicssystems/trace/trace.pro @@ -0,0 +1,12 @@ +TARGET = qtracegraphicssystem +include(../../qpluginbase.pri) + +QT += network + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems + +SOURCES = main.cpp qgraphicssystem_trace.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems +INSTALLS += target +INCLUDEPATH += ../../../3rdparty/harfbuzz/src diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index 10563c1..a3abc98 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -1,6 +1,6 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.5.3 + VERSION=4.6.0 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index d467250..d85ecd2 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -791,7 +791,8 @@ static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng) } // namespace QScript QScriptEnginePrivate::QScriptEnginePrivate() - : registeredScriptValues(0), freeScriptValues(0), inEval(false) + : registeredScriptValues(0), freeScriptValues(0), + registeredScriptStrings(0), inEval(false) { qMetaTypeId<QScriptValue>(); @@ -839,6 +840,7 @@ QScriptEnginePrivate::~QScriptEnginePrivate() while (!ownedAgents.isEmpty()) delete ownedAgents.takeFirst(); detachAllRegisteredScriptValues(); + detachAllRegisteredScriptStrings(); qDeleteAll(m_qobjectData); qDeleteAll(m_typeInfos); JSC::JSLock lock(false); @@ -1352,6 +1354,19 @@ void QScriptEnginePrivate::detachAllRegisteredScriptValues() registeredScriptValues = 0; } +void QScriptEnginePrivate::detachAllRegisteredScriptStrings() +{ + QScriptStringPrivate *it; + QScriptStringPrivate *next; + for (it = registeredScriptStrings; it != 0; it = next) { + it->detachFromEngine(); + next = it->next; + it->prev = 0; + it->next = 0; + } + registeredScriptStrings = 0; +} + #ifdef QT_NO_QOBJECT QScriptEngine::QScriptEngine() @@ -3236,11 +3251,10 @@ QStringList QScriptEngine::importedExtensions() const The \c Container type must provide a \c const_iterator class to enable the contents of the container to be copied into the array. - Additionally, the type of each element in the sequence should be suitable - for conversion to a QScriptValue. - See \l{QtScript Module#Conversion Between QtScript and C++ Types} - {Conversion Between QtScript and C++ Types} for more information about the - restrictions on types that can be used with QScriptValue. + Additionally, the type of each element in the sequence should be + suitable for conversion to a QScriptValue. See + \l{Conversion Between QtScript and C++ Types} for more information + about the restrictions on types that can be used with QScriptValue. \sa qScriptValueFromValue() */ @@ -3257,11 +3271,11 @@ QStringList QScriptEngine::importedExtensions() const as long as it provides a \c length property describing how many elements it contains. - Additionally, the type of each element in the sequence must be suitable - for conversion to a C++ type from a QScriptValue. - See \l{QtScript Module#Conversion Between QtScript and C++ Types} - {Conversion Between QtScript and C++ Types} for more information about the - restrictions on types that can be used with QScriptValue. + Additionally, the type of each element in the sequence must be + suitable for conversion to a C++ type from a QScriptValue. See + \l{Conversion Between QtScript and C++ Types} for more information + about the restrictions on types that can be used with + QScriptValue. \sa qscriptvalue_cast() */ @@ -3622,9 +3636,11 @@ QScriptEngineAgent *QScriptEngine::agent() const QScriptString QScriptEngine::toStringHandle(const QString &str) { Q_D(QScriptEngine); - QScriptString ss; - QScriptStringPrivate::init(ss, this, JSC::Identifier(d->currentFrame, str)); - return ss; + QScriptString result; + QScriptStringPrivate *p = new QScriptStringPrivate(d, JSC::Identifier(d->currentFrame, str), QScriptStringPrivate::HeapAllocated); + QScriptStringPrivate::init(result, p); + d->registerScriptString(p); + return result; } /*! diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index f06f717..826c2da 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -58,6 +58,7 @@ #include <QtCore/qhash.h> #include <QtCore/qset.h> #include "qscriptvalue_p.h" +#include "qscriptstring_p.h" #include "RefPtr.h" #include "Structure.h" @@ -217,6 +218,10 @@ public: inline void unregisterScriptValue(QScriptValuePrivate *value); void detachAllRegisteredScriptValues(); + inline void registerScriptString(QScriptStringPrivate *value); + inline void unregisterScriptString(QScriptStringPrivate *value); + void detachAllRegisteredScriptStrings(); + // private slots void _q_objectDestroyed(QObject *); #endif @@ -241,6 +246,7 @@ public: int agentLineNumber; QScriptValuePrivate *registeredScriptValues; QScriptValuePrivate *freeScriptValues; + QScriptStringPrivate *registeredScriptStrings; QHash<int, QScriptTypeInfo*> m_typeInfos; int processEventsInterval; QScriptValue abortResult; @@ -362,6 +368,29 @@ inline QScriptValue QScriptValuePrivate::property(const QString &name, int resol return property(JSC::Identifier(exec, name), resolveMode); } +inline void QScriptEnginePrivate::registerScriptString(QScriptStringPrivate *value) +{ + Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated); + value->prev = 0; + value->next = registeredScriptStrings; + if (registeredScriptStrings) + registeredScriptStrings->prev = value; + registeredScriptStrings = value; +} + +inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *value) +{ + Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated); + if (value->prev) + value->prev->next = value->next; + if (value->next) + value->next->prev = value->prev; + if (value == registeredScriptStrings) + registeredScriptStrings = value->next; + value->prev = 0; + value->next = 0; +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 58a7c2b..94b69b9 100644 --- a/src/script/api/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -39,10 +39,11 @@ ** ****************************************************************************/ -#include "config.h" +#include "config.h" // compile on Windows #include "qscriptstring.h" - #include "qscriptstring_p.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" QT_BEGIN_NAMESPACE @@ -70,32 +71,6 @@ QT_BEGIN_NAMESPACE */ /*! - \internal -*/ -QScriptStringPrivate::QScriptStringPrivate(QScriptEngine *e, const JSC::Identifier &id) - : engine(e), identifier(id) -{ - ref = 0; -} - -/*! - \internal -*/ -QScriptStringPrivate::~QScriptStringPrivate() -{ -} - -/*! - \internal -*/ -void QScriptStringPrivate::init(QScriptString &q, QScriptEngine *engine, - const JSC::Identifier &value) -{ - Q_ASSERT(!q.isValid()); - q.d_ptr = new QScriptStringPrivate(engine, value); -} - -/*! Constructs an invalid QScriptString. */ QScriptString::QScriptString() @@ -109,6 +84,13 @@ QScriptString::QScriptString() QScriptString::QScriptString(const QScriptString &other) : d_ptr(other.d_ptr) { + if (d_func() && (d_func()->type == QScriptStringPrivate::StackAllocated)) { + Q_ASSERT(d_func()->ref != 1); + d_ptr.detach(); + d_func()->ref = 1; + d_func()->type = QScriptStringPrivate::HeapAllocated; + d_func()->engine->registerScriptString(d_func()); + } } /*! @@ -116,6 +98,19 @@ QScriptString::QScriptString(const QScriptString &other) */ QScriptString::~QScriptString() { + Q_D(QScriptString); + if (d) { + switch (d->type) { + case QScriptStringPrivate::StackAllocated: + Q_ASSERT(d->ref == 1); + d->ref.ref(); // avoid deletion + break; + case QScriptStringPrivate::HeapAllocated: + if (d->engine && (d->ref == 1)) + d->engine->unregisterScriptString(d); + break; + } + } } /*! @@ -123,7 +118,18 @@ QScriptString::~QScriptString() */ QScriptString &QScriptString::operator=(const QScriptString &other) { + if (d_func() && d_func()->engine && (d_func()->ref == 1) && (d_func()->type == QScriptStringPrivate::HeapAllocated)) { + // current d_ptr will be deleted at the assignment below, so unregister it first + d_func()->engine->unregisterScriptString(d_func()); + } d_ptr = other.d_ptr; + if (d_func() && (d_func()->type == QScriptStringPrivate::StackAllocated)) { + Q_ASSERT(d_func()->ref != 1); + d_ptr.detach(); + d_func()->ref = 1; + d_func()->type = QScriptStringPrivate::HeapAllocated; + d_func()->engine->registerScriptString(d_func()); + } return *this; } @@ -147,7 +153,7 @@ bool QScriptString::operator==(const QScriptString &other) const if (d == other.d_func()) return true; if (!d || !other.d_func()) - return false; + return d == other.d_func(); if (d->engine != other.d_func()->engine) return false; if (!d->engine) diff --git a/src/script/api/qscriptstring.h b/src/script/api/qscriptstring.h index 30e6856..2808916 100644 --- a/src/script/api/qscriptstring.h +++ b/src/script/api/qscriptstring.h @@ -52,10 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Script) -class QScriptEngine; class QScriptStringPrivate; -struct QScriptStringPrivatePointerDeleter; - class Q_SCRIPT_EXPORT QScriptString { public: diff --git a/src/script/api/qscriptstring_p.h b/src/script/api/qscriptstring_p.h index 8f76648..05fed77 100644 --- a/src/script/api/qscriptstring_p.h +++ b/src/script/api/qscriptstring_p.h @@ -55,34 +55,58 @@ #include <QtCore/qobjectdefs.h> -#include <QtCore/qstring.h> -#include <QtCore/qpointer.h> -#include "qscriptengine.h" - #include "Identifier.h" - QT_BEGIN_NAMESPACE -class QScriptString; -class QScriptEngine; +class QScriptEnginePrivate; class QScriptStringPrivate { public: - QScriptStringPrivate(QScriptEngine *engine, const JSC::Identifier &id); - ~QScriptStringPrivate(); + enum AllocationType { + StackAllocated, + HeapAllocated + }; - static void init(QScriptString &q, QScriptEngine *engine, const JSC::Identifier &id); + inline QScriptStringPrivate(QScriptEnginePrivate *engine, const JSC::Identifier &id, + AllocationType type); + inline ~QScriptStringPrivate(); + static inline void init(QScriptString &q, QScriptStringPrivate *d); + + inline void detachFromEngine(); QBasicAtomicInt ref; -#ifndef QT_NO_QOBJECT - QPointer<QScriptEngine> engine; -#else - void *engine; -#endif + QScriptEnginePrivate *engine; JSC::Identifier identifier; + AllocationType type; + + // linked list of engine's script values + QScriptStringPrivate *prev; + QScriptStringPrivate *next; }; +inline QScriptStringPrivate::QScriptStringPrivate(QScriptEnginePrivate *e, const JSC::Identifier &id, + AllocationType tp) + : engine(e), identifier(id), type(tp), prev(0), next(0) +{ + ref = 0; +} + +inline QScriptStringPrivate::~QScriptStringPrivate() +{ +} + +inline void QScriptStringPrivate::init(QScriptString &q, QScriptStringPrivate *d) +{ + q.d_ptr = d; +} + +inline void QScriptStringPrivate::detachFromEngine() +{ + engine = 0; + identifier = JSC::Identifier(); +} + QT_END_NAMESPACE #endif diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index c8633ab..5dea491 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -97,8 +97,9 @@ bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object, QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); - QString name(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + QScriptString scriptName; + QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); + QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); @@ -116,8 +117,9 @@ void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); - QString name(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + QScriptString scriptName; + QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); + QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); @@ -135,8 +137,9 @@ bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState * // ### avoid duplication of put() QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); - QString name(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + QScriptString scriptName; + QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); + QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); @@ -155,8 +158,9 @@ bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); - QString name(propertyName.ustring()); - QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + QScriptString scriptName; + QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); + QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 0592a89..bd5d161 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -1869,6 +1869,7 @@ JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec, QScriptContext *ctx = eng_p->contextForFrame(exec); JSC::CallData callData; JSC::CallType callType = data->ctor.getCallData(callData); + Q_UNUSED(callType); Q_ASSERT_X(callType == JSC::CallTypeHost, Q_FUNC_INFO, "script constructors not supported"); if (data->ctor.isObject(&FunctionWithArgWrapper::info)) { FunctionWithArgWrapper *wrapper = static_cast<FunctionWithArgWrapper*>(JSC::asObject(data->ctor)); diff --git a/src/script/parser/qscript.g b/src/script/parser/qscript.g index bcf27da..c5902f6 100644 --- a/src/script/parser/qscript.g +++ b/src/script/parser/qscript.g @@ -37,9 +37,6 @@ -- -- $QT_END_LICENSE$ -- --- This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE --- WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. --- ---------------------------------------------------------------------------- %parser QScriptGrammar diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index fa79460..097ecbf 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1310,23 +1310,42 @@ QSqlResult *QMYSQLDriver::createResult() const QStringList QMYSQLDriver::tables(QSql::TableType type) const { QStringList tl; - if (!isOpen()) - return tl; - if (!(type & QSql::Tables)) - return tl; - - MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL); - MYSQL_ROW row; - int i = 0; - while (tableRes) { - mysql_data_seek(tableRes, i); - row = mysql_fetch_row(tableRes); - if (!row) - break; - tl.append(toUnicode(d->tc, row[0])); - i++; +#if MYSQL_VERSION_ID >= 40100 + if( mysql_get_server_version(d->mysql) < 50000) + { +#endif + if (!isOpen()) + return tl; + if (!(type & QSql::Tables)) + return tl; + + MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL); + MYSQL_ROW row; + int i = 0; + while (tableRes) { + mysql_data_seek(tableRes, i); + row = mysql_fetch_row(tableRes); + if (!row) + break; + tl.append(toUnicode(d->tc, row[0])); + i++; + } + mysql_free_result(tableRes); +#if MYSQL_VERSION_ID >= 40100 + } else { + QSqlQuery q(createResult()); + if(type & QSql::Tables) { + q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'BASE TABLE'")); + while(q.next()) + tl.append(q.value(0).toString()); + } + if(type & QSql::Views) { + q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'VIEW'")); + while(q.next()) + tl.append(q.value(0).toString()); + } } - mysql_free_result(tableRes); +#endif return tl; } diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 7dd2ea9..6437841 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -2220,6 +2220,22 @@ QStringList QOCIDriver::tables(QSql::TableType type) const else tl.append(t.value(1).toString()); } + + // list all table synonyms as well + t.exec(QLatin1String("select owner, synonym_name from all_synonyms " + "where owner != 'MDSYS' " + "and owner != 'LBACSYS' " + "and owner != 'SYS' " + "and owner != 'SYSTEM' " + "and owner != 'WKSYS'" + "and owner != 'CTXSYS'" + "and owner != 'WMSYS'")); + while (t.next()) { + if (t.value(0).toString() != d->user) + tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString()); + else + tl.append(t.value(1).toString()); + } } if (type & QSql::Views) { t.exec(QLatin1String("select owner, view_name from all_views " @@ -2269,8 +2285,8 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const // eg. a sub-query on the sys.synonyms table QString stmt(QLatin1String("select column_name, data_type, data_length, " "data_precision, data_scale, nullable, data_default%1" - "from all_tab_columns " - "where table_name=%2")); + "from all_tab_columns a " + "where a.table_name=%2")); if (d->serverVersion >= 9) stmt = stmt.arg(QLatin1String(", char_length ")); else @@ -2294,12 +2310,15 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const else owner = owner.toUpper(); - tmpStmt += QLatin1String(" and owner='") + owner + QLatin1Char('\''); + tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1Char('\''); t.setForwardOnly(true); t.exec(tmpStmt); if (!t.next()) { // try and see if the tablename is a synonym - stmt= stmt.arg(QLatin1String("(select tname from sys.synonyms where sname='") - + table + QLatin1String("' and creator=owner)")); + stmt = stmt + QLatin1String(" join all_synonyms b " + "on a.owner=b.table_owner and a.table_name=b.table_name " + "where b.owner='") + owner + + QLatin1String("' and b.synonym_name='") + table + + QLatin1Char('\''); t.setForwardOnly(true); t.exec(stmt); if (t.next()) diff --git a/src/svg/qgraphicssvgitem.h b/src/svg/qgraphicssvgitem.h index e8065da..d51095c 100644 --- a/src/svg/qgraphicssvgitem.h +++ b/src/svg/qgraphicssvgitem.h @@ -58,6 +58,7 @@ class QGraphicsSvgItemPrivate; class Q_SVG_EXPORT QGraphicsSvgItem : public QObject, public QGraphicsItem { Q_OBJECT + Q_INTERFACES(QGraphicsItem) public: QGraphicsSvgItem(QGraphicsItem *parentItem=0); diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 9683efd..b7b041f 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -76,6 +76,77 @@ static const char *qt_inherit_text = "inherit"; double qstrtod(const char *s00, char const **se, bool *ok); +// ======== duplicated from qcolor_p + +static inline int h2i(char hex) +{ + if (hex >= '0' && hex <= '9') + return hex - '0'; + if (hex >= 'a' && hex <= 'f') + return hex - 'a' + 10; + if (hex >= 'A' && hex <= 'F') + return hex - 'A' + 10; + return -1; +} + +static inline int hex2int(const char *s) +{ + return (h2i(s[0]) << 4) | h2i(s[1]); +} + +static inline int hex2int(char s) +{ + int h = h2i(s); + return (h << 4) | h; +} + +bool qt_get_hex_rgb(const char *name, QRgb *rgb) +{ + if(name[0] != '#') + return false; + name++; + int len = qstrlen(name); + int r, g, b; + if (len == 12) { + r = hex2int(name); + g = hex2int(name + 4); + b = hex2int(name + 8); + } else if (len == 9) { + r = hex2int(name); + g = hex2int(name + 3); + b = hex2int(name + 6); + } else if (len == 6) { + r = hex2int(name); + g = hex2int(name + 2); + b = hex2int(name + 4); + } else if (len == 3) { + r = hex2int(name[0]); + g = hex2int(name[1]); + b = hex2int(name[2]); + } else { + r = g = b = -1; + } + if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255) { + *rgb = 0; + return false; + } + *rgb = qRgb(r, g ,b); + return true; +} + +bool qt_get_hex_rgb(const QChar *str, int len, QRgb *rgb) +{ + if (len > 13) + return false; + char tmp[16]; + for(int i = 0; i < len; ++i) + tmp[i] = str[i].toLatin1(); + tmp[len] = 0; + return qt_get_hex_rgb(tmp, rgb); +} + +// ======== end of qcolor_p duplicate + static bool parsePathDataFast(const QStringRef &data, QPainterPath &path); static inline QString someId(const QXmlStreamAttributes &attributes) @@ -126,7 +197,6 @@ struct QSvgAttributes QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHandler *handler) { - id = someId(xmlAttributes); QStringRef style = xmlAttributes.value(QLatin1String("style")); if (!style.isEmpty()) { handler->parseCSStoXMLAttrs(style.toString(), &m_cssAttributes); @@ -267,6 +337,11 @@ QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHa fontVariant = value; break; + case 'i': + if (name == QLatin1String("id")) + id = value.toString(); + break; + case 'o': if (name == QLatin1String("opacity")) opacity = value; @@ -314,6 +389,11 @@ QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHa visibility = value; break; + case 'x': + if (name == QLatin1String("xml:id") && id.isEmpty()) + id = value.toString(); + break; + default: break; } @@ -321,9 +401,6 @@ QSvgAttributes::QSvgAttributes(const QXmlStreamAttributes &xmlAttributes, QSvgHa } -static inline QString someId(const QSvgAttributes &attributes) -{ return attributes.id; } - static const char * QSvgStyleSelector_nodeString[] = { "svg", "g", @@ -711,38 +788,69 @@ static inline QStringRef trimRef(const QStringRef &str) * returns true when successfuly set the color. false signifies * that the color should be inherited */ -static bool resolveColor(const QString &colorStr, QColor &color, QSvgHandler *handler) -{ - QString colorStrTr = colorStr.trimmed(); - if (colorStr.startsWith(QLatin1String("rgb("))) { - const QChar *s = colorStr.constData() + 4; - QVector<qreal> compo = parseNumbersList(s); - //1 means that it failed after reaching non-parsable - //character which is going to be "%" - if (compo.size() == 1) { - const QChar *s = colorStr.constData() + 4; - compo = parsePercentageList(s); - compo[0] *= (qreal)2.55; - compo[1] *= (qreal)2.55; - compo[2] *= (qreal)2.55; - } - - color = QColor(int(compo[0]), - int(compo[1]), - int(compo[2])); - return true; - } else if (colorStr == QT_INHERIT) { +static bool resolveColor(const QStringRef &colorStr, QColor &color, QSvgHandler *handler) +{ + QStringRef colorStrTr = trimRef(colorStr); + if (colorStrTr.isEmpty()) return false; - } else if (colorStr == QLatin1String("currentColor")) { - color = handler->currentColor(); - return true; + + switch(colorStrTr.at(0).unicode()) { + + case '#': + { + // #rrggbb is very very common, so let's tackle it here + // rather than falling back to QColor + QRgb rgb; + bool ok = qt_get_hex_rgb(colorStrTr.unicode(), colorStrTr.length(), &rgb); + if (ok) + color.setRgb(rgb); + return ok; + } + break; + + case 'r': + { + // starts with "rgb(" + if (colorStrTr == QLatin1String("rgb(")) { + const QChar *s = colorStrTr.constData() + 4; + QVector<qreal> compo = parseNumbersList(s); + //1 means that it failed after reaching non-parsable + //character which is going to be "%" + if (compo.size() == 1) { + const QChar *s = colorStrTr.constData() + 4; + compo = parsePercentageList(s); + compo[0] *= (qreal)2.55; + compo[1] *= (qreal)2.55; + compo[2] *= (qreal)2.55; + } + + color = QColor(int(compo[0]), + int(compo[1]), + int(compo[2])); + return true; + } + } + break; + + case 'c': + if (colorStrTr == QLatin1String("currentColor")) { + color = handler->currentColor(); + return true; + } + break; + case 'i': + if (colorStrTr == QT_INHERIT) + return false; + break; + default: + break; } - color = QColor(colorStrTr); + color = QColor(colorStrTr.toString()); return color.isValid(); } -static bool constructColor(const QString &colorStr, const QString &opacity, +static bool constructColor(const QStringRef &colorStr, const QStringRef &opacity, QColor &color, QSvgHandler *handler) { if (!resolveColor(colorStr, color, handler)) @@ -855,10 +963,8 @@ static void parseColor(QSvgNode *, const QSvgAttributes &attributes, QSvgHandler *handler) { - QString colorStr = attributes.color.toString(); - QString opacity = attributes.colorOpacity.toString(); QColor color; - if (constructColor(colorStr, opacity, color, handler)) { + if (constructColor(attributes.color, attributes.colorOpacity, color, handler)) { handler->pushColor(color); } } @@ -913,13 +1019,13 @@ static void parseBrush(QSvgNode *node, } } else if (attributes.fill != QLatin1String("none")) { QColor color; - if (resolveColor(attributes.fill.toString(), color, handler)) + if (resolveColor(attributes.fill, color, handler)) prop->setBrush(QBrush(color)); } else { prop->setBrush(QBrush(Qt::NoBrush)); } } - node->appendStyleProperty(prop, someId(attributes)); + node->appendStyleProperty(prop, attributes.id); } } @@ -1086,7 +1192,7 @@ static void parsePen(QSvgNode *node, } } else if (attributes.stroke != QLatin1String("none")) { QColor color; - if (resolveColor(attributes.stroke.toString(), color, handler)) + if (resolveColor(attributes.stroke, color, handler)) prop->setStroke(QBrush(color)); } else { prop->setStroke(QBrush(Qt::NoBrush)); @@ -1155,7 +1261,7 @@ static void parsePen(QSvgNode *node, if (!attributes.strokeOpacity.isEmpty() && attributes.strokeOpacity != QT_INHERIT) prop->setOpacity(qMin(qreal(1.0), qMax(qreal(0.0), toDouble(attributes.strokeOpacity)))); - node->appendStyleProperty(prop, someId(attributes)); + node->appendStyleProperty(prop, attributes.id); } } @@ -1229,7 +1335,7 @@ static void parseFont(QSvgNode *node, fontStyle->setTextAnchor(Qt::AlignRight); } - node->appendStyleProperty(fontStyle, someId(attributes)); + node->appendStyleProperty(fontStyle, attributes.id); } static void parseTransform(QSvgNode *node, @@ -1241,7 +1347,7 @@ static void parseTransform(QSvgNode *node, QMatrix matrix = parseTransformationMatrix(trimRef(attributes.transform)); if (!matrix.isIdentity()) { - node->appendStyleProperty(new QSvgTransformStyle(QTransform(matrix)), someId(attributes)); + node->appendStyleProperty(new QSvgTransformStyle(QTransform(matrix)), attributes.id); } } @@ -1944,7 +2050,7 @@ static void parseOpacity(QSvgNode *node, if (ok) { QSvgOpacityStyle *opacity = new QSvgOpacityStyle(qBound(qreal(0.0), op, qreal(1.0))); - node->appendStyleProperty(opacity, someId(attributes)); + node->appendStyleProperty(opacity, attributes.id); } } @@ -2016,7 +2122,7 @@ static void parseCompOp(QSvgNode *node, if (!value.isEmpty()) { QSvgCompOpStyle *compop = new QSvgCompOpStyle(svgToQtCompositionMode(value)); - node->appendStyleProperty(compop, someId(attributes)); + node->appendStyleProperty(compop, attributes.id); } } @@ -2146,8 +2252,8 @@ static bool parseAnimateColorNode(QSvgNode *parent, QSvgHandler *handler) { QString typeStr = attributes.value(QLatin1String("type")).toString(); - QString fromStr = attributes.value(QLatin1String("from")).toString(); - QString toStr = attributes.value(QLatin1String("to")).toString(); + QStringRef fromStr = attributes.value(QLatin1String("from")); + QStringRef toStr = attributes.value(QLatin1String("to")); QString valuesStr = attributes.value(QLatin1String("values")).toString(); QString beginStr = attributes.value(QLatin1String("begin")).toString(); QString durStr = attributes.value(QLatin1String("dur")).toString(); @@ -2158,8 +2264,8 @@ static bool parseAnimateColorNode(QSvgNode *parent, QList<QColor> colors; if (valuesStr.isEmpty()) { QColor startColor, endColor; - constructColor(fromStr, QString(), startColor, handler); - constructColor(toStr, QString(), endColor, handler); + resolveColor(fromStr, startColor, handler); + resolveColor(toStr, endColor, handler); colors.append(startColor); colors.append(endColor); } else { @@ -2167,7 +2273,8 @@ static bool parseAnimateColorNode(QSvgNode *parent, QStringList::const_iterator itr; for (itr = str.constBegin(); itr != str.constEnd(); ++itr) { QColor color; - constructColor(*itr, QString(), color, handler); + QString str = *itr; + resolveColor(QStringRef(&str), color, handler); colors.append(color); } } @@ -2902,11 +3009,11 @@ static QSvgStyleProperty *createSolidColorNode(QSvgNode *parent, QSvgHandler *handler) { Q_UNUSED(parent); Q_UNUSED(attributes); - QString solidColorStr = attributes.value(QLatin1String("solid-color")).toString(); - QString solidOpacityStr = attributes.value(QLatin1String("solid-opacity")).toString(); + QStringRef solidColorStr = attributes.value(QLatin1String("solid-color")); + QStringRef solidOpacityStr = attributes.value(QLatin1String("solid-opacity")); if (solidOpacityStr.isEmpty()) - solidOpacityStr = attributes.value(QLatin1String("opacity")).toString(); + solidOpacityStr = attributes.value(QLatin1String("opacity")); QColor color; if (!constructColor(solidColorStr, solidOpacityStr, color, handler)) @@ -2957,19 +3064,19 @@ static bool parseStopNode(QSvgStyleProperty *parent, QSvgGradientStyle *style = static_cast<QSvgGradientStyle*>(parent); QString offsetStr = attrs.offset.toString(); - QString colorStr = attrs.stopColor.toString(); - QString opacityStr = attrs.stopOpacity.toString(); + QStringRef colorStr = attrs.stopColor; QColor color; bool ok = true; qreal offset = convertToNumber(offsetStr, handler, &ok); if (!ok) offset = 0.0; + QString black = QString::fromLatin1("#000000"); if (colorStr.isEmpty()) { - colorStr = QLatin1String("#000000"); + colorStr = QStringRef(&black); } - constructColor(colorStr, opacityStr, color, handler); + constructColor(colorStr, attrs.stopOpacity, color, handler); QGradient *grad = style->qgradient(); diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh index 215b8cb..9673c71 100755 --- a/src/tools/moc/util/generate.sh +++ b/src/tools/moc/util/generate.sh @@ -1,4 +1,45 @@ #!/bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + qmake make cat licenseheader.txt > ../keywords.cpp diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp index d8186e5..3aca100 100644 --- a/src/xmlpatterns/data/qatomicvalue.cpp +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -172,13 +172,19 @@ Item AtomicValue::toXDM(const QVariant &value) return Item(Double::fromValue(value.toDouble())); default: { - Q_ASSERT_X(false, - Q_FUNC_INFO, - qPrintable(QString::fromLatin1( - "QVariants of type %1 are not supported in " - "Patternist, see the documentation") + if (value.userType() == qMetaTypeId<float>()) + { + return Item(Float::fromValue(value.value<float>())); + } + else { + Q_ASSERT_X(false, + Q_FUNC_INFO, + qPrintable(QString::fromLatin1( + "QVariants of type %1 are not supported in " + "Patternist, see the documentation") .arg(QLatin1String(value.typeName())))); - return AtomicValue::Ptr(); + return AtomicValue::Ptr(); + } } } } diff --git a/src/xmlpatterns/environment/createReportContext.sh b/src/xmlpatterns/environment/createReportContext.sh index dcbf9ea..7f01538 100755 --- a/src/xmlpatterns/environment/createReportContext.sh +++ b/src/xmlpatterns/environment/createReportContext.sh @@ -1,4 +1,45 @@ #!/bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + # Generate ReportContext.h by invoking createReportContext.xsl, which # in turns performs a transformation on the specs, fetched from http://www.w3.org/. diff --git a/src/xmlpatterns/parser/createParser.sh b/src/xmlpatterns/parser/createParser.sh index 51453eea..8b2849a 100755 --- a/src/xmlpatterns/parser/createParser.sh +++ b/src/xmlpatterns/parser/createParser.sh @@ -1,4 +1,44 @@ #!/bin/bash +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# files="qquerytransformparser_p.h qquerytransformparser.cpp" diff --git a/src/xmlpatterns/parser/createTokenLookup.sh b/src/xmlpatterns/parser/createTokenLookup.sh index f84ee72..8e90500 100755 --- a/src/xmlpatterns/parser/createTokenLookup.sh +++ b/src/xmlpatterns/parser/createTokenLookup.sh @@ -1,4 +1,45 @@ #!/bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + outFile="qtokenlookup.cpp" license=`cat <<EOF diff --git a/src/xmlpatterns/parser/createXSLTTokenLookup.sh b/src/xmlpatterns/parser/createXSLTTokenLookup.sh index 3a60dc4..9db886d 100755 --- a/src/xmlpatterns/parser/createXSLTTokenLookup.sh +++ b/src/xmlpatterns/parser/createXSLTTokenLookup.sh @@ -1,3 +1,44 @@ #!/bin/sh +############################################################################# +## +## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility 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 Technology Preview License Agreement accompanying +## this package. +## +## 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.1, included in the file LGPL_EXCEPTION.txt in this +## package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + xmllint --noout --schema ../qtokenautomaton/qtokenautomaton.xsd qxslttokenlookup.xml java net.sf.saxon.Transform -xsl:../qtokenautomaton/qautomaton2cpp.xsl qxslttokenlookup.xml |