summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-05-12 17:42:55 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-05-12 17:42:55 (GMT)
commit161e4c77b35a7cc4dda5b83b212fedaa02c46cdf (patch)
tree3728674860306f7a1ae0c4e75f35352af5f49ca9 /src
parent47760d59d57f548d5816ae43e456c86e01146491 (diff)
parent770a2428357f030d4efad8c64ceb381ce50c9fb9 (diff)
downloadQt-161e4c77b35a7cc4dda5b83b212fedaa02c46cdf.zip
Qt-161e4c77b35a7cc4dda5b83b212fedaa02c46cdf.tar.gz
Qt-161e4c77b35a7cc4dda5b83b212fedaa02c46cdf.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: (33 commits) Compile fix on Windows. Remove an unnecessary assert. Documentation for the Pad Navigator Example. New Pad Nagivator example implementation. Skip definition of wintab functions in case of QT_NO_TABLETEVENT. Made curve tesselation be dynamically adjusted based on transform. Modified QPainter and QPixmap benchmarks to use raster pixmaps. Stabilize tst_QWidgetAction::visibilityUpdate Fix compiler warning in QT_REQUIRE_VERSION 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. ...
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/dialogs/qmessagebox.h2
-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/kernel/qwidget_win.cpp5
-rw-r--r--src/gui/kernel/qwidget_wince.cpp2
-rw-r--r--src/gui/painting/qbezier.cpp228
-rw-r--r--src/gui/painting/qbezier_p.h7
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qstroker.cpp23
-rw-r--r--src/gui/painting/qstroker_p.h18
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h2
-rw-r--r--src/gui/painting/qtransform.cpp9
-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.cpp76
-rw-r--r--src/opengl/qpaintengine_opengl.cpp2
-rw-r--r--src/plugins/imageformats/svg/qsvgiohandler.cpp10
-rw-r--r--src/s60installs/bwins/QtGuiu.def4
-rw-r--r--src/s60installs/eabi/QtGuiu.def4
37 files changed, 394 insertions, 463 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/dialogs/qmessagebox.h b/src/gui/dialogs/qmessagebox.h
index bc6170d..f1ff6cc 100644
--- a/src/gui/dialogs/qmessagebox.h
+++ b/src/gui/dialogs/qmessagebox.h
@@ -354,7 +354,7 @@ if (!qApp){ \
QString s = QApplication::tr("Executable '%1' requires Qt "\
"%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
-"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal(s.toLatin1().data()); }}
+"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal("%s", s.toLatin1().data()); }}
#endif // QT_NO_MESSAGEBOX
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/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 7d647b7..c2a24fe 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -123,9 +123,11 @@ static PtrWTClose ptrWTClose = 0;
static PtrWTInfo ptrWTInfo = 0;
static PtrWTQueueSizeGet ptrWTQueueSizeGet = 0;
static PtrWTQueueSizeSet ptrWTQueueSizeSet = 0;
+#ifndef QT_NO_TABLETEVENT
static void init_wintab_functions();
static void qt_tablet_init();
static void qt_tablet_cleanup();
+#endif // QT_NO_TABLETEVENT
extern HCTX qt_tablet_context;
extern bool qt_tablet_tilt_support;
@@ -136,6 +138,8 @@ QWidget* qt_get_tablet_widget()
}
extern bool qt_is_gui_used;
+
+#ifndef QT_NO_TABLETEVENT
static void init_wintab_functions()
{
#if defined(Q_OS_WINCE)
@@ -227,6 +231,7 @@ static void qt_tablet_cleanup()
delete qt_tablet_widget;
qt_tablet_widget = 0;
}
+#endif // QT_NO_TABLETEVENT
const QString qt_reg_winclass(QWidget *w); // defined in qapplication_win.cpp
diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp
index 509847b..9c2c8c7 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/gui/kernel/qwidget_wince.cpp
@@ -63,6 +63,7 @@ typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
typedef int (API *PtrWTQueueSizeGet)(HCTX);
typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
+#ifndef QT_NO_TABLETEVENT
static void qt_tablet_init_wce();
static void qt_tablet_cleanup_wce();
@@ -135,6 +136,7 @@ static void qt_tablet_cleanup_wce() {
delete qt_tablet_widget;
qt_tablet_widget = 0;
}
+#endif // QT_NO_TABLETEVENT
// The internal qWinRequestConfig, defined in qapplication_win.cpp, stores move,
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index 7ff2a37..2a9b31a 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -93,7 +93,7 @@ QBezier QBezier::fromPoints(const QPointF &p1, const QPointF &p2,
/*!
\internal
*/
-QPolygonF QBezier::toPolygon() const
+QPolygonF QBezier::toPolygon(qreal bezier_flattening_threshold) const
{
// flattening is done by splitting the bezier until we can replace the segment by a straight
// line. We split further until the control points are close enough to the line connecting the
@@ -108,7 +108,7 @@ QPolygonF QBezier::toPolygon() const
QPolygonF polygon;
polygon.append(QPointF(x1, y1));
- addToPolygon(&polygon);
+ addToPolygon(&polygon, bezier_flattening_threshold);
return polygon;
}
@@ -117,34 +117,6 @@ QBezier QBezier::mapBy(const QTransform &transform) const
return QBezier::fromPoints(transform.map(pt1()), transform.map(pt2()), transform.map(pt3()), transform.map(pt4()));
}
-//0.05 is really low, but required for scaled-up beziers...
-static const qreal flatness = 0.05;
-
-//based on "Fast, precise flattening of cubic Bezier path and offset curves"
-// by T. F. Hain, A. L. Ahmad, S. V. R. Racherla and D. D. Langan
-static inline void flattenBezierWithoutInflections(QBezier &bez,
- QPolygonF *&p)
-{
- QBezier left;
-
- while (1) {
- qreal dx = bez.x2 - bez.x1;
- qreal dy = bez.y2 - bez.y1;
-
- qreal normalized = qSqrt(dx * dx + dy * dy);
- if (qFuzzyIsNull(normalized))
- break;
-
- qreal d = qAbs(dx * (bez.y3 - bez.y2) - dy * (bez.x3 - bez.x2));
-
- qreal t = qSqrt(4. / 3. * normalized * flatness / d);
- if (t > 1 || qFuzzyIsNull(t - (qreal)1.))
- break;
- bez.parameterSplitLeft(t, &left);
- p->append(bez.pt1());
- }
-}
-
QBezier QBezier::getSubRange(qreal t0, qreal t1) const
{
QBezier result;
@@ -223,7 +195,7 @@ static inline bool findInflections(qreal a, qreal b, qreal c,
}
-void QBezier::addToPolygon(QPolygonF *polygon) const
+void QBezier::addToPolygon(QPolygonF *polygon, qreal bezier_flattening_threshold) const
{
QBezier beziers[32];
beziers[0] = *this;
@@ -243,7 +215,7 @@ void QBezier::addToPolygon(QPolygonF *polygon) const
qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
l = 1.;
}
- if (d < flatness*l || b == beziers + 31) {
+ if (d < bezier_flattening_threshold*l || b == beziers + 31) {
// good enough, we pop it off and add the endpoint
polygon->append(QPointF(b->x4, b->y4));
--b;
@@ -255,55 +227,6 @@ void QBezier::addToPolygon(QPolygonF *polygon) const
}
}
-void QBezier::addToPolygonMixed(QPolygonF *polygon) const
-{
- qreal ax = -x1 + 3*x2 - 3*x3 + x4;
- qreal ay = -y1 + 3*y2 - 3*y3 + y4;
- qreal bx = 3*x1 - 6*x2 + 3*x3;
- qreal by = 3*y1 - 6*y2 + 3*y3;
- qreal cx = -3*x1 + 3*x2;
- qreal cy = -3*y1 + 2*y2;
- qreal a = 6 * (ay * bx - ax * by);
- qreal b = 6 * (ay * cx - ax * cy);
- qreal c = 2 * (by * cx - bx * cy);
-
- if ((qFuzzyIsNull(a) && qFuzzyIsNull(b)) ||
- (b * b - 4 * a *c) < 0) {
- QBezier bez(*this);
- flattenBezierWithoutInflections(bez, polygon);
- polygon->append(QPointF(x4, y4));
- } else {
- QBezier beziers[32];
- beziers[0] = *this;
- QBezier *b = beziers;
-
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal y4y1 = b->y4 - b->y1;
- qreal x4x1 = b->x4 - b->x1;
- qreal l = qAbs(x4x1) + qAbs(y4y1);
- qreal d;
- if (l > 1.) {
- d = qAbs( (x4x1)*(b->y1 - b->y2) - (y4y1)*(b->x1 - b->x2) )
- + qAbs( (x4x1)*(b->y1 - b->y3) - (y4y1)*(b->x1 - b->x3) );
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- l = 1.;
- }
- if (d < .5*l || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- polygon->append(QPointF(b->x4, b->y4));
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- }
-}
-
QRectF QBezier::bounds() const
{
qreal xmin = x1;
@@ -824,147 +747,4 @@ QBezier QBezier::bezierOnInterval(qreal t0, qreal t1) const
return result;
}
-
-static inline void bindInflectionPoint(const QBezier &bez, const qreal t,
- qreal *tMinus , qreal *tPlus)
-{
- if (t <= 0) {
- *tMinus = *tPlus = -1;
- return;
- } else if (t >= 1) {
- *tMinus = *tPlus = 2;
- return;
- }
-
- QBezier left, right;
- splitBezierAt(bez, t, &left, &right);
-
- qreal ax = -right.x1 + 3*right.x2 - 3*right.x3 + right.x4;
- qreal ay = -right.y1 + 3*right.y2 - 3*right.y3 + right.y4;
- qreal ex = 3 * (right.x2 - right.x3);
- qreal ey = 3 * (right.y2 - right.y3);
-
- qreal s4 = qAbs(6 * (ey * ax - ex * ay) / qSqrt(ex * ex + ey * ey)) + 0.00001f;
- qreal tf = qPow(qreal(9 * flatness / s4), qreal(1./3.));
- *tMinus = t - (1 - t) * tf;
- *tPlus = t + (1 - t) * tf;
-}
-
-void QBezier::addToPolygonIterative(QPolygonF *p) const
-{
- qreal t1, t2, tcusp;
- qreal t1min, t1plus, t2min, t2plus;
-
- qreal ax = -x1 + 3*x2 - 3*x3 + x4;
- qreal ay = -y1 + 3*y2 - 3*y3 + y4;
- qreal bx = 3*x1 - 6*x2 + 3*x3;
- qreal by = 3*y1 - 6*y2 + 3*y3;
- qreal cx = -3*x1 + 3*x2;
- qreal cy = -3*y1 + 2*y2;
-
- if (findInflections(6 * (ay * bx - ax * by),
- 6 * (ay * cx - ax * cy),
- 2 * (by * cx - bx * cy),
- &t1, &t2, &tcusp)) {
- bindInflectionPoint(*this, t1, &t1min, &t1plus);
- bindInflectionPoint(*this, t2, &t2min, &t2plus);
-
- QBezier tmpBez = *this;
- QBezier left, right, bez1, bez2, bez3;
- if (t1min > 0) {
- if (t1min >= 1) {
- flattenBezierWithoutInflections(tmpBez, p);
- } else {
- splitBezierAt(tmpBez, t1min, &left, &right);
- flattenBezierWithoutInflections(left, p);
- p->append(tmpBez.pointAt(t1min));
-
- if (t2min < t1plus) {
- if (tcusp < 1) {
- p->append(tmpBez.pointAt(tcusp));
- }
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &right);
- flattenBezierWithoutInflections(right, p);
- }
- } else if (t1plus < 1) {
- if (t2min < 1) {
- splitBezierAt(tmpBez, t2min, &bez3, &right);
- splitBezierAt(bez3, t1plus, &left, &bez2);
-
- flattenBezierWithoutInflections(bez2, p);
- p->append(tmpBez.pointAt(t2min));
-
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- } else {
- splitBezierAt(tmpBez, t1plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- }
- }
- } else if (t1plus > 0) {
- p->append(QPointF(x1, y1));
- if (t2min < t1plus) {
- if (tcusp < 1) {
- p->append(tmpBez.pointAt(tcusp));
- }
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- } else if (t1plus < 1) {
- if (t2min < 1) {
- splitBezierAt(tmpBez, t2min, &bez3, &right);
- splitBezierAt(bez3, t1plus, &left, &bez2);
-
- flattenBezierWithoutInflections(bez2, p);
-
- p->append(tmpBez.pointAt(t2min));
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- } else {
- splitBezierAt(tmpBez, t1plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- }
- } else if (t2min > 0) {
- if (t2min < 1) {
- splitBezierAt(tmpBez, t2min, &bez1, &right);
- flattenBezierWithoutInflections(bez1, p);
- p->append(tmpBez.pointAt(t2min));
-
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- } else {
- //### in here we should check whether the area of the
- // triangle formed between pt1/pt2/pt3 is smaller
- // or equal to 0 and then do iterative flattening
- // if not we should fallback and do the recursive
- // flattening.
- flattenBezierWithoutInflections(tmpBez, p);
- }
- } else if (t2plus > 0) {
- p->append(QPointF(x1, y1));
- if (t2plus < 1) {
- splitBezierAt(tmpBez, t2plus, &left, &bez2);
- flattenBezierWithoutInflections(bez2, p);
- }
- } else {
- flattenBezierWithoutInflections(tmpBez, p);
- }
- } else {
- QBezier bez = *this;
- flattenBezierWithoutInflections(bez, p);
- }
-
- p->append(QPointF(x4, y4));
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index 846635f..18ec116 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -79,10 +79,9 @@ public:
inline QPointF derivedAt(qreal t) const;
inline QPointF secondDerivedAt(qreal t) const;
- QPolygonF toPolygon() const;
- void addToPolygon(QPolygonF *p) const;
- void addToPolygonIterative(QPolygonF *p) const;
- void addToPolygonMixed(QPolygonF *p) const;
+ QPolygonF toPolygon(qreal bezier_flattening_threshold = 0.5) const;
+ void addToPolygon(QPolygonF *p, qreal bezier_flattening_threshold = 0.5) const;
+
QRectF bounds() const;
qreal length(qreal error = 0.01) const;
void addIfClose(qreal *length, qreal error) const;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index fda937e..ff82d59 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -461,6 +461,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
// change the current transform. Normal transformed,
// non-cosmetic pens will be transformed as part of fill
// later, so they are also covered here..
+ d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
d->activeStroker->begin(d->strokeHandler);
if (types) {
while (points < lastPoint) {
@@ -518,6 +519,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
} else {
+ d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
d->activeStroker->begin(d->strokeHandler);
if (types) {
while (points < lastPoint) {
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 9b8e099..eabbd8a 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -120,8 +120,8 @@ private:
class QSubpathFlatIterator
{
public:
- QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path)
- : m_path(path), m_pos(0), m_curve_index(-1) { }
+ QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path, qreal threshold)
+ : m_path(path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { }
inline bool hasNext() const { return m_curve_index >= 0 || m_pos < m_path->size(); }
@@ -152,7 +152,7 @@ public:
QPointF(qt_fixed_to_real(m_path->at(m_pos+1).x),
qt_fixed_to_real(m_path->at(m_pos+1).y)),
QPointF(qt_fixed_to_real(m_path->at(m_pos+2).x),
- qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon();
+ qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon(m_curve_threshold);
m_curve_index = 1;
e.type = QPainterPath::LineToElement;
e.x = m_curve.at(0).x();
@@ -169,6 +169,7 @@ private:
int m_pos;
QPolygonF m_curve;
int m_curve_index;
+ qreal m_curve_threshold;
};
template <class Iterator> bool qt_stroke_side(Iterator *it, QStroker *stroker,
@@ -187,7 +188,12 @@ static inline qreal adapted_angle_on_x(const QLineF &line)
}
QStrokerOps::QStrokerOps()
- : m_elements(0), m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0)
+ : m_elements(0)
+ , m_curveThreshold(qt_real_to_fixed(0.25))
+ , m_customData(0)
+ , m_moveTo(0)
+ , m_lineTo(0)
+ , m_cubicTo(0)
{
}
@@ -195,7 +201,6 @@ QStrokerOps::~QStrokerOps()
{
}
-
/*!
Prepares the stroker. Call this function once before starting a
stroke by calling moveTo, lineTo or cubicTo.
@@ -238,6 +243,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q
if (path.isEmpty())
return;
+ setCurveThresholdFromTransform(matrix);
begin(customData);
int count = path.elementCount();
if (matrix.isIdentity()) {
@@ -308,6 +314,8 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl
{
if (!pointCount)
return;
+
+ setCurveThresholdFromTransform(matrix);
begin(data);
if (matrix.isIdentity()) {
moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y()));
@@ -348,6 +356,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform
}
}
+ setCurveThresholdFromTransform(matrix);
begin(data);
moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y()));
for (int i=0; i<12; i+=3) {
@@ -366,12 +375,10 @@ QStroker::QStroker()
{
m_strokeWidth = qt_real_to_fixed(1);
m_miterLimit = qt_real_to_fixed(2);
- m_curveThreshold = qt_real_to_fixed(0.25);
}
QStroker::~QStroker()
{
-
}
Qt::PenCapStyle QStroker::capForJoinMode(LineJoinMode mode)
@@ -1135,7 +1142,7 @@ void QDashStroker::processCurrentSubpath()
QPainterPath dashPath;
- QSubpathFlatIterator it(&m_elements);
+ QSubpathFlatIterator it(&m_elements, m_curveThreshold);
qfixed2d prev = it.next();
bool clipping = !m_clip_rect.isEmpty();
diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h
index 3e622a8..d646135 100644
--- a/src/gui/painting/qstroker_p.h
+++ b/src/gui/painting/qstroker_p.h
@@ -124,6 +124,9 @@ typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
qfixed ex, qfixed ey,
void *data);
+// qtransform.cpp
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+
class Q_GUI_EXPORT QStrokerOps
{
public:
@@ -161,6 +164,16 @@ public:
QRectF clipRect() const { return m_clip_rect; }
void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
+ void setCurveThresholdFromTransform(const QTransform &transform)
+ {
+ qreal scale;
+ qt_scaleForTransform(transform, &scale);
+ setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale));
+ }
+
+ void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
+ qfixed curveThreshold() const { return m_curveThreshold; }
+
protected:
inline void emitMoveTo(qfixed x, qfixed y);
inline void emitLineTo(qfixed x, qfixed y);
@@ -170,6 +183,7 @@ protected:
QDataBuffer<Element> m_elements;
QRectF m_clip_rect;
+ qfixed m_curveThreshold;
void *m_customData;
qStrokerMoveToHook m_moveTo;
@@ -208,9 +222,6 @@ public:
void setMiterLimit(qfixed length) { m_miterLimit = length; }
qfixed miterLimit() const { return m_miterLimit; }
- void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
- qfixed curveThreshold() const { return m_curveThreshold; }
-
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
inline void emitMoveTo(qfixed x, qfixed y);
inline void emitLineTo(qfixed x, qfixed y);
@@ -227,7 +238,6 @@ protected:
qfixed m_strokeWidth;
qfixed m_miterLimit;
- qfixed m_curveThreshold;
LineJoinMode m_capStyle;
LineJoinMode m_joinStyle;
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/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 80b7520..aaa241f 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1545,12 +1545,19 @@ static inline bool lineTo_clipped(QPainterPath &path, const QTransform &transfor
return true;
}
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo)
{
// Convert projective xformed curves to line
// segments so they can be transformed more accurately
- QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon();
+
+ qreal scale;
+ qt_scaleForTransform(transform, &scale);
+
+ qreal curveThreshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale);
+
+ QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(curveThreshold);
for (int i = 0; i < segment.size() - 1; ++i)
if (lineTo_clipped(path, transform, segment.at(i), segment.at(i+1), needsMoveTo))
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..7c457de 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1723,7 +1723,6 @@ QGLTextureCache::QGLTextureCache()
QGLTextureCache::~QGLTextureCache()
{
- Q_ASSERT(size() == 0);
QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
@@ -2773,23 +2772,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 +2802,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 +2832,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 +2847,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);
@@ -2864,7 +2887,7 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
- if (d_ptr->active_engine &&
+ if (d_ptr->active_engine &&
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
if (!eng->isNativePaintingActive()) {
@@ -4911,11 +4934,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 +4955,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/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index d2b0d4f..08a50cb 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -3950,7 +3950,7 @@ void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path)
enableClipping();
}
-extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_cache)
{
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) {
diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def
index e574c31..8ae3b9d 100644
--- a/src/s60installs/bwins/QtGuiu.def
+++ b/src/s60installs/bwins/QtGuiu.def
@@ -2126,8 +2126,8 @@ EXPORTS
?addToGroup@QGraphicsItemGroup@@QAEXPAVQGraphicsItem@@@Z @ 2125 NONAME ; void QGraphicsItemGroup::addToGroup(class QGraphicsItem *)
?addToIndex@QGraphicsItem@@IAEXXZ @ 2126 NONAME ; void QGraphicsItem::addToIndex(void)
?addToPolygon@QBezier@@QBEXPAVQPolygonF@@@Z @ 2127 NONAME ; void QBezier::addToPolygon(class QPolygonF *) const
- ?addToPolygonIterative@QBezier@@QBEXPAVQPolygonF@@@Z @ 2128 NONAME ; void QBezier::addToPolygonIterative(class QPolygonF *) const
- ?addToPolygonMixed@QBezier@@QBEXPAVQPolygonF@@@Z @ 2129 NONAME ; void QBezier::addToPolygonMixed(class QPolygonF *) const
+ ?addToPolygonIterative@QBezier@@QBEXPAVQPolygonF@@@Z @ 2128 NONAME ABSENT ; void QBezier::addToPolygonIterative(class QPolygonF *) const
+ ?addToPolygonMixed@QBezier@@QBEXPAVQPolygonF@@@Z @ 2129 NONAME ABSENT ; void QBezier::addToPolygonMixed(class QPolygonF *) const
?addToolBar@QMainWindow@@QAEPAVQToolBar@@ABVQString@@@Z @ 2130 NONAME ; class QToolBar * QMainWindow::addToolBar(class QString const &)
?addToolBar@QMainWindow@@QAEXPAVQToolBar@@@Z @ 2131 NONAME ; void QMainWindow::addToolBar(class QToolBar *)
?addToolBar@QMainWindow@@QAEXW4ToolBarArea@Qt@@PAVQToolBar@@@Z @ 2132 NONAME ; void QMainWindow::addToolBar(enum Qt::ToolBarArea, class QToolBar *)
diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def
index 8987470..02b74ee 100644
--- a/src/s60installs/eabi/QtGuiu.def
+++ b/src/s60installs/eabi/QtGuiu.def
@@ -9901,9 +9901,9 @@ EXPORTS
_ZNK7QBezier10addIfCloseEPff @ 9900 NONAME
_ZNK7QBezier12addToPolygonEP9QPolygonF @ 9901 NONAME
_ZNK7QBezier16bezierOnIntervalEff @ 9902 NONAME
- _ZNK7QBezier17addToPolygonMixedEP9QPolygonF @ 9903 NONAME
+ _ZNK7QBezier17addToPolygonMixedEP9QPolygonF @ 9903 NONAME ABSENT
_ZNK7QBezier17stationaryYPointsERfS0_ @ 9904 NONAME
- _ZNK7QBezier21addToPolygonIterativeEP9QPolygonF @ 9905 NONAME
+ _ZNK7QBezier21addToPolygonIterativeEP9QPolygonF @ 9905 NONAME ABSENT
_ZNK7QBezier5tForYEfff @ 9906 NONAME
_ZNK7QBezier6boundsEv @ 9907 NONAME
_ZNK7QBezier6lengthEf @ 9908 NONAME