diff options
Diffstat (limited to 'src')
34 files changed, 524 insertions, 642 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index f3ec8e1..bfb03ab 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -975,7 +975,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) face->glyphs_substituted = false; face->buffer = 0; - HB_Error error; + HB_Error error = HB_Err_Ok; HB_Stream stream; HB_Stream gdefStream; diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ef4989b..299585a 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -229,7 +229,10 @@ void QUnifiedTimer::restartAnimationTimer() void QUnifiedTimer::timerEvent(QTimerEvent *event) { - if (event->timerId() == startStopAnimationTimer.timerId()) { + //in the case of consistent timing we make sure the orders in which events come is always the same + //for that purpose we do as if the startstoptimer would always fire before the animation timer + if ((consistentTiming && startStopAnimationTimer.isActive()) || + event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); //we transfer the waiting animations into the "really running" state @@ -247,7 +250,9 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) time.start(); } } - } else if (event->timerId() == animationTimer.timerId()) { + } + + if (event->timerId() == animationTimer.timerId()) { // update current time on all top level animations updateAnimationsTime(); restartAnimationTimer(); diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 10a61ca..9335085 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2546,9 +2546,9 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour int destinationLast = destinationChild + (sourceLast - sourceFirst); d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast)); - d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); emit layoutAboutToBeChanged(); + d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); return true; } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 95602d9..4321c59 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -145,8 +145,7 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i) - connectedSignals[i] = 0; + connectedSignals = 0; inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; @@ -2937,13 +2936,9 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, QObjectPrivate *const sender_d = QObjectPrivate::get(s); if (signal_index < 0) { - for (uint i = 0; i < (sizeof sender_d->connectedSignals - / sizeof sender_d->connectedSignals[0] ); ++i) - sender_d->connectedSignals[i] = ~0u; - } else if (signal_index < (int)sizeof sender_d->connectedSignals * 8) { - uint n = (signal_index / (8 * sizeof sender_d->connectedSignals[0])); - sender_d->connectedSignals[n] |= (1 << (signal_index - n * 8 - * sizeof sender_d->connectedSignals[0])); + sender_d->connectedSignals = ~ulong(0); + } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) { + sender_d->connectedSignals |= ulong(1) << signal_index; } return true; @@ -3201,15 +3196,9 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign computeOffsets(m, &signalOffset, &methodOffset); int signal_index = signalOffset + local_signal_index; - if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8 - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback) { - uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0])); - uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]); - if ((sender->d_func()->connectedSignals[n] & m) == 0) - // nothing connected to these signals, and no spy - return; - } + + if (!sender->d_func()->isSignalConnected(signal_index)) + return; // nothing connected to these signals, and no spy if (sender->d_func()->blockSig) return; @@ -3370,28 +3359,6 @@ int QObjectPrivate::signalIndex(const char *signalName) const return relative_index + signalOffset; } -/*! \internal - - Returns true if the signal with index \a signal_index from object \a sender is connected. - Signals with indices above a certain range are always considered connected (see connectedSignals - in QObjectPrivate). If a signal spy is installed, all signals are considered connected. - - \a signal_index must be the index returned by QObjectPrivate::signalIndex; -*/ -bool QObjectPrivate::isSignalConnected(int signal_index) const -{ - if (signal_index < (int)sizeof(connectedSignals) * 8 - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback) { - uint n = (signal_index / (8 * sizeof connectedSignals[0])); - uint m = 1 << (signal_index - n * 8 * sizeof connectedSignals[0]); - if ((connectedSignals[n] & m) == 0) - // nothing connected to these signals, and no spy - return false; - } - return true; -} - /***************************************************************************** Properties *****************************************************************************/ diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index f087407..f899c78 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -172,7 +172,7 @@ public: } int signalIndex(const char *signalName) const; - bool isSignalConnected(int signalIdx) const; + inline bool isSignalConnected(int signalIdx) const; public: QString objectName; @@ -183,7 +183,7 @@ public: Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object - mutable quint32 connectedSignals[2]; // 64-bit, so doesn't cause padding on 64-bit platforms + mutable ulong connectedSignals; #ifdef QT3_SUPPORT QList<QObject *> pendingChildInsertedEvents; @@ -205,6 +205,23 @@ public: int *deleteWatch; }; +/*! \internal + + Returns true if the signal with index \a signal_index from object \a sender is connected. + Signals with indices above a certain range are always considered connected (see connectedSignals + in QObjectPrivate). If a signal spy is installed, all signals are considered connected. + + \a signal_index must be the index returned by QObjectPrivate::signalIndex; +*/ +inline bool QObjectPrivate::isSignalConnected(int signal_index) const +{ + return signal_index >= (int)sizeof(connectedSignals) * 8 + || qt_signal_spy_callback_set.signal_begin_callback + || qt_signal_spy_callback_set.signal_end_callback + || (connectedSignals & (ulong(1) << signal_index)); +} + + inline void q_guard_addGuard(QGuard<QObject> *g) { QObjectPrivate *p = QObjectPrivate::get(g->o); diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index c0e4890..cf28dc4 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -236,6 +236,18 @@ bool QEglContext::makeCurrent(EGLSurface surface) currentSurface = surface; setCurrentContext(apiType, this); + // Force the right API to be bound before making the context current. + // The EGL implementation should be able to figure this out from ctx, + // but some systems require the API to be explicitly set anyway. +#ifdef EGL_OPENGL_ES_API + if (apiType == QEgl::OpenGL) + eglBindAPI(EGL_OPENGL_ES_API); +#endif +#ifdef EGL_OPENVG_API + if (apiType == QEgl::OpenVG) + eglBindAPI(EGL_OPENVG_API); +#endif + bool ok = eglMakeCurrent(dpy, surface, surface, ctx); if (!ok) qWarning() << "QEglContext::makeCurrent():" << errorString(eglGetError()); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 94a37a0..bb45e7e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -755,7 +755,6 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch case QGraphicsItem::ItemClipsChildrenToShape: flag = AncestorClipsChildren; enabled = flags & QGraphicsItem::ItemClipsChildrenToShape; - invalidateCachedClipPathRecursively(/*childrenOnly=*/true); break; case QGraphicsItem::ItemIgnoresTransformations: flag = AncestorIgnoresTransformations; @@ -1104,9 +1103,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); if (scene) { if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); + scene->d_func()->markDirty(q_ptr); // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1147,11 +1144,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setEnabledHelper(true, /* explicit = */ false); // If the item is being deleted, the whole scene will be updated. - if (scene) { - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr); } } @@ -1732,9 +1726,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); } - if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape)) - d_ptr->invalidateCachedClipPath(); - if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) { // Item children clipping changes. Propagate the ancestor flag to // all children. @@ -1777,9 +1768,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) else d_ptr->scene->d_func()->unregisterScenePosItem(this); } - d_ptr->scene->d_func()->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath*/true); + d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); } // Notify change. @@ -2127,12 +2116,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData)); if (c) c->purge(); - if (scene) { - scene->d_func()->markDirty(q_ptr, QRectF(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/false, - /*force=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); } // Certain properties are dropped as an item becomes invisible. @@ -2542,7 +2527,6 @@ void QGraphicsItem::setOpacity(qreal opacity) #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/false, /*force=*/false, /*ignoreOpacity=*/true); } @@ -2590,8 +2574,11 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) d_ptr->graphicsEffect = 0; if (oldEffectPrivate) { oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source. - if (d_ptr->scene) // Update the views directly. - d_ptr->scene->d_func()->markDirty(this, QRectF(), false, false, false, false, true); + if (d_ptr->scene) { // Update the views directly. + d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/false, + /*force=*/false, /*ignoreOpacity=*/false, + /*removeItemFromScene=*/true); + } } } else { // Set new effect. @@ -3399,7 +3386,6 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) { Q_Q(QGraphicsItem); inSetPosHelper = 1; - updateCachedClipPathFromSetPosHelper(pos); if (scene) q->prepareGeometryChange(); QPointF oldPos = this->pos; @@ -4535,22 +4521,12 @@ bool QGraphicsItem::isClipped() const QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); - if (!d->dirtyClipPath) - return d->emptyClipPath ? QPainterPath() : d->cachedClipPath; - - if (!isClipped()) { - d_ptr->setCachedClipPath(QPainterPath()); - return d->cachedClipPath; - } + if (!isClipped()) + return QPainterPath(); const QRectF thisBoundingRect(boundingRect()); - if (thisBoundingRect.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + if (thisBoundingRect.isEmpty()) return QPainterPath(); - } QPainterPath clip; // Start with the item's bounding rect. @@ -4561,40 +4537,18 @@ QPainterPath QGraphicsItem::clipPath() const const QGraphicsItem *lastParent = this; // Intersect any in-between clips starting at the top and moving downwards. - bool foundValidClipPath = false; while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); - if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { - if (parent->d_ptr->emptyClipPath) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); - return QPainterPath(); - } - clip = clip.intersected(parent->d_ptr->cachedClipPath); - if (!(parent->d_ptr->flags & ItemClipsToShape)) - clip = clip.intersected(parent->shape()); - } else { - clip = clip.intersected(parent->shape()); - } - - if (clip.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + clip = clip.intersected(parent->shape()); + if (clip.isEmpty()) return clip; - } lastParent = parent; } - if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - || foundValidClipPath) { + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; - } } if (lastParent != this) { @@ -4607,7 +4561,6 @@ QPainterPath QGraphicsItem::clipPath() const if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); - d_ptr->setCachedClipPath(clip); return clip; } @@ -5026,15 +4979,14 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) \internal Returns true if we can discard an update request; otherwise false. */ -bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit, - bool ignoreDirtyBit, bool ignoreOpacity) const +bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit, + bool ignoreOpacity) const { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. return !scene || (!visible && !ignoreVisibleBit && !this->ignoreVisible) || (!ignoreDirtyBit && fullUpdatePending) - || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } @@ -5169,109 +5121,6 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } -void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect) -{ - setEmptyCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull() - && !(flags & QGraphicsItem::ItemClipsChildrenToShape); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->setEmptyCachedClipPathRecursively(); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect) -{ - if (!childrenOnly) - invalidateCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull(); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos) -{ - Q_ASSERT(inSetPosHelper); - - if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) - return; // Not clipped by any ancestor. - - // Find closest clip ancestor and transform. - Q_Q(QGraphicsItem); - // COMBINE - QTransform thisToParentTransform = QTransform::fromTranslate(newPos.x(), newPos.y()); - if (transformData) - thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform); - QGraphicsItem *clipParent = parent; - while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) { - thisToParentTransform *= clipParent->d_ptr->transformToParent(); - clipParent = clipParent->d_ptr->parent; - } - - // 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()); - const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); - - if (!parentBoundingRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's bounding rect, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect)); - return; - } - - const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape()); - if (parentClip.contains(thisBoundingRect)) - return; // Item is inside the clip parent's shape. No update required. - - const QRectF parentClipRect(parentClip.controlPointRect()); - if (!parentClipRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's shape, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect)); - } else { - // Item is partially inside the clip parent's shape, - // i.e. the cached clip path must be invalidated. - invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect)); - } -} - // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -7288,9 +7137,7 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); // For compatibility reasons, we have to update the item's old geometry // if someone is connected to the changed signal or the scene has no views. @@ -7313,16 +7160,6 @@ void QGraphicsItem::prepareGeometryChange() // ### Only do this if the parent's effect applies to the entire subtree. parent->d_ptr->notifyBoundingRectChanged = 1; } - - if (d_ptr->inSetPosHelper) - return; - - if (d_ptr->flags & ItemClipsChildrenToShape - || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - d_ptr->invalidateCachedClipPathRecursively(); - } else { - d_ptr->invalidateCachedClipPath(); - } } /*! @@ -9604,9 +9441,11 @@ void QGraphicsTextItem::setDefaultTextColor(const QColor &col) { QTextControl *c = dd->textControl(); QPalette pal = c->palette(); + QColor old = pal.color(QPalette::Text); pal.setColor(QPalette::Text, col); c->setPalette(pal); - update(); + if (old != col) + update(); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 75c8246..d6ffb1a 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -152,8 +152,6 @@ public: dirty(0), dirtyChildren(0), localCollisionHack(0), - dirtyClipPath(1), - emptyClipPath(0), inSetPosHelper(0), needSortChildren(1), // ### can be 0 by default? allChildrenDirty(0), @@ -221,7 +219,7 @@ public: void appendGraphicsTransform(QGraphicsTransform *t); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); - bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, + bool discardUpdateRequest(bool ignoreVisibleBit = false, bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT @@ -307,26 +305,6 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); - inline void setCachedClipPath(const QPainterPath &path) - { - cachedClipPath = path; - dirtyClipPath = 0; - emptyClipPath = 0; - } - - inline void setEmptyCachedClipPath() - { - emptyClipPath = 1; - dirtyClipPath = 0; - } - - void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF()); - - inline void invalidateCachedClipPath() - { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } - - void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); - void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { @@ -409,17 +387,12 @@ public: return true; } - inline bool isClippedAway() const - { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } - inline bool childrenClippedToShape() const { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); } inline bool isInvisible() const { - return !visible - || (childrenClippedToShape() && isClippedAway()) - || (childrenCombineOpacity() && isFullyTransparent()); + return !visible || (childrenCombineOpacity() && isFullyTransparent()); } void setFocusHelper(Qt::FocusReason focusReason, bool climb); @@ -435,7 +408,6 @@ public: inline void sendScenePosChange(); virtual void siblingOrderChange(); - QPainterPath cachedClipPath; QRectF childrenBoundingRect; QRectF needsRepaint; QMap<QWidget *, QRect> paintedViewBoundingRects; @@ -480,8 +452,6 @@ public: quint32 dirty : 1; quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; - quint32 dirtyClipPath : 1; - quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 10d251d..8777cdc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -555,7 +555,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) // Clear focus on the item to remove any reference in the focusWidget chain. item->clearFocus(); - markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true); + markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false, + /*ignoreOpacity=*/false, /*removingItemFromScene=*/true); if (item->d_ptr->inDestructor) { // The item is actually in its destructor, we call the special method in the index. @@ -4759,15 +4760,13 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool maybeDirtyClipPath, bool force, bool ignoreOpacity, - bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene) { Q_ASSERT(item); if (updateAll) return; - if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, - /*ignoreVisibleBit=*/force, + if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, /*ignoreOpacity=*/ignoreOpacity)) { if (item->d_ptr->dirty) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index fdec466..69e4d5b 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -78,7 +78,7 @@ class QGraphicsSceneIndex; class QGraphicsView; class QGraphicsWidget; -class QGraphicsScenePrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsScene) public: @@ -222,8 +222,7 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, - bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); @@ -266,6 +265,7 @@ public: { if (needSortTopLevelItems) { qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + topLevelSequentialOrdering = false; needSortTopLevelItems = false; } } diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index d9c65bb..f6c06d5 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -385,8 +385,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - wd->invalidateCachedClipPathRecursively(); - // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 35322e9..650075b 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -55,20 +55,11 @@ Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0; Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0; Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0; - -QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks = 0; - - -QImagePixmapCleanupHooks::QImagePixmapCleanupHooks() -{ - qt_image_and_pixmap_cleanup_hooks = this; -} +Q_GLOBAL_STATIC(QImagePixmapCleanupHooks, qt_image_and_pixmap_cleanup_hooks) QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() { - if (!qt_image_and_pixmap_cleanup_hooks) - qt_image_and_pixmap_cleanup_hooks = new QImagePixmapCleanupHooks; - return qt_image_and_pixmap_cleanup_hooks; + return qt_image_and_pixmap_cleanup_hooks(); } void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) @@ -105,9 +96,8 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks[i](pm); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -115,9 +105,8 @@ void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks[i](pm); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -125,9 +114,8 @@ void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->imageHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->imageHooks[i](key); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->imageHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->imageHooks[i](key); if (qt_image_cleanup_hook_64) qt_image_cleanup_hook_64(key); diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index 9e490d7..dfc5f28 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -61,13 +61,10 @@ typedef void (*_qt_image_cleanup_hook_64)(qint64); typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*); class QImagePixmapCleanupHooks; -extern QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks; class Q_GUI_EXPORT QImagePixmapCleanupHooks { public: - QImagePixmapCleanupHooks(); - static QImagePixmapCleanupHooks *instance(); static void enableCleanupHooks(const QImage &image); diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index f1ae3d2..fc82f30 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1153,6 +1153,8 @@ void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() { Q_Q(QSortFilterProxyModel); q->beginResetModel(); + invalidatePersistentIndexes(); + clear_mapping(); } void QSortFilterProxyModelPrivate::_q_sourceReset() @@ -1470,6 +1472,8 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { Q_D(QSortFilterProxyModel); + beginResetModel(); + disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex))); @@ -1551,7 +1555,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); d->clear_mapping(); - reset(); + endResetModel(); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); } diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index fb2bc72..89d961c 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -133,36 +133,46 @@ private: TTimeIntervalMicroSeconds iDuration; }; +static QS60Beep* qt_S60Beep = 0; + QS60Beep::~QS60Beep() { + if (iToneUtil) { + switch (iState) { + case EBeepPlaying: + iToneUtil->CancelPlay(); + break; + case EBeepNotPrepared: + iToneUtil->CancelPrepare(); + break; + } + } delete iToneUtil; } QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - QS60Beep* self=new (ELeave) QS60Beep(); + QS60Beep* self = new (ELeave) QS60Beep(); CleanupStack::PushL(self); self->ConstructL(aFrequency, aDuration); CleanupStack::Pop(); return self; -}; +} void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - iToneUtil=CMdaAudioToneUtility::NewL(*this); - iState=EBeepNotPrepared; - iFrequency=aFrequency; - iDuration=aDuration; - iToneUtil->PrepareToPlayTone(iFrequency,iDuration); + iToneUtil = CMdaAudioToneUtility::NewL(*this); + iState = EBeepNotPrepared; + iFrequency = aFrequency; + iDuration = aDuration; + iToneUtil->PrepareToPlayTone(iFrequency, iDuration); } void QS60Beep::Play() { - if (iState != EBeepNotPrepared) { - if (iState == EBeepPlaying) { - iToneUtil->CancelPlay(); - iState = EBeepPrepared; - } + if (iState == EBeepPlaying) { + iToneUtil->CancelPlay(); + iState = EBeepPrepared; } iToneUtil->Play(); @@ -173,13 +183,14 @@ void QS60Beep::MatoPrepareComplete(TInt aError) { if (aError == KErrNone) { iState = EBeepPrepared; + Play(); } } void QS60Beep::MatoPlayComplete(TInt aError) { Q_UNUSED(aError); - iState=EBeepPrepared; + iState = EBeepPrepared; } @@ -1226,6 +1237,10 @@ void qt_init(QApplicationPrivate * /* priv */, int) *****************************************************************************/ void qt_cleanup() { + if(qt_S60Beep) { + delete qt_S60Beep; + qt_S60Beep = 0; + } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -1467,14 +1482,13 @@ void QApplication::setCursorFlashTime(int msecs) void QApplication::beep() { - TInt frequency=440; - TTimeIntervalMicroSeconds duration(500000); - QS60Beep* beep=NULL; - TRAPD(err, beep=QS60Beep::NewL(frequency, duration)); - if (!err) - beep->Play(); - delete beep; - beep=NULL; + if (!qt_S60Beep) { + TInt frequency = 880; + TTimeIntervalMicroSeconds duration(500000); + TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration)); + } + if (qt_S60Beep) + qt_S60Beep->Play(); } /*! diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fbb9115..b389054 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4605,7 +4605,7 @@ void QWidgetPrivate::updateFont(const QFont &font) if (!q->parentWidget() && extra && extra->proxyWidget) { QGraphicsProxyWidget *p = extra->proxyWidget; inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve(); - } else + } else #endif //QT_NO_GRAPHICSVIEW if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedFontResolveMask = 0; @@ -9897,13 +9897,13 @@ void QWidget::scroll(int dx, int dy) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, proxy->subWidgetRect(this)); return; } @@ -9932,13 +9932,13 @@ void QWidget::scroll(int dx, int dy, const QRect &r) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint())); return; } diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8226797..1b8f413 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -949,6 +949,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; QWidgetBackingStore *wbs = x->backingStore; + if (!wbs) + return; static int accelEnv = -1; if (accelEnv == -1) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 48629d1..fc1863f 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5886,7 +5886,12 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption Draws the text item \a ti at position \a p. */ -/*! \internal +/*! + \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti) + + \internal + \since 4.1 + Draws the text item \a ti at position \a p. This method ignores the painters background mode and @@ -5899,34 +5904,57 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption ignored aswell. You'll need to pass in the correct flags to get underlining and strikeout. */ -static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device) + +static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { - extern int qt_defaultDpi(); + const qreal radiusBase = qMax(qreal(1), maxRadius); + + QString key = QLatin1String("WaveUnderline-"); + key += pen.color().name(); + key += QLatin1Char('-'); + key += QString::number(radiusBase); + + QPixmap pixmap; + if (QPixmapCache::find(key, pixmap)) + return pixmap; + + const qreal halfPeriod = qMax(qreal(2), radiusBase * 1.61803399); // the golden ratio + const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod); + const int radius = qFloor(radiusBase); + QPainterPath path; - bool up = true; - const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius)); - qreal xs, ys; - int i = 0; - path.moveTo(0, radius); - do { - xs = i*(2*radius); - ys = 0; + qreal xs = 0; + qreal ys = radius; - qreal remaining = minWidth - xs; - qreal angle = 180; + while (xs < width) { + xs += halfPeriod; + ys = -ys; + path.quadTo(xs - halfPeriod / 2, ys, xs, 0); + } - // cut-off at the last arc segment - if (remaining < 2 * radius) - angle = 180 * remaining / (2 * radius); + pixmap = QPixmap(width, radius * 2); + pixmap.fill(Qt::transparent); + { + QPen wavePen = pen; + wavePen.setCapStyle(Qt::SquareCap); + + // This is to protect against making the line too fat, as happens on Mac OS X + // due to it having a rather thick width for the regular underline. + const qreal maxPenWidth = .8 * radius; + if (wavePen.widthF() > maxPenWidth) + wavePen.setWidth(maxPenWidth); - path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle); + QPainter imgPainter(&pixmap); + imgPainter.setPen(wavePen); + imgPainter.setRenderHint(QPainter::Antialiasing); + imgPainter.translate(0, radius); + imgPainter.drawPath(path); + } - up = !up; - ++i; - } while (xs + 2*radius < minWidth); + QPixmapCache::insert(key, pixmap); - return path; + return pixmap; } static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) @@ -5947,9 +5975,11 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setCapStyle(Qt::FlatCap); QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + + const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal()); + const qreal underlinePos = pos.y() + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -5957,16 +5987,18 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const if (underlineStyle == QTextCharFormat::WaveUnderline) { painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - painter->translate(pos.x(), underlinePos); + painter->translate(0, pos.y() + 1); QColor uc = ti.charFormat.underlineColor(); if (uc.isValid()) - painter->setPen(uc); + pen.setColor(uc); - painter->drawPath(generateWavyPath(ti.width.toReal(), - fe->underlinePosition().toReal(), - painter->device())); + // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms + const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); + const int descent = (int) ti.descent.toReal(); + + painter->setBrushOrigin(painter->brushOrigin().x(), 0); + painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); @@ -6001,10 +6033,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } -/*! - \internal - \since 4.1 -*/ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 51c2a96..4075cf7 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -4843,9 +4843,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex uint sc = SC_TitleBarMinButton; ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox; bool active = titlebar->state & State_Active; - int border = 2; - titleBarRect.origin.x += border; - titleBarRect.origin.y -= border; + if (qMacVersion() < QSysInfo::MV_10_6) { + int border = 2; + titleBarRect.origin.x += border; + titleBarRect.origin.y -= border; + } while (sc <= SC_TitleBarCloseButton) { if (sc & titlebar->subControls) { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index ee10ff6..dca78ca 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -144,7 +144,7 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, - {SE_Editor, QS60StyleEnums::SP_QsnFrNotepadCenter}, + {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, }; static const int frameElementsCount = @@ -459,11 +459,6 @@ void QS60StylePrivate::setThemePalette(QApplication *app) const storeThemePalette(&widgetPalette); } -void QS60StylePrivate::setThemePalette(QStyleOption *option) const -{ - setThemePalette(&option->palette); -} - QPalette* QS60StylePrivate::themePalette() { return m_themePalette; @@ -640,16 +635,16 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const { if(!widget) return; - QPalette widgetPalette = QApplication::palette(widget); //header view and its viewport need to be set 100% transparent button color, since drawing code will //draw transparent theme graphics to table column and row headers. if (qobject_cast<QHeaderView *>(widget)){ + QPalette widgetPalette = QApplication::palette(widget); widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); QHeaderView* header = qobject_cast<QHeaderView *>(widget); widgetPalette.setColor(QPalette::Button, Qt::transparent ); - if ( header->viewport() ) + if (header->viewport()) header->viewport()->setPalette(widgetPalette); QApplication::setPalette(widgetPalette, "QHeaderView"); } @@ -812,7 +807,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(10); + result.setWidth(result.height()>>1); break; case QS60StyleEnums::SP_QgnIndiSliderEdit: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -870,7 +865,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag return result; } -bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) +bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) { //If brush is not changed from style's default values, draw theme graphics. return (backgroundBrush.color() == Qt::transparent || @@ -1788,7 +1783,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (qobject_cast<const QAbstractButton *>(widget)) { //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; - const int borderTweak = + const int borderTweak = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); @@ -1881,7 +1876,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest); } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - if (option->direction == Qt::LeftToRight) + if (option->direction == Qt::LeftToRight) headerRect.adjust(-2*frameWidth, 0, 0, 0); else headerRect.adjust(0, 0, 2*frameWidth, 0); @@ -2027,7 +2022,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.setHeight((int)(buttonRect.height() * scaler)); // move the rect up for half of the new height-gain const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; - buttonRect.adjust(0,-newY,0,-newY); + buttonRect.adjust(0, -newY, -1, -newY); painter->save(); QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); @@ -2596,7 +2591,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; - const bool popup = (toolButton->features & + const bool popup = (toolButton->features & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay)) == QStyleOptionToolButton::MenuButtonPopup; switch (scontrol) { diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index ea86bb2..5ab2308 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -271,15 +271,6 @@ public: SP_QsnFrButtonSideLInactive, SP_QsnFrButtonSideRInactive, SP_QsnFrButtonCenterInactive, - SP_QsnFrNotepadCornerTl, - SP_QsnFrNotepadCornerTr, - SP_QsnFrNotepadCornerBl, - SP_QsnFrNotepadCornerBr, - SP_QsnFrNotepadSideT, - SP_QsnFrNotepadSideB, - SP_QsnFrNotepadSideL, - SP_QsnFrNotepadSideR, - SP_QsnFrNotepadCenter }; enum ColorLists { @@ -418,8 +409,6 @@ public: //set theme palette for application void setThemePalette(QApplication *application) const; - //set theme palette for style option - void setThemePalette(QStyleOption *option) const; //access to theme palette static QPalette* themePalette(); diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 18851b7..7ec8e31 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -485,6 +485,7 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); } +#ifndef Q_WS_WINCE bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const { Q_ASSERT(metrics != 0); @@ -536,6 +537,7 @@ bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph return false; } } +#endif glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) { diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 43e1f12..bab71c9 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -109,7 +109,9 @@ public: int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); +#ifndef Q_WS_WINCE bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const; +#endif QString _name; HFONT hfont; diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 3800224..785b2bd 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1411,6 +1411,8 @@ bool QLineEdit::event(QEvent * e) QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate())); }else if(e->type() == QEvent::ShortcutOverride){ d->control->processEvent(e); + } else if (e->type() == QEvent::KeyRelease) { + d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); } #ifdef QT_KEYPAD_NAVIGATION @@ -1615,6 +1617,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) } #endif d->control->processKeyEvent(event); + if (event->isAccepted()) + d->control->setCursorBlinkPeriod(0); } /*! diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 501e62f..557acfb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -120,6 +120,7 @@ void QMainWindowPrivate::init() #ifdef QT_SOFTKEYS_ENABLED menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q); menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction")); + menuBarAction->setVisible(false); #endif } diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 761a060..2e27226 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -229,7 +229,7 @@ void QMenuPrivate::updateActionRects() const Q_Q(const QMenu); if (!itemsDirty) return; - + q->ensurePolished(); //let's reinitialize the buffer @@ -292,7 +292,7 @@ void QMenuPrivate::updateActionRects() const if (!action->isVisible() || (collapsibleSeparators && previousWasSeparator && action->isSeparator())) continue; // we continue, this action will get an empty QRect - + previousWasSeparator = action->isSeparator(); //let the style modify the above size.. @@ -1139,7 +1139,7 @@ void QMenuPrivate::_q_actionTriggered() //we check the parent hierarchy QList< QPointer<QWidget> > list; for(QWidget *widget = q->parentWidget(); widget; ) { - if (qobject_cast<QMenu*>(widget) + if (qobject_cast<QMenu*>(widget) #ifndef QT_NO_MENUBAR || qobject_cast<QMenuBar*>(widget) #endif @@ -1306,7 +1306,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) the addAction(), addActions() and insertAction() functions. An action is represented vertically and rendered by QStyle. In addition, actions can have a text label, an optional icon drawn on the very left side, - and shortcut key sequence such as "Ctrl+X". + and shortcut key sequence such as "Ctrl+X". The existing actions held by a menu can be found with actions(). @@ -1906,9 +1906,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction) pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); } else { if (pos.x()+size.width()-1 > screen.right()-desktopFrame) - pos.setX(qMin(p.x()+size.width(), screen.right()-desktopFrame-size.width()+1)); + pos.setX(screen.right()-desktopFrame-size.width()+1); if (pos.x() < screen.left()+desktopFrame) - pos.setX(qMax(p.x(), screen.left() + desktopFrame)); + pos.setX(screen.left() + desktopFrame); } if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { if(snapToMouse) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c7759e8..eae8b7d 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1802,6 +1802,9 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) QTextBlock block = firstVisibleBlock(); qreal maximumWidth = document()->documentLayout()->documentSize().width(); + // Set a brush origin so that the WaveUnderline knows where the wave started + painter.setBrushOrigin(offset); + // keep right margin clean from full-width selection int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - document()->documentMargin(); diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index 9eb07ac..50b225c 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -65,14 +65,13 @@ class QSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QSpinBox) public: - QSpinBoxPrivate(QWidget *parent = 0); + QSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; virtual QString textFromValue(const QVariant &n) const; QVariant validateAndInterpret(QString &input, int &pos, QValidator::State &state) const; - QChar thousand; inline void init() { Q_Q(QSpinBox); @@ -85,7 +84,7 @@ class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QDoubleSpinBox) public: - QDoubleSpinBoxPrivate(QWidget *parent = 0); + QDoubleSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; @@ -95,7 +94,6 @@ public: double round(double input) const; // variables int decimals; - QChar delimiter, thousand; inline void init() { Q_Q(QDoubleSpinBox); @@ -201,7 +199,7 @@ public: */ QSpinBox::QSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->init(); @@ -213,7 +211,7 @@ QSpinBox::QSpinBox(QWidget *parent) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); setObjectName(QString::fromAscii(name)); @@ -225,7 +223,7 @@ QSpinBox::QSpinBox(QWidget *parent, const char *name) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->minimum = QVariant(qMin<int>(minimum, maximum)); @@ -464,10 +462,9 @@ void QSpinBox::setRange(int minimum, int maximum) QString QSpinBox::textFromValue(int value) const { - Q_D(const QSpinBox); QString str = locale().toString(value); if (qAbs(value) >= 1000 || value == INT_MIN) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; @@ -516,9 +513,7 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const */ void QSpinBox::fixup(QString &input) const { - Q_D(const QSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } @@ -600,7 +595,7 @@ void QSpinBox::fixup(QString &input) const \sa setMinimum(), setMaximum(), setSingleStep() */ QDoubleSpinBox::QDoubleSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent) { Q_D(QDoubleSpinBox); d->init(); @@ -875,7 +870,7 @@ QString QDoubleSpinBox::textFromValue(double value) const Q_D(const QDoubleSpinBox); QString str = locale().toString(value, 'f', d->decimals); if (qAbs(value) >= 1000.0) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; } @@ -920,9 +915,7 @@ QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const */ void QDoubleSpinBox::fixup(QString &input) const { - Q_D(const QDoubleSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } // --- QSpinBoxPrivate --- @@ -932,18 +925,13 @@ void QDoubleSpinBox::fixup(QString &input) const Constructs a QSpinBoxPrivate object */ -QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent) +QSpinBoxPrivate::QSpinBoxPrivate() { minimum = QVariant((int)0); maximum = QVariant((int)99); value = minimum; singleStep = QVariant((int)1); type = QVariant::Int; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567); - if (str.size() == 5) { - thousand = QChar(str.at(1)); - } - } /*! @@ -1019,20 +1007,17 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100 } else { bool ok = false; - bool removedThousand = false; num = locale.toInt(copy, &ok, 10); - if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) { - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - removedThousand = true; - num = locale.toInt(copy, &ok, 10); + if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) { + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toInt(copy2, &ok, 10); } QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num; if (!ok) { state = QValidator::Invalid; } else if (num >= min && num <= max) { - state = removedThousand ? QValidator::Intermediate : QValidator::Acceptable; + state = QValidator::Acceptable; } else if (max == min) { state = QValidator::Invalid; } else { @@ -1064,7 +1049,7 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, Constructs a QSpinBoxPrivate object */ -QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) +QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate() { minimum = QVariant(0.0); maximum = QVariant(99.99); @@ -1072,15 +1057,6 @@ QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) singleStep = QVariant(1.0); decimals = 2; type = QVariant::Double; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1); - if (str.size() == 6) { - delimiter = str.at(4); - thousand = QChar((ushort)0); - } else if (str.size() == 7) { - thousand = str.at(1); - delimiter = str.at(5); - } - Q_ASSERT(!delimiter.isNull()); } /*! @@ -1155,7 +1131,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = max != min ? QValidator::Intermediate : QValidator::Invalid; goto end; case 1: - if (copy.at(0) == delimiter + if (copy.at(0) == locale.decimalPoint() || (plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-'))) { state = QValidator::Intermediate; @@ -1163,7 +1139,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } break; case 2: - if (copy.at(1) == delimiter + if (copy.at(1) == locale.decimalPoint() && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) { state = QValidator::Intermediate; goto end; @@ -1172,14 +1148,14 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, default: break; } - if (copy.at(0) == thousand) { + if (copy.at(0) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } else if (len > 1) { - const int dec = copy.indexOf(delimiter); + const int dec = copy.indexOf(locale.decimalPoint()); if (dec != -1) { - if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == dec + 1) { + if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) { copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter } // should be treated as typing right arrow @@ -1189,7 +1165,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, goto end; } for (int i=dec + 1; i<copy.size(); ++i) { - if (copy.at(i).isSpace() || copy.at(i) == thousand) { + if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; @@ -1198,12 +1174,12 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } else { const QChar &last = copy.at(len - 1); const QChar &secondLast = copy.at(len - 2); - if ((last == thousand || last.isSpace()) - && (secondLast == thousand || secondLast.isSpace())) { + if ((last == locale.groupSeparator() || last.isSpace()) + && (secondLast == locale.groupSeparator() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; - } else if (last.isSpace() && (!thousand.isSpace() || secondLast.isSpace())) { + } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1215,11 +1191,10 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, bool ok = false; num = locale.toDouble(copy, &ok); QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok; - bool notAcceptable = false; if (!ok) { - if (thousand.isPrint()) { - if (max < 1000 && min > -1000 && copy.contains(thousand)) { + if (locale.groupSeparator().isPrint()) { + if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1227,27 +1202,23 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, const int len = copy.size(); for (int i=0; i<len- 1; ++i) { - if (copy.at(i) == thousand && copy.at(i + 1) == thousand) { + if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } } - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - - - num = locale.toDouble(copy, &ok); - QSBDEBUG() << thousand << num << copy << ok; + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toDouble(copy2, &ok); + QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok; if (!ok) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; } - notAcceptable = true; } } @@ -1255,9 +1226,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; } else if (num >= min && num <= max) { - state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable; - QSBDEBUG() << __FILE__ << __LINE__<< "state is set to " - << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable"); + state = QValidator::Acceptable; + QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Acceptable"; } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min) state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 823f919..07432c6 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1773,13 +1773,10 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->device->format().alpha() #if defined(Q_WS_WIN) - && qt_cleartype_enabled + if (qt_cleartype_enabled) #endif - ) { d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; - } #endif #if defined(QT_OPENGL_ES_2) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 1478b09..c78f73f 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -209,6 +209,65 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) } } +void QTriangulatingStroker::moveTo(const qreal *pts) +{ + m_cx = pts[0]; + m_cy = pts[1]; + + float x2 = pts[2]; + float y2 = pts[3]; + normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); + + + // To acheive jumps we insert zero-area tringles. This is done by + // adding two identical points in both the end of previous strip + // and beginning of next strip + bool invisibleJump = m_vertices.size(); + + switch (m_cap_style) { + case Qt::FlatCap: + if (invisibleJump) { + m_vertices.add(m_cx + m_nvx); + m_vertices.add(m_cy + m_nvy); + } + break; + case Qt::SquareCap: { + float sx = m_cx - m_nvy; + float sy = m_cy + m_nvx; + if (invisibleJump) { + m_vertices.add(sx + m_nvx); + m_vertices.add(sy + m_nvy); + } + emitLineSegment(sx, sy, m_nvx, m_nvy); + break; } + case Qt::RoundCap: { + QVarLengthArray<float> points; + arcPoints(m_cx, m_cy, m_cx + m_nvx, m_cy + m_nvy, m_cx - m_nvx, m_cy - m_nvy, points); + m_vertices.resize(m_vertices.size() + points.size() + 2 * int(invisibleJump)); + int count = m_vertices.size(); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.at(--count) = points[2 * end - 1]; + m_vertices.at(--count) = points[2 * end - 2]; + --end; + if (front == end) + break; + m_vertices.at(--count) = points[2 * front + 1]; + m_vertices.at(--count) = points[2 * front + 0]; + ++front; + } + + if (invisibleJump) { + m_vertices.at(count - 1) = m_vertices.at(count + 1); + m_vertices.at(count - 2) = m_vertices.at(count + 0); + } + break; } + default: break; // ssssh gcc... + } + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + void QTriangulatingStroker::cubicTo(const qreal *pts) { const QPointF *p = (const QPointF *) pts; @@ -246,6 +305,151 @@ void QTriangulatingStroker::cubicTo(const qreal *pts) m_nvy = vy; } +void QTriangulatingStroker::join(const qreal *pts) +{ + // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) + normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); + + switch (m_join_style) { + case Qt::BevelJoin: + break; + case Qt::MiterJoin: { + // Find out on which side the join should be. + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + float xprod = prevNvx * m_nvy - prevNvy * m_nvx; + float px, py, qx, qy; + + // If the segments are parallel, use bevel join. + if (qFuzzyIsNull(xprod)) + break; + + // Find the corners of the previous and next segment to join. + if (xprod < 0) { + px = m_vertices.at(count - 2); + py = m_vertices.at(count - 1); + qx = m_cx - m_nvx; + qy = m_cy - m_nvy; + } else { + px = m_vertices.at(count - 4); + py = m_vertices.at(count - 3); + qx = m_cx + m_nvx; + qy = m_cy + m_nvy; + } + + // Find intersection point. + float pu = px * prevNvx + py * prevNvy; + float qv = qx * m_nvx + qy * m_nvy; + float ix = (m_nvy * pu - prevNvy * qv) / xprod; + float iy = (prevNvx * qv - m_nvx * pu) / xprod; + + // Check that the distance to the intersection point is less than the miter limit. + if ((ix - px) * (ix - px) + (iy - py) * (iy - py) <= m_miter_limit * m_miter_limit) { + m_vertices.add(ix); + m_vertices.add(iy); + m_vertices.add(ix); + m_vertices.add(iy); + } + // else + // Do a plain bevel join if the miter limit is exceeded or if + // the lines are parallel. This is not what the raster + // engine's stroker does, but it is both faster and similar to + // what some other graphics API's do. + + break; } + case Qt::RoundJoin: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + if (m_nvx * prevNvy - m_nvy * prevNvx < 0) { + arcPoints(0, 0, m_nvx, m_nvy, -prevNvx, -prevNvy, points); + for (int i = points.size() / 2; i > 0; --i) + emitLineSegment(m_cx, m_cy, points[2 * i - 2], points[2 * i - 1]); + } else { + arcPoints(0, 0, -prevNvx, -prevNvy, m_nvx, m_nvy, points); + for (int i = 0; i < points.size() / 2; ++i) + emitLineSegment(m_cx, m_cy, points[2 * i + 0], points[2 * i + 1]); + } + break; } + default: break; // gcc warn-- + } + + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + +void QTriangulatingStroker::endCap(const qreal *) +{ + switch (m_cap_style) { + case Qt::FlatCap: + break; + case Qt::SquareCap: + emitLineSegment(m_cx + m_nvy, m_cy - m_nvx, m_nvx, m_nvy); + break; + case Qt::RoundCap: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + arcPoints(m_cx, m_cy, m_vertices.at(count - 2), m_vertices.at(count - 1), m_vertices.at(count - 4), m_vertices.at(count - 3), points); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.add(points[2 * end - 2]); + m_vertices.add(points[2 * end - 1]); + --end; + if (front == end) + break; + m_vertices.add(points[2 * front + 0]); + m_vertices.add(points[2 * front + 1]); + ++front; + } + break; } + default: break; // to shut gcc up... + } +} + +void QTriangulatingStroker::arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points) +{ + float dx1 = fromX - cx; + float dy1 = fromY - cy; + float dx2 = toX - cx; + float dy2 = toY - cy; + + // while more than 180 degrees left: + while (dx1 * dy2 - dx2 * dy1 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 90 degrees left: + while (dx1 * dx2 + dy1 * dy2 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 0 degrees left: + while (dx1 * dy2 - dx2 * dy1 > 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // remove last point which was rotated beyond [toX, toY]. + if (!points.isEmpty()) + points.resize(points.size() - 2); +} + static void qdashprocessor_moveTo(qreal x, qreal y, void *data) { ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::MoveToElement, x, y); diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index a0117d5..2dba0ce 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -43,6 +43,7 @@ #define QTRIANGULATINGSTROKER_P_H #include <private/qdatabuffer_p.h> +#include <qvarlengtharray.h> #include <private/qvectorpath_p.h> #include <private/qbezier_p.h> #include <private/qnumeric_p.h> @@ -62,13 +63,13 @@ public: private: inline void emitLineSegment(float x, float y, float nx, float ny); - inline void moveTo(const qreal *pts); + void moveTo(const qreal *pts); inline void lineTo(const qreal *pts); void cubicTo(const qreal *pts); - inline void join(const qreal *pts); + void join(const qreal *pts); inline void normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny); - inline void endCap(const qreal *pts); - inline void arc(float x, float y); + void endCap(const qreal *pts); + void arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points); void endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart); @@ -116,10 +117,6 @@ private: qreal m_inv_scale; }; - - - - inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny) { @@ -139,8 +136,6 @@ inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, fl *ny = dx * pw; } - - inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, float vy) { m_vertices.add(x + vx); @@ -149,103 +144,6 @@ inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, f m_vertices.add(y - vy); } - - -// We draw a full circle for any round join or round cap which is a -// bit of overkill... -inline void QTriangulatingStroker::arc(float x, float y) -{ - float dx = m_width; - float dy = 0; - for (int i=0; i<=m_roundness; ++i) { - float tmpx = dx * m_cos_theta - dy * m_sin_theta; - float tmpy = dx * m_sin_theta + dy * m_cos_theta; - dx = tmpx; - dy = tmpy; - emitLineSegment(x, y, dx, dy); - } -} - - - -inline void QTriangulatingStroker::endCap(const qreal *pts) -{ - switch (m_cap_style) { - case Qt::FlatCap: - break; - case Qt::SquareCap: { - float dx = m_cx - *(pts - 2); - float dy = m_cy - *(pts - 1); - - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - - emitLineSegment(m_cx + dx, m_cy + dy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - arc(m_cx, m_cy); - break; - default: break; // to shut gcc up... - } -} - - -void QTriangulatingStroker::moveTo(const qreal *pts) -{ - m_cx = pts[0]; - m_cy = pts[1]; - - float x2 = pts[2]; - float y2 = pts[3]; - normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); - - - // To acheive jumps we insert zero-area tringles. This is done by - // adding two identical points in both the end of previous strip - // and beginning of next strip - bool invisibleJump = m_vertices.size(); - - switch (m_cap_style) { - case Qt::FlatCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - break; - case Qt::SquareCap: { - float dx = x2 - m_cx; - float dy = y2 - m_cy; - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - float sx = m_cx - dx; - float sy = m_cy - dy; - if (invisibleJump) { - m_vertices.add(sx + m_nvx); - m_vertices.add(sy + m_nvy); - } - emitLineSegment(sx, sy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - - // This emitLineSegment is not needed for the arc, but we need - // to start where we put the invisibleJump vertex, otherwise - // we'll have visible triangles between subpaths. - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); - arc(m_cx, m_cy); - break; - default: break; // ssssh gcc... - } - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - - - void QTriangulatingStroker::lineTo(const qreal *pts) { emitLineSegment(pts[0], pts[1], m_nvx, m_nvy); @@ -253,52 +151,6 @@ void QTriangulatingStroker::lineTo(const qreal *pts) m_cy = pts[1]; } - - -void QTriangulatingStroker::join(const qreal *pts) -{ - // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) - normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); - - switch (m_join_style) { - case Qt::BevelJoin: - break; - case Qt::MiterJoin: { - int p1 = m_vertices.size() - 6; - int p2 = m_vertices.size() - 2; - QLineF line(m_vertices.at(p1), m_vertices.at(p1+1), - m_vertices.at(p2), m_vertices.at(p2+1)); - QLineF nextLine(m_cx - m_nvx, m_cy - m_nvy, - pts[0] - m_nvx, pts[1] - m_nvy); - - QPointF isect; - if (line.intersect(nextLine, &isect) != QLineF::NoIntersection - && QLineF(line.p2(), isect).length() <= m_miter_limit) { - // The intersection point mirrored over the m_cx, m_cy point - m_vertices.add(m_cx - (isect.x() - m_cx)); - m_vertices.add(m_cy - (isect.y() - m_cy)); - - // The intersection point - m_vertices.add(isect.x()); - m_vertices.add(isect.y()); - } - // else - // Do a plain bevel join if the miter limit is exceeded or if - // the lines are parallel. This is not what the raster - // engine's stroker does, but it is both faster and similar to - // what some other graphics API's do. - - break; } - case Qt::RoundJoin: - arc(m_cx, m_cy); - break; - - default: break; // gcc warn-- - } - - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - QT_END_NAMESPACE #endif diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index fda4b10..6b829dd 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1570,12 +1570,6 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(rect, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -1612,12 +1606,6 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(region, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -3459,14 +3447,11 @@ void QVGCompositionHelper::endCompositing() } void QVGCompositionHelper::blitWindow - (QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity) + (VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity) { - // Get the VGImage that is acting as a back buffer for the window. - VGImage image = surface->surfaceImage(); if (image == VG_INVALID_HANDLE) return; - QSize imageSize = surface->surfaceSize(); // Determine which sub rectangle of the window to draw. QRect sr = rect.translated(-topLeft); diff --git a/src/openvg/qvgcompositionhelper_p.h b/src/openvg/qvgcompositionhelper_p.h index 3afe31e..ed24e73 100644 --- a/src/openvg/qvgcompositionhelper_p.h +++ b/src/openvg/qvgcompositionhelper_p.h @@ -71,8 +71,8 @@ public: void startCompositing(const QSize& screenSize); void endCompositing(); - void blitWindow(QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity); + void blitWindow(VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity); void fillBackground(const QRegion& region, const QBrush& brush); void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset); void setScissor(const QRegion& region); diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 29d82c8..62871cf 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -200,6 +200,42 @@ static QEglContext *createContext(QPaintDevice *device) else eglSwapInterval(context->display(), 1); +#ifdef EGL_RENDERABLE_TYPE + // Has the user specified an explicit EGL configuration to use? + QByteArray configId = qgetenv("QT_VG_EGL_CONFIG"); + if (!configId.isEmpty()) { + EGLint cfgId = configId.toInt(); + EGLint properties[] = { + EGL_CONFIG_ID, cfgId, + EGL_NONE + }; + EGLint matching = 0; + EGLConfig cfg; + if (eglChooseConfig + (context->display(), properties, &cfg, 1, &matching) && + matching > 0) { + // Check that the selected configuration actually supports OpenVG + // and then create the context with it. + EGLint id = 0; + EGLint type = 0; + eglGetConfigAttrib + (context->display(), cfg, EGL_CONFIG_ID, &id); + eglGetConfigAttrib + (context->display(), cfg, EGL_RENDERABLE_TYPE, &type); + if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) { + context->setConfig(cfg); + if (!context->createContext()) { + delete context; + return 0; + } + return context; + } else { + qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId)); + } + } + } +#endif + // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); @@ -211,19 +247,19 @@ static QEglContext *createContext(QPaintDevice *device) configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT | + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; |