summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-05-11 11:44:50 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-05-11 11:44:50 (GMT)
commitfd252f78e907bb998fc654c0332cfd2adfaf8b1e (patch)
tree4b09a528659361121e133c12e307bf27587efb9e /src
parentb4c589868f278aa9a58ab9afa727dbf0a9442e22 (diff)
parenta7b128ae838b006be1259ef6ba79da5440ed52dd (diff)
downloadQt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.zip
Qt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.tar.gz
Qt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (24 commits) Stabilize tst_QColumnView::parentCurrentIndex Really fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux Fix typos in Elastic Nodes example documentation. Made paint engine texture drawing work in GL ES 2 and updated docs. Opt out of visual-config size checks with extension Fix off-by-one in text layouts and widget size hints on Mac Stabilize tst_QDockWidget::taskQTBUG_9758_undockedGeometry Mark QFileDialog::Options as a Q_FLAGS fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux Fixed scrolling bugs in widget graphics effect backend. Fixed source pixmap bug in widget graphics effect backend. Fix crash with stylesheet if widget change style in the changeEvent Fix textdrawing under GL on N900. Fixed bug in QIODevice::read after first reading 0 bytes. Fix auto-test failure on Mac/Linux/QWS. Some EGL implementations does not return a EGLNativeDisplayType Fixed the sizing of the dock area with fixed size dock widgets QSortFilterProxyModel: Warning or assert failure Performance issue with QGraphicsItem::ItemClipsChildrenToShape. Fixes crash in QGraphicsItem::mouseMove for untransformable items. ...
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qiodevice.cpp3
-rw-r--r--src/gui/dialogs/qfiledialog.h1
-rw-r--r--src/gui/effects/qgraphicseffect.cpp2
-rw-r--r--src/gui/egl/qegl_qws.cpp2
-rw-r--r--src/gui/egl/qegl_x11.cpp5
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp33
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp30
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h40
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp76
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h33
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp2
-rw-r--r--src/gui/kernel/qwidget.cpp57
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm20
-rw-r--r--src/gui/text/qtextengine_p.h2
-rw-r--r--src/gui/widgets/qcombobox.cpp3
-rw-r--r--src/gui/widgets/qcommandlinkbutton.cpp3
-rw-r--r--src/gui/widgets/qdockarealayout.cpp46
-rw-r--r--src/gui/widgets/qdockarealayout_p.h4
-rw-r--r--src/gui/widgets/qdockwidget.cpp9
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp86
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h5
-rw-r--r--src/opengl/qgl.cpp73
-rw-r--r--src/plugins/imageformats/svg/qsvgiohandler.cpp10
25 files changed, 334 insertions, 214 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index bb11d6b..223df9b 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -810,6 +810,9 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
}
}
+ if (!maxSize)
+ return readSoFar;
+
if ((d->openMode & Unbuffered) == 0 && maxSize < QIODEVICE_BUFFERSIZE) {
// In buffered mode, we try to fill up the QIODevice buffer before
// we do anything else.
diff --git a/src/gui/dialogs/qfiledialog.h b/src/gui/dialogs/qfiledialog.h
index 97fac4e..16cb317 100644
--- a/src/gui/dialogs/qfiledialog.h
+++ b/src/gui/dialogs/qfiledialog.h
@@ -67,6 +67,7 @@ class Q_GUI_EXPORT QFileDialog : public QDialog
{
Q_OBJECT
Q_ENUMS(ViewMode FileMode AcceptMode Option)
+ Q_FLAGS(Options)
Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode)
Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode)
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index ce4ce6a..5e4e49e 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -326,7 +326,7 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
}
QPixmap pm;
- if (d->m_cachedSystem == system && d->m_cachedMode == mode)
+ if (item && d->m_cachedSystem == system && d->m_cachedMode == mode)
QPixmapCache::find(d->m_cacheKey, &pm);
if (pm.isNull()) {
diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp
index 56383a5..50db397 100644
--- a/src/gui/egl/qegl_qws.cpp
+++ b/src/gui/egl/qegl_qws.cpp
@@ -94,7 +94,7 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
EGLNativeDisplayType QEgl::nativeDisplay()
{
- return EGL_DEFAULT_DISPLAY;
+ return EGLNativeDisplayType(EGL_DEFAULT_DISPLAY);
}
EGLNativeWindowType QEgl::nativeWindow(QWidget* widget)
diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp
index cb8dcda..969acc4 100644
--- a/src/gui/egl/qegl_x11.cpp
+++ b/src/gui/egl/qegl_x11.cpp
@@ -163,6 +163,11 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config)
int matchingCount = 0;
chosenVisualInfo = XGetVisualInfo(X11->display, VisualIDMask, &visualInfoTemplate, &matchingCount);
if (chosenVisualInfo) {
+ // Skip size checks if implementation supports non-matching visual
+ // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
+ if (QEgl::hasExtension("EGL_NV_post_convert_replication"))
+ return visualId;
+
int visualRedSize = countBits(chosenVisualInfo->red_mask);
int visualGreenSize = countBits(chosenVisualInfo->green_mask);
int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index b2bdc5c..b491ab9 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1813,7 +1813,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
if (fullUpdate)
- d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+ d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
// Keep the old flags to compare the diff.
GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
@@ -5433,6 +5433,24 @@ void QGraphicsItemPrivate::removeExtraItemCache()
unsetExtra(ExtraCacheData);
}
+void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
+{
+ if (!scene)
+ return;
+
+ for (int i = 0; i < scene->d_func()->views.size(); ++i) {
+ QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
+ QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
+ rect.translate(viewPrivate->dirtyScrollOffset);
+ viewPrivate->updateRect(rect);
+ }
+
+ if (updateChildren) {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
+ }
+}
+
// 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
@@ -5636,8 +5654,9 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
// Adjust with 2 pixel margin. Notice the loss of precision
// when converting to QRect.
int adjust = 2;
+ QRectF scrollRect = !rect.isNull() ? rect : boundingRect();
QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust);
- QRect irect = rect.toRect().translated(-br.x(), -br.y());
+ QRect irect = scrollRect.toRect().translated(-br.x(), -br.y());
pix.scroll(dx, dy, irect);
@@ -5645,11 +5664,11 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
// Translate the existing expose.
foreach (QRectF exposedRect, c->exposed)
- c->exposed += exposedRect.translated(dx, dy) & rect;
+ c->exposed += exposedRect.translated(dx, dy) & scrollRect;
// Calculate exposure.
QRegion exposed;
- QRect r = rect.toRect();
+ QRect r = scrollRect.toRect();
exposed += r;
exposed -= r.translated(dx, dy);
foreach (QRect rect, exposed.rects())
@@ -7132,7 +7151,11 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// calculate their diff by mapping viewport coordinates
// directly to parent coordinates.
// COMBINE
- QTransform viewToParentTransform = (item->d_func()->transformData->computedFullTransform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()))
+ QTransform itemTransform;
+ if (item->d_ptr->transformData)
+ itemTransform = item->d_ptr->transformData->computedFullTransform();
+ itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
+ QTransform viewToParentTransform = itemTransform
* (item->sceneTransform() * view->viewportTransform()).inverted();
currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 569a329..e812f29 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -377,6 +377,7 @@ public:
QGraphicsItemCache *extraItemCache() const;
void removeExtraItemCache();
+ void updatePaintedViewBoundingRects(bool updateChildren);
void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
inline void ensureSceneTransform()
{
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 0d4e48a..dfba7c9 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -290,13 +290,19 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
updateAll(false),
calledEmitUpdated(false),
processDirtyItemsEmitted(false),
- selectionChanging(0),
needSortTopLevelItems(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
scenePosDescendantsUpdatePending(false),
stickyFocus(false),
hasFocus(false),
+ lastMouseGrabberItemHasImplicitMouseGrab(false),
+ allItemsIgnoreHoverEvents(true),
+ allItemsUseDefaultCursor(true),
+ painterStateProtection(true),
+ sortCacheEnabled(false),
+ allItemsIgnoreTouchEvents(true),
+ selectionChanging(0),
rectAdjust(2),
focusItem(0),
lastFocusItem(0),
@@ -306,16 +312,10 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
activationRefCount(0),
childExplicitActivation(0),
lastMouseGrabberItem(0),
- lastMouseGrabberItemHasImplicitMouseGrab(false),
dragDropItem(0),
enterWidget(0),
lastDropAction(Qt::IgnoreAction),
- allItemsIgnoreHoverEvents(true),
- allItemsUseDefaultCursor(true),
- painterStateProtection(true),
- sortCacheEnabled(false),
- style(0),
- allItemsIgnoreTouchEvents(true)
+ style(0)
{
}
@@ -5116,9 +5116,15 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
// Process children.
if (itemHasChildren && item->d_ptr->dirtyChildren) {
+ const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
+ if (itemClipsChildrenToShape) {
+ // Make sure child updates are clipped to the item's bounding rect.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->setUpdateClip(item);
+ }
if (!dirtyAncestorContainsChildren) {
dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
- && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ && itemClipsChildrenToShape;
}
const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
@@ -5141,6 +5147,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
}
processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
}
+
+ if (itemClipsChildrenToShape) {
+ // Reset updateClip.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->setUpdateClip(0);
+ }
} else if (wasDirtyParentSceneTransform) {
item->d_ptr->invalidateChildrenSceneTransform();
}
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 0a85f0e..77bf450 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -97,24 +97,36 @@ public:
int lastItemCount;
QRectF sceneRect;
- bool hasSceneRect;
- bool dirtyGrowingItemsBoundingRect;
+
+ quint32 hasSceneRect : 1;
+ quint32 dirtyGrowingItemsBoundingRect : 1;
+ quint32 updateAll : 1;
+ quint32 calledEmitUpdated : 1;
+ quint32 processDirtyItemsEmitted : 1;
+ quint32 needSortTopLevelItems : 1;
+ quint32 holesInTopLevelSiblingIndex : 1;
+ quint32 topLevelSequentialOrdering : 1;
+ quint32 scenePosDescendantsUpdatePending : 1;
+ quint32 stickyFocus : 1;
+ quint32 hasFocus : 1;
+ quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1;
+ quint32 allItemsIgnoreHoverEvents : 1;
+ quint32 allItemsUseDefaultCursor : 1;
+ quint32 painterStateProtection : 1;
+ quint32 sortCacheEnabled : 1; // for compatibility
+ quint32 allItemsIgnoreTouchEvents : 1;
+ quint32 padding : 15;
+
QRectF growingItemsBoundingRect;
void _q_emitUpdated();
QList<QRectF> updatedRects;
- bool updateAll;
- bool calledEmitUpdated;
- bool processDirtyItemsEmitted;
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
QVector<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
- bool needSortTopLevelItems;
- bool holesInTopLevelSiblingIndex;
- bool topLevelSequentialOrdering;
QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
void registerTopLevelItem(QGraphicsItem *item);
@@ -125,7 +137,6 @@ public:
void _q_processDirtyItems();
QSet<QGraphicsItem *> scenePosItems;
- bool scenePosDescendantsUpdatePending;
void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
void registerScenePosItem(QGraphicsItem *item);
void unregisterScenePosItem(QGraphicsItem *item);
@@ -136,9 +147,6 @@ public:
QBrush backgroundBrush;
QBrush foregroundBrush;
- quint32 stickyFocus : 1;
- quint32 hasFocus : 1;
- quint32 padding : 30;
quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
@@ -155,7 +163,6 @@ public:
void removePopup(QGraphicsWidget *widget, bool itemIsDying = false);
QGraphicsItem *lastMouseGrabberItem;
- bool lastMouseGrabberItemHasImplicitMouseGrab;
QList<QGraphicsItem *> mouseGrabberItems;
void grabMouse(QGraphicsItem *item, bool implicit = false);
void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false);
@@ -172,8 +179,6 @@ public:
QList<QGraphicsItem *> cachedItemsUnderMouse;
QList<QGraphicsItem *> hoverItems;
QPointF lastSceneMousePos;
- bool allItemsIgnoreHoverEvents;
- bool allItemsUseDefaultCursor;
void enableMouseTrackingOnViews();
QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos;
QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos;
@@ -187,8 +192,6 @@ public:
void addView(QGraphicsView *view);
void removeView(QGraphicsView *view);
- bool painterStateProtection;
-
QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters;
void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
@@ -210,8 +213,6 @@ public:
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
- bool sortCacheEnabled; // for compatibility
-
void drawItemHelper(QGraphicsItem *item, QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget,
bool painterStateProtection);
@@ -295,7 +296,6 @@ public:
int findClosestTouchPointId(const QPointF &scenePos);
void touchEventHandler(QTouchEvent *touchEvent);
bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent);
- bool allItemsIgnoreTouchEvents;
void enableTouchEventsOnViews();
QList<QGraphicsObject *> cachedTargetItems;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 0bba7e9..0f951ef 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -327,16 +327,21 @@ QGraphicsViewPrivate::QGraphicsViewPrivate()
dragMode(QGraphicsView::NoDrag),
sceneInteractionAllowed(true), hasSceneRect(false),
connectedToScene(false),
- mousePressButton(Qt::NoButton),
+ useLastMouseEvent(false),
identityMatrix(true),
dirtyScroll(true),
accelerateScrolling(true),
+ keepLastCenterPoint(true),
+ transforming(false),
+ handScrolling(false),
+ mustAllocateStyleOptions(false),
+ mustResizeBackgroundPixmap(true),
+ fullUpdatePending(true),
+ hasUpdateClip(false),
+ mousePressButton(Qt::NoButton),
leftIndent(0), topIndent(0),
lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0),
- useLastMouseEvent(false),
- keepLastCenterPoint(true),
alignment(Qt::AlignCenter),
- transforming(false),
transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
optimizationFlags(0),
@@ -345,14 +350,11 @@ QGraphicsViewPrivate::QGraphicsViewPrivate()
rubberBanding(false),
rubberBandSelectionMode(Qt::IntersectsItemShape),
#endif
- handScrolling(false), handScrollMotions(0), cacheMode(0),
- mustAllocateStyleOptions(false),
- mustResizeBackgroundPixmap(true),
+ handScrollMotions(0), cacheMode(0),
#ifndef QT_NO_CURSOR
hasStoredOriginalCursor(false),
#endif
lastDragDropEvent(0),
- fullUpdatePending(true),
updateSceneSlotReimplementedChecked(false)
{
styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS);
@@ -879,6 +881,52 @@ static inline void QRect_unite(QRect *rect, const QRect &other)
}
}
+/*
+ Calling this function results in update rects being clipped to the item's
+ bounding rect. Note that updates prior to this function call is not clipped.
+ The clip is removed by passing 0.
+*/
+void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item)
+{
+ Q_Q(QGraphicsView);
+ // We simply ignore the request if the update mode is either FullViewportUpdate
+ // or NoViewportUpdate; in that case there's no point in clipping anything.
+ if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate
+ || viewportUpdateMode == QGraphicsView::FullViewportUpdate) {
+ hasUpdateClip = false;
+ return;
+ }
+
+ // Calculate the clip (item's bounding rect in view coordinates).
+ // Optimized version of:
+ // QRect clip = item->deviceTransform(q->viewportTransform())
+ // .mapRect(item->boundingRect()).toAlignedRect();
+ QRect clip;
+ if (item->d_ptr->itemIsUntransformable()) {
+ QTransform xform = item->deviceTransform(q->viewportTransform());
+ clip = xform.mapRect(item->boundingRect()).toAlignedRect();
+ } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) {
+ QRectF r(item->boundingRect());
+ r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
+ item->d_ptr->sceneTransform.dy() - verticalScroll());
+ clip = r.toAlignedRect();
+ } else if (!q->isTransformed()) {
+ clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
+ } else {
+ QTransform xform = item->d_ptr->sceneTransform;
+ xform *= q->viewportTransform();
+ clip = xform.mapRect(item->boundingRect()).toAlignedRect();
+ }
+
+ if (hasUpdateClip) {
+ // Intersect with old clip.
+ updateClip &= clip;
+ } else {
+ updateClip = clip;
+ hasUpdateClip = true;
+ }
+}
+
bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
{
if (rect.isEmpty())
@@ -909,6 +957,8 @@ bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xf
viewRect.adjust(-1, -1, 1, 1);
else
viewRect.adjust(-2, -2, 2, 2);
+ if (hasUpdateClip)
+ viewRect &= updateClip;
dirtyRegion += viewRect;
}
@@ -930,7 +980,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r)
viewport->update();
break;
case QGraphicsView::BoundingRectViewportUpdate:
- QRect_unite(&dirtyBoundingRect, r);
+ if (hasUpdateClip)
+ QRect_unite(&dirtyBoundingRect, r & updateClip);
+ else
+ QRect_unite(&dirtyBoundingRect, r);
if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
fullUpdatePending = true;
viewport->update();
@@ -938,7 +991,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r)
break;
case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
case QGraphicsView::MinimalViewportUpdate:
- dirtyRegion += r;
+ if (hasUpdateClip)
+ dirtyRegion += r & updateClip;
+ else
+ dirtyRegion += r;
break;
default:
break;
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index aeff28a..7bd9ecb 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -77,11 +77,25 @@ public:
QPainter::RenderHints renderHints;
QGraphicsView::DragMode dragMode;
- bool sceneInteractionAllowed;
+
+ quint32 sceneInteractionAllowed : 1;
+ quint32 hasSceneRect : 1;
+ quint32 connectedToScene : 1;
+ quint32 useLastMouseEvent : 1;
+ quint32 identityMatrix : 1;
+ quint32 dirtyScroll : 1;
+ quint32 accelerateScrolling : 1;
+ quint32 keepLastCenterPoint : 1;
+ quint32 transforming : 1;
+ quint32 handScrolling : 1;
+ quint32 mustAllocateStyleOptions : 1;
+ quint32 mustResizeBackgroundPixmap : 1;
+ quint32 fullUpdatePending : 1;
+ quint32 hasUpdateClip : 1;
+ quint32 padding : 18;
+
QRectF sceneRect;
- bool hasSceneRect;
void updateLastCenterPoint();
- bool connectedToScene;
qint64 horizontalScroll() const;
qint64 verticalScroll() const;
@@ -89,6 +103,7 @@ public:
QRectF mapRectToScene(const QRect &rect) const;
QRectF mapRectFromScene(const QRectF &rect) const;
+ QRect updateClip;
QPointF mousePressItemPoint;
QPointF mousePressScenePoint;
QPoint mousePressViewPoint;
@@ -98,26 +113,20 @@ public:
QPoint dirtyScrollOffset;
Qt::MouseButton mousePressButton;
QTransform matrix;
- bool identityMatrix;
qint64 scrollX, scrollY;
- bool dirtyScroll;
void updateScroll();
- bool accelerateScrolling;
qreal leftIndent;
qreal topIndent;
// Replaying mouse events
QMouseEvent lastMouseEvent;
- bool useLastMouseEvent;
void replayLastMouseEvent();
void storeMouseEvent(QMouseEvent *event);
void mouseMoveEventHandler(QMouseEvent *event);
QPointF lastCenterPoint;
- bool keepLastCenterPoint;
Qt::Alignment alignment;
- bool transforming;
QGraphicsView::ViewportAnchor transformationAnchor;
QGraphicsView::ViewportAnchor resizeAnchor;
@@ -131,20 +140,17 @@ public:
bool rubberBanding;
Qt::ItemSelectionMode rubberBandSelectionMode;
#endif
- bool handScrolling;
int handScrollMotions;
QGraphicsView::CacheMode cacheMode;
QVector<QStyleOptionGraphicsItem> styleOptions;
- bool mustAllocateStyleOptions;
QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems);
void freeStyleOptionsArray(QStyleOptionGraphicsItem *array);
QBrush backgroundBrush;
QBrush foregroundBrush;
QPixmap backgroundPixmap;
- bool mustResizeBackgroundPixmap;
QRegion backgroundPixmapExposed;
#ifndef QT_NO_CURSOR
@@ -161,7 +167,6 @@ public:
QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
- bool fullUpdatePending;
QRegion dirtyRegion;
QRect dirtyBoundingRect;
void processPendingUpdates();
@@ -192,6 +197,8 @@ public:
#endif
}
+ void setUpdateClip(QGraphicsItem *);
+
inline bool updateRectF(const QRectF &rect)
{
if (rect.isEmpty())
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index dce5c6a..b12cd45 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -1099,7 +1099,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
if (!source_top_left.isValid() || !source_bottom_right.isValid())
return;
QModelIndex source_parent = source_top_left.parent();
- IndexMap::const_iterator it = create_mapping(source_parent);
+ IndexMap::const_iterator it = source_index_mapping.find(source_parent);
if (it == source_index_mapping.constEnd()) {
// Don't care, since we don't have mapping for this index
return;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 60f38f2..0c22368 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -2535,7 +2535,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
Q_Q(QWidget);
QStyle *oldStyle = q->style();
#ifndef QT_NO_STYLE_STYLESHEET
- QStyle *origStyle = 0;
+ QWeakPointer<QStyle> origStyle;
#endif
#ifdef Q_WS_MAC
@@ -2549,7 +2549,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
- origStyle = extra->style;
+ origStyle = extra->style.data();
#endif
extra->style = newStyle;
}
@@ -2578,23 +2578,23 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
}
}
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(q, &e);
-#ifdef QT3_SUPPORT
- q->styleChange(*oldStyle);
-#endif
-
#ifndef QT_NO_STYLE_STYLESHEET
if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
- if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle)) {
+ if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
cssStyle->clearWidgetFont(q);
}
}
#endif
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(q, &e);
+#ifdef QT3_SUPPORT
+ q->styleChange(*oldStyle);
+#endif
+
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the old stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle))
+ if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
proxy->deref();
#endif
}
@@ -5583,52 +5583,23 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset = painterTransform.map(pixmapOffset);
}
-
QRect effectRect;
- if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
+ if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
-
- } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
+ else if (mode == QGraphicsEffect::PadToTransparentBorder)
effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect();
-
- } else {
+ else
effectRect = sourceRect.toAlignedRect();
- }
-
if (offset)
*offset = effectRect.topLeft();
- if (deviceCoordinates) {
- // Clip to device rect.
- int left, top, right, bottom;
- effectRect.getCoords(&left, &top, &right, &bottom);
- if (left < 0) {
- if (offset)
- offset->rx() += -left;
- effectRect.setX(0);
- }
- if (top < 0) {
- if (offset)
- offset->ry() += -top;
- effectRect.setY(0);
- }
- // NB! We use +-1 for historical reasons (see QRect documentation).
- QPaintDevice *device = context->painter->device();
- const int deviceWidth = device->width();
- const int deviceHeight = device->height();
- if (right + 1 > deviceWidth)
- effectRect.setRight(deviceWidth - 1);
- if (bottom + 1 > deviceHeight)
- effectRect.setBottom(deviceHeight -1);
- }
-
pixmapOffset -= effectRect.topLeft();
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
- m_widget->render(&pixmap, pixmapOffset);
+ m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
return pixmap;
}
#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 390fe51..a818978 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -125,7 +125,7 @@ protected:
};
-class QImageTextureGlyphCache : public QTextureGlyphCache
+class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
{
public:
QImageTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index f5b0b0c..e065bcc 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -97,6 +97,7 @@
#include <qdebug.h>
#include <qlibrary.h>
#include <qdatetimeedit.h>
+#include <qmath.h>
#include <QtGui/qgraphicsproxywidget.h>
#include <QtGui/qgraphicsview.h>
#include <private/qt_cocoa_helpers_mac_p.h>
@@ -2142,6 +2143,9 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
// The combo box popup has no frame.
if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
ret = 0;
+ // Frame of mac style line edits is two pixels on top and one on the bottom
+ else if (qobject_cast<const QLineEdit *>(widget) != 0)
+ ret = 2;
else
ret = 1;
break;
@@ -5437,14 +5441,12 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
CGFloat height;
QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
HIThemeGetTextDimensions(groupText, 0, &tti, &width, &height, 0);
- tw = int(width);
- h = int(height);
+ tw = qRound(width);
+ h = qCeil(height);
} else {
- QFontMetrics fm = groupBox->fontMetrics;
- if (!checkable && !fontIsSet)
- fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
- h = fm.height();
- tw = fm.size(Qt::TextShowMnemonic, groupBox->text).width();
+ QFontMetricsF fm = QFontMetricsF(groupBox->fontMetrics);
+ h = qCeil(fm.height());
+ tw = qCeil(fm.size(Qt::TextShowMnemonic, groupBox->text).width());
}
ret.setHeight(h);
@@ -5491,10 +5493,10 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
yOffset = 5;
if (hasNoText)
- yOffset = -fm.height();
+ yOffset = -qCeil(QFontMetricsF(fm).height());
}
- ret = opt->rect.adjusted(0, fm.height() + yOffset, 0, 0);
+ ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
if (sc == SC_GroupBoxContents)
ret.adjust(3, 3, -3, -4); // guess
}
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 5054b66..d92148f 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -389,7 +389,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine
mutable uint gridfitted : 1;
uint hasTrailingSpaces : 1;
uint leadingIncluded : 1;
- QFixed height() const { return ascent + descent + 1
+ QFixed height() const { return (ascent + descent).ceil() + 1
+ (leadingIncluded? qMax(QFixed(),leading) : QFixed()); }
QFixed base() const { return ascent
+ (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); }
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index ca58e6d..e0b09aa 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -56,6 +56,7 @@
#include <qscrollbar.h>
#include <qtreeview.h>
#include <qheaderview.h>
+#include <qmath.h>
#ifndef QT_NO_IM
#include "qinputcontext.h"
#endif
@@ -328,7 +329,7 @@ QSize QComboBoxPrivate::recomputeSizeHint(QSize &sh) const
// height
- sh.setHeight(qMax(fm.height(), 14) + 2);
+ sh.setHeight(qMax(qCeil(QFontMetricsF(fm).height()), 14) + 2);
if (hasIcon) {
sh.setHeight(qMax(sh.height(), iconSize.height() + 2));
}
diff --git a/src/gui/widgets/qcommandlinkbutton.cpp b/src/gui/widgets/qcommandlinkbutton.cpp
index 6919bc0..e8fe299 100644
--- a/src/gui/widgets/qcommandlinkbutton.cpp
+++ b/src/gui/widgets/qcommandlinkbutton.cpp
@@ -46,6 +46,7 @@
#include "qtextlayout.h"
#include "qcolor.h"
#include "qfont.h"
+#include <qmath.h>
#include "private/qpushbutton_p.h"
@@ -242,7 +243,7 @@ int QCommandLinkButtonPrivate::descriptionHeight(int widgetWidth) const
}
layout.endLayout();
}
- return qRound(descriptionheight);
+ return qCeil(descriptionheight);
}
/*!
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index 806654c..171000b 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -225,7 +225,7 @@ static const int zero = 0;
QDockAreaLayoutInfo::QDockAreaLayoutInfo()
: sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
#ifndef QT_NO_TABBAR
- , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false)
+ , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth)
#endif
{
}
@@ -235,7 +235,7 @@ QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPositio
QMainWindow *window)
: sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
#ifndef QT_NO_TABBAR
- , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)), tabBarVisible(false)
+ , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape))
#endif
{
#ifdef QT_NO_TABBAR
@@ -296,8 +296,8 @@ QSize QDockAreaLayoutInfo::minimumSize() const
rperp(o, result) = b;
#ifndef QT_NO_TABBAR
- if (tabbed) {
- QSize tbm = tabBarMinimumSize();
+ QSize tbm = tabBarMinimumSize();
+ if (!tbm.isNull()) {
switch (tabBarShape) {
case QTabBar::RoundedNorth:
case QTabBar::RoundedSouth:
@@ -369,8 +369,8 @@ QSize QDockAreaLayoutInfo::maximumSize() const
rperp(o, result) = b;
#ifndef QT_NO_TABBAR
- if (tabbed) {
- QSize tbh = tabBarSizeHint();
+ QSize tbh = tabBarSizeHint();
+ if (!tbh.isNull()) {
switch (tabBarShape) {
case QTabBar::RoundedNorth:
case QTabBar::RoundedSouth:
@@ -1500,7 +1500,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
QRect tab_rect;
QSize tbh = tabBarSizeHint();
- if (tabBarVisible) {
+ if (!tbh.isNull()) {
switch (tabBarShape) {
case QTabBar::RoundedNorth:
case QTabBar::TriangularNorth:
@@ -2079,10 +2079,11 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const
#endif //QT_NO_TABBAR
#ifndef QT_NO_TABBAR
-void QDockAreaLayoutInfo::updateTabBar() const
+//returns whether the tabbar is visible or not
+bool QDockAreaLayoutInfo::updateTabBar() const
{
if (!tabbed)
- return;
+ return false;
QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
@@ -2150,12 +2151,8 @@ void QDockAreaLayoutInfo::updateTabBar() const
tabBar->blockSignals(blocked);
- that->tabBarVisible = ( (gap ? 1 : 0) + tabBar->count()) > 1;
-
- if (changed || !tabBarMin.isValid() | !tabBarHint.isValid()) {
- that->tabBarMin = tabBar->minimumSizeHint();
- that->tabBarHint = tabBar->sizeHint();
- }
+ //returns if the tabbar is visible or not
+ return ( (gap ? 1 : 0) + tabBar->count()) > 1;
}
void QDockAreaLayoutInfo::setTabBarShape(int shape)
@@ -2163,11 +2160,8 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape)
if (shape == tabBarShape)
return;
tabBarShape = shape;
- if (tabBar != 0) {
+ if (tabBar != 0)
tabBar->setShape(static_cast<QTabBar::Shape>(shape));
- tabBarMin = QSize();
- tabBarHint = QSize();
- }
for (int i = 0; i < item_list.count(); ++i) {
QDockAreaLayoutItem &item = item_list[i];
@@ -2178,22 +2172,18 @@ void QDockAreaLayoutInfo::setTabBarShape(int shape)
QSize QDockAreaLayoutInfo::tabBarMinimumSize() const
{
- if (!tabbed)
+ if (!updateTabBar())
return QSize(0, 0);
- updateTabBar();
-
- return tabBarMin;
+ return tabBar->minimumSizeHint();
}
QSize QDockAreaLayoutInfo::tabBarSizeHint() const
{
- if (!tabbed)
+ if (!updateTabBar())
return QSize(0, 0);
- updateTabBar();
-
- return tabBarHint;
+ return tabBar->sizeHint();
}
QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const
@@ -2240,7 +2230,7 @@ QRect QDockAreaLayoutInfo::tabContentRect() const
QRect result = rect;
QSize tbh = tabBarSizeHint();
- if (tabBarVisible) {
+ if (!tbh.isNull()) {
switch (tabBarShape) {
case QTabBar::RoundedNorth:
case QTabBar::TriangularNorth:
diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h
index 0088f00..9cb77ba 100644
--- a/src/gui/widgets/qdockarealayout_p.h
+++ b/src/gui/widgets/qdockarealayout_p.h
@@ -208,11 +208,9 @@ public:
QRect tabContentRect() const;
bool tabbed;
QTabBar *tabBar;
- QSize tabBarMin, tabBarHint;
int tabBarShape;
- bool tabBarVisible;
- void updateTabBar() const;
+ bool updateTabBar() const;
void setTabBarShape(int shape);
QSize tabBarMinimumSize() const;
QSize tabBarSizeHint() const;
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
index 54189de..11f0a94 100644
--- a/src/gui/widgets/qdockwidget.cpp
+++ b/src/gui/widgets/qdockwidget.cpp
@@ -1269,12 +1269,11 @@ void QDockWidget::setFloating(bool floating)
QRect r = d->undockedGeometry;
d->setWindowState(floating, false, floating ? r : QRect());
+
if (floating && r.isNull()) {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
- QRect titleArea = layout->titleArea();
- int h = layout->verticalTitleBar ? titleArea.width() : titleArea.height();
- QPoint p = mapToGlobal(QPoint(h, h));
- move(p);
+ if (x() < 0 || y() < 0) //may happen if we have been hidden
+ move(QPoint());
+ setAttribute(Qt::WA_Moved, false); //we want it at the default position
}
}
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 994c1c9..452d37d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -42,6 +42,10 @@
#include "qtextureglyphcache_gl_p.h"
#include "qpaintengineex_opengl2_p.h"
+#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL)
+#include "private/qeglcontext_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN
@@ -49,12 +53,27 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif
QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
- : QTextureGlyphCache(type, matrix)
+ : QImageTextureGlyphCache(type, matrix)
, ctx(context)
, m_width(0)
, m_height(0)
+ , m_broken_fbo_readback(false)
{
- glGenFramebuffers(1, &m_fbo);
+ // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where
+ // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The
+ // workaround is to use a system-memory copy of the glyph cache for this device.
+ // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and
+ // be slower, so that is not desireable.
+#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL)
+ if (QByteArray((char*) glGetString(GL_RENDERER)).contains("SGX")) {
+ QGLContextPrivate *ctxd = context->d_func();
+ m_broken_fbo_readback = QByteArray((char *) eglQueryString(ctxd->eglContext->display(), EGL_VERSION)).contains("1.3");
+ }
+#endif
+
+ if (!m_broken_fbo_readback)
+ glGenFramebuffers(1, &m_fbo);
+
connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
SLOT(contextDestroyed(const QGLContext*)));
}
@@ -63,7 +82,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache()
{
if (ctx) {
QGLShareContextScope scope(ctx);
- glDeleteFramebuffers(1, &m_fbo);
+
+ if (!m_broken_fbo_readback)
+ glDeleteFramebuffers(1, &m_fbo);
if (m_width || m_height)
glDeleteTextures(1, &m_texture);
@@ -72,6 +93,12 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache()
void QGLTextureGlyphCache::createTextureData(int width, int height)
{
+ // create in QImageTextureGlyphCache baseclass is meant to be called
+ // only to create the initial image and does not preserve the content,
+ // so we don't call when this function is called from resize.
+ if (m_broken_fbo_readback && image().isNull())
+ QImageTextureGlyphCache::createTextureData(width, height);
+
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
@@ -93,14 +120,22 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
- // ### the QTextureGlyphCache API needs to be reworked to allow
- // ### resizeTextureData to fail
-
int oldWidth = m_width;
int oldHeight = m_height;
GLuint oldTexture = m_texture;
createTextureData(width, height);
+
+ if (m_broken_fbo_readback) {
+ QImageTextureGlyphCache::resizeTextureData(width, height);
+ Q_ASSERT(image().depth() == 8);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
+ glDeleteTextures(1, &oldTexture);
+ return;
+ }
+
+ // ### the QTextureGlyphCache API needs to be reworked to allow
+ // ### resizeTextureData to fail
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
@@ -159,20 +194,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glBindTexture(GL_TEXTURE_2D, m_texture);
-#ifdef QT_OPENGL_ES_2
- QDataBuffer<uchar> buffer(4*oldWidth*oldHeight);
- buffer.resize(4*oldWidth*oldHeight);
- glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
-
- // do an in-place conversion from GL_RGBA to GL_ALPHA
- for (int i=0; i<oldWidth*oldHeight; ++i)
- buffer.data()[i] = buffer.at(4*i + 3);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight,
- GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data());
-#else
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
-#endif
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_RENDERBUFFER_EXT, 0);
@@ -187,6 +209,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
{
+ if (m_broken_fbo_readback) {
+ QImageTextureGlyphCache::fillTexture(c, glyph);
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ const QImage &texture = image();
+ const uchar *bits = texture.constBits();
+ bits += c.y * texture.bytesPerLine() + c.x;
+ for (int i=0; i<c.h; ++i) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
+ bits += texture.bytesPerLine();
+ }
+
+ return;
+ }
+
QImage mask = textureMapForGlyph(glyph);
const int maskWidth = mask.width();
const int maskHeight = mask.height();
@@ -235,17 +272,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
}
}
-int QGLTextureGlyphCache::glyphMargin() const
-{
-#if defined(Q_WS_MAC)
- return 2;
-#elif defined (Q_WS_X11)
- return 0;
-#else
- return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
-#endif
-}
-
int QGLTextureGlyphCache::glyphPadding() const
{
return 1;
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 75c2bb1..efb7435 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QTextureGlyphCache
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache
{
Q_OBJECT
public:
@@ -72,7 +72,6 @@ public:
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
virtual void fillTexture(const Coord &c, glyph_t glyph);
- virtual int glyphMargin() const;
virtual int glyphPadding() const;
inline GLuint texture() const { return m_texture; }
@@ -116,6 +115,8 @@ private:
int m_height;
QGLShaderProgram *m_program;
+
+ bool m_broken_fbo_readback;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index cfacf26..a3c1bac 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2773,23 +2773,27 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
/*!
\since 4.4
- Draws the given texture, \a textureId, to the given target rectangle,
- \a target, in OpenGL model space. The \a textureTarget should be a 2D
- texture target.
+ This function supports the following use cases:
+
+ \list
+ \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId,
+ to the given target rectangle, \a target, in OpenGL model space. The
+ \a textureTarget should be a 2D texture target.
+ \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a
+ beginNativePainting / endNativePainting block, and uses the
+ engine with type QPaintEngine::OpenGL2, the function will draw the given
+ texture, \a textureId, to the given target rectangle, \a target,
+ respecting the current painter state. This will let you draw a texture
+ with the clip, transform, render hints, and composition mode set by the
+ painter. Note that the texture target needs to be GL_TEXTURE_2D for this
+ use case, and that this is the only supported use case under OpenGL ES 2.x.
+ \endlist
- \note This function is not supported under OpenGL/ES 2.0.
*/
void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
-#ifndef QT_OPENGL_ES_2
-#ifdef QT_OPENGL_ES
- if (textureTarget != GL_TEXTURE_2D) {
- qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
- return;
- }
-#else
-
- if (d_ptr->active_engine &&
+#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
+ if (d_ptr->active_engine &&
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
if (!eng->isNativePaintingActive()) {
@@ -2799,7 +2803,15 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
return;
}
}
+#endif
+#ifndef QT_OPENGL_ES_2
+#ifdef QT_OPENGL_ES
+ if (textureTarget != GL_TEXTURE_2D) {
+ qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
+ return;
+ }
+#else
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
GLint oldTexture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
@@ -2821,7 +2833,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
Q_UNUSED(target);
Q_UNUSED(textureId);
Q_UNUSED(textureTarget);
- qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");
+ qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
#endif
}
@@ -2836,14 +2848,26 @@ void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, Q
/*!
\since 4.4
- Draws the given texture at the given \a point in OpenGL model
- space. The \a textureTarget should be a 2D texture target.
+ This function supports the following use cases:
+
+ \list
+ \i By default it draws the given texture, \a textureId,
+ at the given \a point in OpenGL model space. The
+ \a textureTarget should be a 2D texture target.
+ \i If a painter is active, not inside a
+ beginNativePainting / endNativePainting block, and uses the
+ engine with type QPaintEngine::OpenGL2, the function will draw the given
+ texture, \a textureId, at the given \a point,
+ respecting the current painter state. This will let you draw a texture
+ with the clip, transform, render hints, and composition mode set by the
+ painter. Note that the texture target needs to be GL_TEXTURE_2D for this
+ use case.
+ \endlist
- \note This function is not supported under OpenGL/ES.
+ \note This function is not supported under any version of OpenGL ES.
*/
void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
- // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that
#ifdef QT_OPENGL_ES
Q_UNUSED(point);
Q_UNUSED(textureId);
@@ -4911,11 +4935,8 @@ void QGLWidget::deleteTexture(QMacCompatGLuint id)
/*!
\since 4.4
- Draws the given texture, \a textureId to the given target rectangle,
- \a target, in OpenGL model space. The \a textureTarget should be a 2D
- texture target.
-
- Equivalent to the corresponding QGLContext::drawTexture().
+ Calls the corresponding QGLContext::drawTexture() on
+ this widget's context.
*/
void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
@@ -4935,10 +4956,8 @@ void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QM
/*!
\since 4.4
- Draws the given texture, \a textureId, at the given \a point in OpenGL
- model space. The \a textureTarget should be a 2D texture target.
-
- Equivalent to the corresponding QGLContext::drawTexture().
+ Calls the corresponding QGLContext::drawTexture() on
+ this widget's context.
*/
void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
diff --git a/src/plugins/imageformats/svg/qsvgiohandler.cpp b/src/plugins/imageformats/svg/qsvgiohandler.cpp
index 8155569..7b8463d 100644
--- a/src/plugins/imageformats/svg/qsvgiohandler.cpp
+++ b/src/plugins/imageformats/svg/qsvgiohandler.cpp
@@ -82,15 +82,19 @@ bool QSvgIOHandlerPrivate::load(QIODevice *device)
if (q->format().isEmpty())
q->canRead();
+ // # The SVG renderer doesn't handle trailing, unrelated data, so we must
+ // assume that all available data in the device is to be read.
bool res = false;
QBuffer *buf = qobject_cast<QBuffer *>(device);
if (buf) {
- res = r.load(buf->data());
+ const QByteArray &ba = buf->data();
+ res = r.load(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos()));
+ buf->seek(ba.size());
} else if (q->format() == "svgz") {
- res = r.load(device->readAll()); // ### can't stream svgz
+ res = r.load(device->readAll());
} else {
xmlReader.setDevice(device);
- res = r.load(&xmlReader); //### doesn't leave pos() correctly
+ res = r.load(&xmlReader);
}
if (res) {