summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEspen Riskedal <espenr@trolltech.com>2009-09-04 15:42:14 (GMT)
committerEspen Riskedal <espenr@trolltech.com>2009-09-04 15:42:14 (GMT)
commita2b83068ea3309c6371d028c5a1eeee42022f93e (patch)
treecd1f1229ade4aec9c329725561e90fb06c642359 /src
parentdb134371f5279d31e3d02a29951edf56be42017f (diff)
parent3959edcf4c4a531e87c9296ba401bd0f08caaed4 (diff)
downloadQt-a2b83068ea3309c6371d028c5a1eeee42022f93e.zip
Qt-a2b83068ea3309c6371d028c5a1eeee42022f93e.tar.gz
Qt-a2b83068ea3309c6371d028c5a1eeee42022f93e.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into qt46
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp23
-rw-r--r--src/corelib/arch/qatomic_windows.h49
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp10
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp18
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp6
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp164
-rw-r--r--src/gui/kernel/qsizepolicy.h12
-rw-r--r--src/gui/painting/qpaintbuffer.cpp101
-rw-r--r--src/gui/painting/qpaintbuffer_p.h8
-rw-r--r--src/gui/painting/qpainter.cpp68
-rw-r--r--src/gui/text/qtextdocument.cpp8
-rw-r--r--src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp60
12 files changed, 391 insertions, 136 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp
index f0d3b84..0eb0799 100644
--- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp
@@ -73,6 +73,19 @@ namespace JSC {
#define SYMBOL_STRING(name) #name
#endif
+#if PLATFORM(DARWIN)
+ // Mach-O platform
+#define HIDE_SYMBOL(name) ".private_extern _" #name
+#elif PLATFORM(AIX)
+ // IBM's own file format
+#define HIDE_SYMBOL(name) ".lglobl " #name
+#elif PLATFORM(LINUX) || PLATFORM(FREEBSD) || PLATFORM(OPENBSD) || PLATFORM(SOLARIS) || (PLATFORM(HPUX) && PLATFORM(IA64)) || PLATFORM(SYMBIAN) || PLATFORM(NETBSD)
+ // ELF platform
+#define HIDE_SYMBOL(name) ".hidden " #name
+#else
+#define HIDE_SYMBOL(name)
+#endif
+
#if COMPILER(GCC) && PLATFORM(X86)
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
@@ -83,6 +96,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_s
asm volatile (
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"pushl %ebp" "\n"
"movl %esp, %ebp" "\n"
@@ -103,6 +117,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
asm volatile (
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if !USE(JIT_STUB_ARGUMENT_VA_LIST)
"movl %esp, %ecx" "\n"
@@ -118,6 +133,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
asm volatile (
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"addl $0x1c, %esp" "\n"
"popl %ebx" "\n"
@@ -141,6 +157,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_s
asm volatile (
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"pushq %rbp" "\n"
"movq %rsp, %rbp" "\n"
@@ -167,6 +184,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
asm volatile (
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"movq %rsp, %rdi" "\n"
"call " SYMBOL_STRING(cti_vm_throw) "\n"
@@ -182,6 +200,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
asm volatile (
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"addq $0x48, %rsp" "\n"
"popq %rbx" "\n"
@@ -203,6 +222,7 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
".thumb" "\n"
".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
@@ -229,6 +249,7 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
".thumb" "\n"
".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
@@ -246,6 +267,7 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
".thumb" "\n"
".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
@@ -591,6 +613,7 @@ namespace JITStubs {
".text" "\n" \
".align 2" "\n" \
".globl " SYMBOL_STRING(cti_##op) "\n" \
+ HIDE_SYMBOL(cti_##op) "\n" \
".thumb" "\n" \
".thumb_func " SYMBOL_STRING(cti_##op) "\n" \
SYMBOL_STRING(cti_##op) ":" "\n" \
diff --git a/src/corelib/arch/qatomic_windows.h b/src/corelib/arch/qatomic_windows.h
index 6082d0b..07b0b25 100644
--- a/src/corelib/arch/qatomic_windows.h
+++ b/src/corelib/arch/qatomic_windows.h
@@ -102,9 +102,14 @@
#define QT_INTERLOCKED_CONCAT(prefix, suffix) \
QT_INTERLOCKED_CONCAT_I(prefix, suffix)
-// MSVC intrinsics prefix function names with an underscore
+// MSVC intrinsics prefix function names with an underscore. Also, if platform
+// SDK headers have been included, the Interlocked names may be defined as
+// macros.
+// To avoid double underscores, we paste the prefix with Interlocked first and
+// then the remainder of the function name.
#define QT_INTERLOCKED_FUNCTION(name) \
- QT_INTERLOCKED_CONCAT(QT_INTERLOCKED_PREFIX, name)
+ QT_INTERLOCKED_CONCAT( \
+ QT_INTERLOCKED_CONCAT(QT_INTERLOCKED_PREFIX, Interlocked), name)
#ifdef QT_INTERLOCKED_NO_VOLATILE
# define QT_INTERLOCKED_VOLATILE
@@ -127,16 +132,16 @@
extern "C" {
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( InterlockedIncrement )(long QT_INTERLOCKED_VOLATILE *);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( InterlockedDecrement )(long QT_INTERLOCKED_VOLATILE *);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( InterlockedCompareExchange )(long QT_INTERLOCKED_VOLATILE *, long, long);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( InterlockedExchange )(long QT_INTERLOCKED_VOLATILE *, long);
- long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( InterlockedExchangeAdd )(long QT_INTERLOCKED_VOLATILE *, long);
+ long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment )(long QT_INTERLOCKED_VOLATILE *);
+ long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement )(long QT_INTERLOCKED_VOLATILE *);
+ long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange )(long QT_INTERLOCKED_VOLATILE *, long, long);
+ long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange )(long QT_INTERLOCKED_VOLATILE *, long);
+ long QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd )(long QT_INTERLOCKED_VOLATILE *, long);
# if !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86)
- void * QT_INTERLOCKED_FUNCTION( InterlockedCompareExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *, void *);
- void * QT_INTERLOCKED_FUNCTION( InterlockedExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *);
- __int64 QT_INTERLOCKED_FUNCTION( InterlockedExchangeAdd64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
+ void * QT_INTERLOCKED_FUNCTION( CompareExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *, void *);
+ void * QT_INTERLOCKED_FUNCTION( ExchangePointer )(void * QT_INTERLOCKED_VOLATILE *, void *);
+ __int64 QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
# endif
}
@@ -156,7 +161,7 @@ extern "C" {
# pragma intrinsic (_InterlockedCompareExchange)
# pragma intrinsic (_InterlockedExchangeAdd)
-# ifndef _M_IX86
+# if !defined(Q_OS_WINCE) && !defined(_M_IX86)
# pragma intrinsic (_InterlockedCompareExchangePointer)
# pragma intrinsic (_InterlockedExchangePointer)
# pragma intrinsic (_InterlockedExchangeAdd64)
@@ -168,26 +173,26 @@ extern "C" {
// Interlocked* replacement macros
#define QT_INTERLOCKED_INCREMENT(value) \
- QT_INTERLOCKED_FUNCTION(InterlockedIncrement)( \
+ QT_INTERLOCKED_FUNCTION( Increment )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ) )
#define QT_INTERLOCKED_DECREMENT(value) \
- QT_INTERLOCKED_FUNCTION(InterlockedDecrement)( \
+ QT_INTERLOCKED_FUNCTION( Decrement )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ) )
#define QT_INTERLOCKED_COMPARE_EXCHANGE(value, newValue, expectedValue) \
- QT_INTERLOCKED_FUNCTION(InterlockedCompareExchange)( \
+ QT_INTERLOCKED_FUNCTION( CompareExchange )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ), \
newValue, \
expectedValue )
#define QT_INTERLOCKED_EXCHANGE(value, newValue) \
- QT_INTERLOCKED_FUNCTION(InterlockedExchange)( \
+ QT_INTERLOCKED_FUNCTION( Exchange )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ), \
newValue )
#define QT_INTERLOCKED_EXCHANGE_ADD(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(InterlockedExchangeAdd)( \
+ QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ), \
valueToAdd )
@@ -195,36 +200,36 @@ extern "C" {
# define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \
reinterpret_cast<void *>( \
- QT_INTERLOCKED_FUNCTION(InterlockedCompareExchange)( \
+ QT_INTERLOCKED_FUNCTION( CompareExchange )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \
(long)( newValue ), \
(long)( expectedValue ) ))
# define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \
- QT_INTERLOCKED_FUNCTION(InterlockedExchange)( \
+ QT_INTERLOCKED_FUNCTION( Exchange )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \
(quintptr)( newValue ) )
# define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(InterlockedExchangeAdd)( \
+ QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \
valueToAdd )
#else // !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86)
# define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \
- QT_INTERLOCKED_FUNCTION(InterlockedCompareExchangePointer)( \
+ QT_INTERLOCKED_FUNCTION( CompareExchangePointer )( \
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_FUNCTION( ExchangePointer )( \
reinterpret_cast<void * QT_INTERLOCKED_VOLATILE *>( QT_INTERLOCKED_REMOVE_VOLATILE( value ) ), \
newValue )
# define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(InterlockedExchangeAdd64)( \
+ QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )( \
QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \
valueToAdd )
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index b7934db..9c308a3 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -331,7 +331,7 @@ public:
WinTimerVec timerVec;
WinTimerDict timerDict;
void registerTimer(WinTimerInfo *t);
- void unregisterTimer(WinTimerInfo *t);
+ void unregisterTimer(WinTimerInfo *t, bool closingDown = false);
void sendTimerEvent(int timerId);
// socket notifiers
@@ -557,10 +557,10 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer");
}
-void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t)
+void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t, bool closingDown)
{
// mark timer as unused
- if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent)
+ if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent && !closingDown)
QAbstractEventDispatcherPrivate::releaseTimerId(t->timerId);
if (t->interval == 0) {
@@ -1019,8 +1019,8 @@ void QEventDispatcherWin32::closingDown()
unregisterSocketNotifier((*(d->sn_except.begin()))->obj);
// clean up any timers
- while (!d->timerDict.isEmpty())
- unregisterTimer((*(d->timerDict.begin()))->timerId);
+ for (int i = 0; i < d->timerVec.count(); ++i)
+ d->unregisterTimer(d->timerVec.at(i), true);
}
bool QEventDispatcherWin32::event(QEvent *e)
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index cdcb0c4..eae3e63 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -4770,7 +4770,7 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n
{
Q_ASSERT(inSetPosHelper);
- if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
return; // Not clipped by any ancestor.
// Find closest clip ancestor and transform.
@@ -4780,15 +4780,19 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n
if (transformData)
thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform);
QGraphicsItem *clipParent = parent;
- while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
+ while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
thisToParentTransform *= clipParent->d_ptr->transformToParent();
clipParent = clipParent->d_ptr->parent;
}
- // thisToParentTransform is now the same as q->itemTransform(clipParent), except
- // that the new position (which is not yet set on the item) is taken into account.
- Q_ASSERT(clipParent);
- Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ // Ensure no parents are currently being deleted. This can only
+ // happen if the item is moved by a dying ancestor.
+ QGraphicsItem *p = clipParent;
+ while (p) {
+ if (p->d_ptr->inDestructor)
+ return;
+ p = p->d_ptr->parent;
+ }
// From here everything is calculated in clip parent's coordinates.
const QRectF parentBoundingRect(clipParent->boundingRect());
@@ -6850,6 +6854,8 @@ void QGraphicsItem::removeFromIndex()
*/
void QGraphicsItem::prepareGeometryChange()
{
+ if (d_ptr->inDestructor)
+ return;
if (d_ptr->scene) {
d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
d_ptr->geometryChanged = 1;
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index afabf49..d0f3b99 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -687,11 +687,13 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
Q_D(const QGraphicsWidget);
QSizeF sh;
if (d->layout) {
- sh = d->layout->effectiveSizeHint(which, constraint);
+ QSizeF marginSize(0,0);
if (d->margins) {
- sh += QSizeF(d->margins[d->Left] + d->margins[d->Right],
+ marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
d->margins[d->Top] + d->margins[d->Bottom]);
}
+ sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
+ sh += marginSize;
} else {
switch (which) {
case Qt::MinimumSize:
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 787bbb1..bf826a9 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -393,49 +393,162 @@ void QGraphicsWidgetPrivate::windowFrameMousePressEvent(QGraphicsSceneMouseEvent
event->setAccepted(windowData->grabbedSection != Qt::NoSection);
}
+/*!
+ Used to calculate the
+ Precondition:
+ \a widget should support either hfw or wfh
+
+ If \a heightForWidth is set to false, this function will query the width for height
+ instead. \a width will then be interpreted as height, \a minh and \a maxh will be interpreted
+ as minimum width and maximum width.
+ */
+static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,
+ const QGraphicsWidget *widget,
+ bool heightForWidth = true)
+{
+ qreal minimumHeightForWidth = -1;
+ const QSizePolicy sp = widget->layout() ? widget->layout()->sizePolicy() : widget->sizePolicy();
+ const bool hasHFW = sp.hasHeightForWidth();
+ if (hasHFW == heightForWidth) {
+ minimumHeightForWidth = hasHFW
+ ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()
+ : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, width)).width(); //"width" is here height!
+ } else {
+ // widthForHeight
+ const qreal constraint = width;
+ while (maxh - minh > 0.1) {
+ qreal middle = minh + (maxh - minh)/2;
+ // ### really bad, if we are a widget with a layout it will call
+ // layout->effectiveSizeHint(Qt::MiniumumSize), which again will call
+ // sizeHint three times because of how the cache works
+ qreal hfw = hasHFW
+ ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(middle, -1)).height()
+ : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, middle)).width();
+ if (hfw > constraint) {
+ minh = middle;
+ } else if (hfw <= constraint) {
+ maxh = middle;
+ }
+ }
+ minimumHeightForWidth = maxh;
+ }
+ return minimumHeightForWidth;
+}
+
+static qreal minimumWidthForHeight(qreal height, qreal minw, qreal maxw,
+ const QGraphicsWidget *widget)
+{
+ return minimumHeightForWidth(height, minw, maxw, widget, false);
+}
+
+static QSizeF closestAcceptableSize(const QSizeF &proposed,
+ const QGraphicsWidget *widget)
+{
+ const QSizeF current = widget->size();
+
+ qreal minw = proposed.width();
+ qreal maxw = current.width();
+ qreal minh = proposed.height();
+ qreal maxh = current.height();
+
+ qreal middlew = maxw;
+ qreal middleh = maxh;
+ qreal min_hfw;
+ min_hfw = minimumHeightForWidth(maxw, minh, maxh, widget);
+
+ do {
+ if (maxw - minw < 0.1) {
+ // we still havent found anything, cut off binary search
+ minw = maxw;
+ minh = maxh;
+ }
+ middlew = minw + (maxw - minw)/2.0;
+ middleh = minh + (maxh - minh)/2.0;
+
+ min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
+
+ if (min_hfw > middleh) {
+ minw = middlew;
+ minh = middleh;
+ } else if (min_hfw <= middleh) {
+ maxw = middlew;
+ maxh = middleh;
+ }
+ } while (maxw != minw);
+
+ min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
+
+ QSizeF result;
+ if (min_hfw < maxh) {
+ result = QSizeF(middlew, min_hfw);
+ } else {
+ // Needed because of the cut-off we do above.
+ result = QSizeF(minimumWidthForHeight(maxh, proposed.width(), current.width(), widget), maxh);
+ }
+ return result;
+}
+
static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
QRectF *rect, Qt::WindowFrameSection section,
- const QSizeF &min, const QSizeF &max)
+ const QSizeF &min, const QSizeF &max,
+ const QGraphicsWidget *widget)
{
- int height;
- int width;
+ const QRectF proposedRect = *rect;
+ qreal width = qBound(min.width(), proposedRect.width(), max.width());
+ qreal height = qBound(min.height(), proposedRect.height(), max.height());
+
+ QSizePolicy sp = widget->sizePolicy();
+ if (const QGraphicsLayout *l = widget->layout()) {
+ sp = l->sizePolicy();
+ }
+ const bool hasHFW = sp.hasHeightForWidth(); // || sp.hasWidthForHeight();
+
+ const bool widthChanged = proposedRect.width() < widget->size().width();
+ const bool heightChanged = proposedRect.height() < widget->size().height();
+
+ if (hasHFW) {
+ if (widthChanged || heightChanged) {
+ const qreal minh = min.height();
+ const qreal maxh = max.height();
+ const qreal proposedHFW = minimumHeightForWidth(width, minh, maxh, widget);
+ if (proposedHFW > proposedRect.height()) {
+ QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
+ width = effectiveSize.width();
+ height = effectiveSize.height();
+ }
+ }
+ }
+
switch (section) {
case Qt::LeftSection:
- width = qRound(qBound(min.width(), rect->width(), max.width()));
- rect->setRect(startGeometry.right() - width, startGeometry.top(),
- width, startGeometry.height());
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
+ qRound(width), startGeometry.height());
break;
case Qt::TopLeftSection:
- width = qRound(qBound(min.width(), rect->width(), max.width()));
- height = qRound(qBound(min.height(), rect->height(), max.height()));
- rect->setRect(startGeometry.right() - width, startGeometry.bottom() - height,
- width, height);
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
+ qRound(width), qRound(height));
break;
case Qt::TopSection:
- height = qRound(qBound(min.height(), rect->height(), max.height()));
- rect->setRect(startGeometry.left(), startGeometry.bottom() - height,
- startGeometry.width(), height);
+ rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
+ startGeometry.width(), qRound(height));
break;
case Qt::TopRightSection:
- height = qRound(qBound(min.height(), rect->height(), max.height()));
- rect->setTop(rect->bottom() - height);
- rect->setWidth(qBound(min.width(), rect->width(), max.width()));
+ rect->setTop(rect->bottom() - qRound(height));
+ rect->setWidth(qRound(width));
break;
case Qt::RightSection:
- rect->setWidth(qBound(min.width(), rect->width(), max.width()));
+ rect->setWidth(qRound(width));
break;
case Qt::BottomRightSection:
- rect->setWidth(qBound(min.width(), rect->width(), max.width()));
- rect->setHeight(qBound(min.height(), rect->height(), max.height()));
+ rect->setWidth(qRound(width));
+ rect->setHeight(qRound(height));
break;
case Qt::BottomSection:
- rect->setHeight(qBound(min.height(), rect->height(), max.height()));
+ rect->setHeight(qRound(height));
break;
case Qt::BottomLeftSection:
- height = qRound(qBound(min.height(), rect->height(), max.height()));
- width = qRound(qBound(min.width(), rect->width(), max.width()));
- rect->setRect(startGeometry.right() - width, startGeometry.top(),
- width, height);
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
+ qRound(width), qRound(height));
break;
default:
break;
@@ -506,7 +619,8 @@ void QGraphicsWidgetPrivate::windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent
_q_boundGeometryToSizeConstraints(windowData->startGeometry, &newGeometry,
windowData->grabbedSection,
q->effectiveSizeHint(Qt::MinimumSize),
- q->effectiveSizeHint(Qt::MaximumSize));
+ q->effectiveSizeHint(Qt::MaximumSize),
+ q);
q->setGeometry(newGeometry);
}
}
diff --git a/src/gui/kernel/qsizepolicy.h b/src/gui/kernel/qsizepolicy.h
index 4261dda..eb13788 100644
--- a/src/gui/kernel/qsizepolicy.h
+++ b/src/gui/kernel/qsizepolicy.h
@@ -64,6 +64,7 @@ private:
VMask = HMask << HSize,
CTShift = 9,
CTSize = 5,
+ WFHShift = CTShift + CTSize,
CTMask = ((0x1 << CTSize) - 1) << CTShift,
UnusedShift = CTShift + CTSize,
UnusedSize = 2
@@ -199,6 +200,17 @@ private:
QSizePolicy(int i) : data(i) { }
quint32 data;
+/* use bit flags instead, keep it here for improved readability for now
+ quint32 horzPolicy : 4;
+ quint32 vertPolicy : 4;
+ quint32 hfw : 1;
+ quint32 ctype : 5;
+ quint32 wfh : 1;
+ quint32 padding : 1; // we cannot use the highest bit
+ quint32 horStretch : 8;
+ quint32 verStretch : 8;
+*/
+
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index 04ddd7d..f9cb108 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -239,7 +239,7 @@ bool QPaintBuffer::isEmpty() const
-void QPaintBuffer::draw(QPainter *painter) const
+void QPaintBuffer::draw(QPainter *painter, int frame) const
{
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBuffer::draw() --------------------------------";
@@ -270,10 +270,10 @@ void QPaintBuffer::draw(QPainter *painter) const
? (QPaintEngineEx *) painter->paintEngine() : 0;
if (xengine) {
QPaintEngineExReplayer player;
- player.draw(*this, painter);
+ player.draw(*this, painter, frame);
} else {
QPainterReplayer player;
- player.draw(*this, painter);
+ player.draw(*this, painter, frame);
}
#ifdef QPAINTBUFFER_DEBUG_DRAW
@@ -1035,17 +1035,31 @@ void QPainterReplayer::setupTransform(QPainter *_painter)
painter->setTransform(m_world_matrix);
}
-void QPainterReplayer::draw(const QPaintBuffer &buffer, QPainter *_painter)
+void QPainterReplayer::draw(const QPaintBuffer &buffer, QPainter *_painter, int frame)
{
d = buffer.d_ptr;
setupTransform(_painter);
- for (int cmdIndex=0; cmdIndex<d->commands.size(); ++cmdIndex) {
+ int frameStart = (frame == 0) ? 0 : d->frames.at(frame-1);
+ int frameEnd = (frame == d->frames.size()) ? d->commands.size() : d->frames.at(frame);
+
+ for (int cmdIndex=frameStart; cmdIndex<frameEnd; ++cmdIndex) {
const QPaintBufferCommand &cmd = d->commands.at(cmdIndex);
process(cmd);
}
}
+void QPaintBuffer::beginNewFrame()
+{
+ if (!d_ptr->commands.isEmpty())
+ d_ptr->frames << d_ptr->commands.size();
+}
+
+int QPaintBuffer::numFrames() const
+{
+ return d_ptr->frames.size() + 1;
+}
+
void QPainterReplayer::process(const QPaintBufferCommand &cmd)
{
switch (cmd.id) {
@@ -1721,24 +1735,99 @@ QDataStream &operator>>(QDataStream &stream, QPaintBufferCommand &command)
return stream;
}
+struct QPaintBufferCacheEntry
+{
+ QVariant::Type type;
+ quint64 cacheKey;
+};
+
+QDataStream &operator<<(QDataStream &stream, const QPaintBufferCacheEntry &entry)
+{
+ return stream << entry.type << entry.cacheKey;
+}
+
+QDataStream &operator>>(QDataStream &stream, QPaintBufferCacheEntry &entry)
+{
+ return stream >> entry.type >> entry.cacheKey;
+}
+
+static int qRegisterPaintBufferMetaTypes()
+{
+ qRegisterMetaType<QPaintBufferCacheEntry>();
+ qRegisterMetaTypeStreamOperators<QPaintBufferCacheEntry>("QPaintBufferCacheEntry");
+
+ return 0; // something
+}
+
+Q_DECLARE_METATYPE(QPaintBufferCacheEntry);
+Q_CONSTRUCTOR_FUNCTION(qRegisterPaintBufferMetaTypes)
+
QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer)
{
+ QHash<qint64, QPixmap> pixmaps;
+ QHash<qint64, QImage> images;
+
+ QVector<QVariant> variants = buffer.d_ptr->variants;
+ for (int i = 0; i < variants.size(); ++i) {
+ const QVariant &v = variants.at(i);
+ if (v.type() == QVariant::Image) {
+ const QImage image(v.value<QImage>());
+ images[image.cacheKey()] = image;
+
+ QPaintBufferCacheEntry entry;
+ entry.type = QVariant::Image;
+ entry.cacheKey = image.cacheKey();
+ variants[i] = QVariant::fromValue(entry);
+ } else if (v.type() == QVariant::Pixmap) {
+ const QPixmap pixmap(v.value<QPixmap>());
+ pixmaps[pixmap.cacheKey()] = pixmap;
+
+ QPaintBufferCacheEntry entry;
+ entry.type = QVariant::Pixmap;
+ entry.cacheKey = pixmap.cacheKey();
+ variants[i] = QVariant::fromValue(entry);
+ }
+ }
+
+ stream << pixmaps;
+ stream << images;
+
stream << buffer.d_ptr->ints;
stream << buffer.d_ptr->floats;
- stream << buffer.d_ptr->variants;
+ stream << variants;
stream << buffer.d_ptr->commands;
stream << buffer.d_ptr->boundingRect;
+ stream << buffer.d_ptr->frames;
return stream;
}
QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer)
{
+ QHash<qint64, QPixmap> pixmaps;
+ QHash<qint64, QImage> images;
+
+ stream >> pixmaps;
+ stream >> images;
+
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;
+ stream >> buffer.d_ptr->frames;
+
+ QVector<QVariant> &variants = buffer.d_ptr->variants;
+ for (int i = 0; i < variants.size(); ++i) {
+ const QVariant &v = variants.at(i);
+ if (v.canConvert<QPaintBufferCacheEntry>()) {
+ QPaintBufferCacheEntry entry = v.value<QPaintBufferCacheEntry>();
+ if (entry.type == QVariant::Image)
+ variants[i] = QVariant(images.value(entry.cacheKey));
+ else
+ variants[i] = QVariant(pixmaps.value(entry.cacheKey));
+ }
+ }
return stream;
}
diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h
index b360279..2cb1d7c 100644
--- a/src/gui/painting/qpaintbuffer_p.h
+++ b/src/gui/painting/qpaintbuffer_p.h
@@ -71,7 +71,10 @@ public:
bool isEmpty() const;
- void draw(QPainter *painter) const;
+ void beginNewFrame();
+ int numFrames() const;
+
+ void draw(QPainter *painter, int frame = 0) const;
void setBoundingRect(const QRectF &rect);
QRectF boundingRect() const;
@@ -270,6 +273,7 @@ public:
QVector<QVariant> variants;
QVector<QPaintBufferCommand> commands;
+ QList<int> frames;
QPaintBufferEngine *engine;
QRectF boundingRect;
@@ -306,7 +310,7 @@ public:
void setupTransform(QPainter *painter);
void process(const QPaintBufferCommand &cmd);
- void draw(const QPaintBuffer &buffer, QPainter *painter);
+ void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);
protected:
QPaintBufferPrivate *d;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index a6bea76..263e53e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -7545,10 +7545,9 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
if (!painter)
tf |= Qt::TextDontPrint;
- int maxUnderlines = 0;
+ uint maxUnderlines = 0;
int numUnderlines = 0;
- int underlinePositionStack[32];
- int *underlinePositions = underlinePositionStack;
+ QVarLengthArray<int, 32> underlinePositions(1);
QFontMetricsF fm(fnt);
QString text = str;
@@ -7557,54 +7556,46 @@ 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;
- 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('&')) {
+ 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')) {
+ text[offset] = QChar::LineSeparator;
+ } else if (chr == QLatin1Char('&')) {
++maxUnderlines;
- } else if (*chr == QLatin1Char('\t')) {
+ } else if (chr == QLatin1Char('\t')) {
+ if (!expandtabs) {
+ text[offset] = QLatin1Char(' ');
+ } else if (!tabarraylen && !tabstops) {
+ tabstops = qRound(fm.width(QLatin1Char('x'))*8);
+ }
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);
- }
}
- QChar *cout = end;
- if (hidemnmemonic || showmnemonic) {
- if (maxUnderlines > 32)
- underlinePositions = new int[maxUnderlines];
- cout = text.data() + offset;
+ int length = offset - old_offset;
+ if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
+ underlinePositions.resize(maxUnderlines + 1);
+
+ QChar *cout = text.data() + old_offset;
QChar *cin = cout;
- int l = end - cout;
+ int l = length;
while (l) {
if (*cin == QLatin1Char('&')) {
++cin;
+ --length;
--l;
if (!l)
break;
if (*cin != QLatin1Char('&') && !hidemnmemonic)
- underlinePositions[numUnderlines++] = cout - text.unicode();
+ underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
}
*cout = *cin;
++cout;
@@ -7621,7 +7612,7 @@ start_lengthVariant:
qreal height = 0;
qreal width = 0;
- QString finalText = text.mid(offset, cout - (text.data() + offset));
+ QString finalText = text.mid(old_offset, length);
QStackTextEngine engine(finalText, fnt);
if (option) {
engine.option = *option;
@@ -7640,7 +7631,7 @@ start_lengthVariant:
engine.forceJustification = true;
QTextLayout textLayout(&engine);
textLayout.setCacheEnabled(true);
- textLayout.engine()->underlinePositions = underlinePositions;
+ textLayout.engine()->underlinePositions = underlinePositions.data();
if (finalText.isEmpty()) {
height = fm.height();
@@ -7709,7 +7700,7 @@ start_lengthVariant:
QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
- offset = end - text.data() + 1;
+ offset++;
goto start_lengthVariant;
}
if (brect)
@@ -7738,9 +7729,6 @@ start_lengthVariant:
painter->restore();
}
}
-
- if (underlinePositions != underlinePositionStack)
- delete [] underlinePositions;
}
/*!
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 1bdaceb..e565d0a 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2521,13 +2521,15 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
default: html += QLatin1String("<ul"); // ### should not happen
}
+ html += QLatin1String(" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;");
+
if (format.hasProperty(QTextFormat::ListIndent)) {
- html += QLatin1String(" style=\"-qt-list-indent: ");
+ html += QLatin1String(" -qt-list-indent: ");
html += QString::number(format.indent());
- html += QLatin1String(";\"");
+ html += QLatin1Char(';');
}
- html += QLatin1Char('>');
+ html += QLatin1String("\">");
}
html += QLatin1String("<li");
diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
index 36a8df1..bbb6536 100644
--- a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
+++ b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
@@ -57,30 +57,35 @@ public:
~QTraceWindowSurface();
QPaintDevice *paintDevice();
+ void beginPaint(const QRegion &rgn);
void endPaint(const QRegion &rgn);
+ bool scroll(const QRegion &area, int dx, int dy);
+
private:
QPaintBuffer *buffer;
+ QList<QRegion> updates;
- QFile *outputFile;
- QDataStream *out;
-
- int frameId;
+ qulonglong winId;
};
QTraceWindowSurface::QTraceWindowSurface(QWidget *widget)
: QRasterWindowSurface(widget)
, buffer(0)
- , outputFile(0)
- , out(0)
- , frameId(0)
+ , winId(0)
{
}
QTraceWindowSurface::~QTraceWindowSurface()
{
- delete out;
- delete outputFile;
+ if (buffer) {
+ QFile outputFile(QString(QLatin1String("qtgraphics-%0.trace")).arg(winId));
+ if (outputFile.open(QIODevice::WriteOnly)) {
+ QDataStream out(&outputFile);
+ out << *buffer << updates;
+ }
+ delete buffer;
+ }
}
QPaintDevice *QTraceWindowSurface::paintDevice()
@@ -92,28 +97,33 @@ QPaintDevice *QTraceWindowSurface::paintDevice()
return buffer;
}
-void QTraceWindowSurface::endPaint(const QRegion &rgn)
+void QTraceWindowSurface::beginPaint(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);
- }
+ // ensure paint buffer is created
+ paintDevice();
+ buffer->beginNewFrame();
+
+ QRasterWindowSurface::beginPaint(rgn);
+}
+void QTraceWindowSurface::endPaint(const QRegion &rgn)
+{
QPainter p(QRasterWindowSurface::paintDevice());
- buffer->draw(&p);
+ buffer->draw(&p, buffer->numFrames()-1);
p.end();
- if (out) {
- *out << frameId++;
- *out << (qulonglong)window()->winId();
- *out << geometry();
- *out << rgn;
- *out << *buffer;
- }
+ winId = (qulonglong)window()->winId();
+
+ updates << rgn;
- delete buffer;
- buffer = 0;
+ QRasterWindowSurface::endPaint(rgn);
+}
+
+bool QTraceWindowSurface::scroll(const QRegion &, int, int)
+{
+ // TODO: scrolling should also be streamed and replayed
+ // to test scrolling performance
+ return false;
}
QTraceGraphicsSystem::QTraceGraphicsSystem()