summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/corelib.pro5
-rw-r--r--src/corelib/kernel/qmetaobject.cpp5
-rw-r--r--src/corelib/tools/qsharedpointer.cpp4
-rw-r--r--src/corelib/tools/qsimd_p.h4
-rw-r--r--src/corelib/tools/qstring.cpp13
-rw-r--r--src/dbus/qdbusconnection.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp6
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp6
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp13
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.cpp8
-rw-r--r--src/declarative/qml/qdeclarativelist.h8
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h4
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp2
-rw-r--r--src/declarative/util/qdeclarativetransition.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp18
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem.cpp51
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicstransform.cpp21
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp266
-rw-r--r--src/gui/graphicsview/qgridlayoutengine_p.h23
-rw-r--r--src/gui/gui.pro19
-rw-r--r--src/gui/image/image.pri1
-rw-r--r--src/gui/image/qimage.cpp8
-rw-r--r--src/gui/image/qimage_neon.cpp114
-rw-r--r--src/gui/image/qjpeghandler.cpp11
-rw-r--r--src/gui/kernel/qevent.cpp5
-rw-r--r--src/gui/kernel/qgesture.cpp28
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp3
-rw-r--r--src/gui/painting/painting.pri21
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp14
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h8
-rw-r--r--src/gui/painting/qpainter.cpp84
-rw-r--r--src/gui/text/qstatictext.cpp16
-rw-r--r--src/gui/text/qtextengine.cpp87
-rw-r--r--src/gui/text/qtextengine_p.h14
-rw-r--r--src/gui/text/qtextlayout.cpp42
-rw-r--r--src/network/access/qnetworkrequest.cpp37
-rw-r--r--src/network/bearer/qnetworkconfiguration.h2
-rw-r--r--src/xml/dom/qdom.cpp6
-rw-r--r--src/xmlpatterns/api/qabstractxmlnodemodel.cpp2
43 files changed, 829 insertions, 167 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index bc8ef9f..728bdf9 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -53,6 +53,9 @@ symbian: {
DEPLOYMENT = partial_upgrade $$DEPLOYMENT
}
-neon: QMAKE_CXXFLAGS *= -mfpu=neon
+neon {
+ DEFINES += QT_HAVE_NEON
+ QMAKE_CXXFLAGS *= -mfpu=neon
+}
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 79a38cd..9854e68 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -1009,8 +1009,11 @@ QByteArray QMetaObject::normalizedSignature(const char *method)
int argdepth = 0;
int templdepth = 0;
while (*d) {
- if (argdepth == 1)
+ if (argdepth == 1) {
d = qNormalizeType(d, templdepth, result);
+ if (!*d) //most likely an invalid signature.
+ break;
+ }
if (*d == '(')
++argdepth;
if (*d == ')')
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index f102598..5fac960 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -67,8 +67,8 @@
QSharedPointer and QWeakPointer are thread-safe and operate
atomically on the pointer value. Different threads can also access
- the same QSharedPointer or QWeakPointer object at the same time
- without need for locking mechanisms.
+ the QSharedPointer or QWeakPointer pointing to the same object at
+ the same time without need for locking mechanisms.
It should be noted that, while the pointer value can be accessed
in this manner, QSharedPointer and QWeakPointer provide no
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 5ff0f97..a3148fb 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -150,7 +150,9 @@ enum CPUFeatures {
Q_CORE_EXPORT uint qDetectCPUFeatures();
-Q_CORE_EXPORT uint qDetectCPUFeatures();
+
+#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
+ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index d6ab5da..2fd9a0b 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -6645,8 +6645,9 @@ QString QString::arg(qlonglong a, int fieldWidth, int base, const QChar &fillCha
QString locale_arg;
if (d.locale_occurrences > 0) {
QLocale locale;
- locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth,
- flags | QLocalePrivate::ThousandsGroup);
+ if (!locale.numberOptions() & QLocale::OmitGroupSeparator)
+ flags |= QLocalePrivate::ThousandsGroup;
+ locale_arg = locale.d()->longLongToString(a, -1, base, fieldWidth, flags);
}
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
@@ -6688,8 +6689,9 @@ QString QString::arg(qulonglong a, int fieldWidth, int base, const QChar &fillCh
QString locale_arg;
if (d.locale_occurrences > 0) {
QLocale locale;
- locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth,
- flags | QLocalePrivate::ThousandsGroup);
+ if (!locale.numberOptions() & QLocale::OmitGroupSeparator)
+ flags |= QLocalePrivate::ThousandsGroup;
+ locale_arg = locale.d()->unsLongLongToString(a, -1, base, fieldWidth, flags);
}
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
@@ -6822,7 +6824,8 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, const QChar &
if (d.locale_occurrences > 0) {
QLocale locale;
- flags |= QLocalePrivate::ThousandsGroup;
+ if (!locale.numberOptions() & QLocale::OmitGroupSeparator)
+ flags |= QLocalePrivate::ThousandsGroup;
locale_arg = locale.d()->doubleToString(a, prec, form, fieldWidth, flags);
}
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index e1fcb36..bf771a8 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -231,6 +231,7 @@ void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionP
\value ExportAllInvokables export all of this object's invokables
\value ExportAllContents export all of this object's contents
\value ExportChildObjects export this object's child objects
+
\sa registerObject(), QDBusAbstractAdaptor, {usingadaptors.html}{Using adaptors}
*/
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 5771f84..380c6ad 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -426,7 +426,7 @@ QDeclarativePathView::~QDeclarativePathView()
The model provides a set of data that is used to create the items for the view.
For large or dynamic datasets the model is usually provided by a C++ model object.
- Models can also be created directly in XML, using the ListModel element.
+ Models can also be created directly in QML, using the ListModel element.
\sa {qmlmodels}{Data Models}
*/
@@ -650,8 +650,8 @@ void QDeclarativePathViewPrivate::setOffset(qreal o)
so as to stay with the current item.
The below example demonstrates how to make a simple highlight. Note the use
- of the PathView.onPath property to ensure that the highlight is hidden
- when flicked off of the path.
+ of the \l{PathView::onPath}{PathView.onPath} attached property to ensure that
+ the highlight is hidden when flicked away from the path.
\code
Component {
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index 2b268fb..68e7e9a 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -133,13 +133,13 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
create items as they are required.
Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects.
- For example, it cannot be used to repeat QtObjects:
+ For example, it cannot be used to repeat QObjects:
\badcode
Item {
- //XXX does not work! Can't repeat QtObject as it doesn't derive from Item.
+ //XXX does not work! Can't repeat QObject as it doesn't derive from Item.
Repeater {
model: 10
- QtObject {}
+ QObject {}
}
}
\endcode
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index 3d25291..a58dc6c 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -80,10 +80,12 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
\code
QDeclarativeEngine engine;
+ QStringListModel modelData;
QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
- context->setContextProperty("myModel", modelData);
+ context->setContextProperty("myModel", &modelData);
- QDeclarativeComponent component(&engine, "ListView { model=myModel }");
+ QDeclarativeComponent component(&engine);
+ component.setData("import Qt 4.7\nListView { model: myModel }", QUrl());
component.create(context);
\endcode
@@ -104,12 +106,13 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate()
...
};
- MyDataSet *myDataSet = new MyDataSet;
+ MyDataSet myDataSet;
QDeclarativeEngine engine;
QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
- context->setContextObject(myDataSet);
+ context->setContextObject(&myDataSet);
- QDeclarativeComponent component(&engine, "ListView { model=myModel }");
+ QDeclarativeComponent component(&engine);
+ component.setData("import Qt 4.7\nListView { model: myModel }", QUrl());
component.create(context);
\endcode
diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp
index 340bfa7..ea68327 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.cpp
+++ b/src/declarative/qml/qdeclarativeimageprovider.cpp
@@ -59,13 +59,13 @@ public:
\list
\o Loaded using QPixmaps rather than actual image files
- \o Loaded asynchronously in a separate thread, if imageType() is \l Image
+ \o Loaded asynchronously in a separate thread, if imageType() is \l{QDeclarativeImageProvider::ImageType}{ImageType::Image}
\endlist
To specify that an image should be loaded by an image provider, use the
\bold {"image:"} scheme for the URL source of the image, followed by the
identifiers of the image provider and the requested image. For example:
-
+
\qml
Image { source: "image://myimageprovider/image.png" }
\endqml
@@ -83,7 +83,7 @@ public:
and "red", respectively:
\snippet examples/declarative/cppextensions/imageprovider/imageprovider-example.qml 0
-
+
When these images are loaded by QML, it looks for a matching image provider
and calls its requestImage() or requestPixmap() method (depending on its
imageType()) to load the image. The method is called with the \c id
@@ -136,7 +136,7 @@ public:
main thread. In this case, if \l {Image::}{asynchronous} is set to
\c true, the value is ignored and the image is loaded
synchronously.
-
+
\sa QDeclarativeEngine::addImageProvider()
*/
diff --git a/src/declarative/qml/qdeclarativelist.h b/src/declarative/qml/qdeclarativelist.h
index 399b2a1..c10bc11 100644
--- a/src/declarative/qml/qdeclarativelist.h
+++ b/src/declarative/qml/qdeclarativelist.h
@@ -98,16 +98,16 @@ public:
private:
static void qlist_append(QDeclarativeListProperty *p, T *v) {
- ((QList<T *> *)p->data)->append(v);
+ reinterpret_cast<QList<T *> *>(p->data)->append(v);
}
static int qlist_count(QDeclarativeListProperty *p) {
- return ((QList<T *> *)p->data)->count();
+ return reinterpret_cast<QList<T *> *>(p->data)->count();
}
static T *qlist_at(QDeclarativeListProperty *p, int idx) {
- return ((QList<T *> *)p->data)->at(idx);
+ return reinterpret_cast<QList<T *> *>(p->data)->at(idx);
}
static void qlist_clear(QDeclarativeListProperty *p) {
- return ((QList<T *> *)p->data)->clear();
+ return reinterpret_cast<QList<T *> *>(p->data)->clear();
}
};
#endif
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index cb916bf..d45ddbc 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -105,7 +105,7 @@ namespace QDeclarativePrivate
template<class From, class To>
struct StaticCastSelectorClass<From, To, sizeof(int)>
{
- static inline int cast() { return (int)((intptr_t)static_cast<To *>((From *)0x10000000)) - 0x10000000; }
+ static inline int cast() { return int(reinterpret_cast<intptr_t>(static_cast<To *>(reinterpret_cast<From *>(0x10000000)))) - 0x10000000; }
};
template<class From, class To>
@@ -119,7 +119,7 @@ namespace QDeclarativePrivate
static inline int cast()
{
- return StaticCastSelectorClass<From, To, sizeof(check((From *)0))>::cast();
+ return StaticCastSelectorClass<From, To, sizeof(check(reinterpret_cast<From *>(0)))>::cast();
}
};
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index b901bb3..a747706 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -1329,7 +1329,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t)
\snippet doc/src/snippets/declarative/rotationanimation.qml 0
- Notice the RotationAnimation did not need to set a \l {PropertyAnimation::}{target}
+ Notice the RotationAnimation did not need to set a \l target
value. As a convenience, when used in a transition, RotationAnimation will rotate all
properties named "rotation" or "angle". You can override this by providing
your own properties via \l {PropertyAnimation::properties}{properties} or
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 9ced14f..de2de21 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -525,6 +525,7 @@ void QDeclarativePixmapReader::cancel(QDeclarativePixmapReply *reply)
mutex.lock();
if (reply->loading) {
cancelled.append(reply);
+ reply->data = 0;
// XXX
if (threadObject) threadObject->processJobs();
} else {
@@ -738,7 +739,6 @@ void QDeclarativePixmapData::release()
if (refCount == 0) {
if (reply) {
- reply->data = 0;
reply->reader->cancel(reply);
reply = 0;
}
diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp
index 7042d0c..aa1426c 100644
--- a/src/declarative/util/qdeclarativetransition.cpp
+++ b/src/declarative/util/qdeclarativetransition.cpp
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
to (50, 50). The added Transition specifies that when the rectangle
changes between the default and the "moved" state, any changes
to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad.
-
+
\snippet doc/src/snippets/declarative/transition.qml 0
Notice the example does not require \l{PropertyAnimation::}{to} and
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp
index 062b5ac..3fc7f10 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp
@@ -641,7 +641,8 @@ QSizeF QGraphicsGridLayout::sizeHint(Qt::SizeHint which, const QSizeF &constrain
Q_D(const QGraphicsGridLayout);
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
- return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom);
+ const QSizeF extraMargins(left + right, top + bottom);
+ return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins;
}
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index e1e27d2..0b3b164 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -7985,6 +7985,24 @@ void QGraphicsItemPrivate::resetHeight()
*/
/*!
+ \property QGraphicsObject::children
+ \since 4.7
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::width
+ \since 4.7
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::height
+ \since 4.7
+ \internal
+*/
+
+/*!
\class QAbstractGraphicsShapeItem
\brief The QAbstractGraphicsShapeItem class provides a common base for
all path items.
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp
index 5a7f1af..3707591 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem.cpp
+++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp
@@ -48,6 +48,7 @@
#include "qgraphicslayoutitem.h"
#include "qgraphicslayoutitem_p.h"
#include "qwidget.h"
+#include "qgraphicswidget.h"
#include <QtDebug>
@@ -139,9 +140,11 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint)
if (!sizeHintCacheDirty && cachedConstraint == constraint)
return cachedSizeHints;
+ const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0;
+
for (int i = 0; i < Qt::NSizeHints; ++i) {
cachedSizeHints[i] = constraint;
- if (userSizeHints)
+ if (userSizeHints && !hasConstraint)
combineSize(cachedSizeHints[i], userSizeHints[i]);
}
@@ -259,6 +262,52 @@ void QGraphicsLayoutItemPrivate::setSizeComponent(
q->updateGeometry();
}
+
+bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const
+{
+ Q_Q(const QGraphicsLayoutItem);
+ if (isLayout) {
+ const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
+ for (int i = l->count() - 1; i >= 0; --i) {
+ if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth())
+ return true;
+ }
+ } else if (QGraphicsItem *item = q->graphicsItem()) {
+ if (item->isWidget()) {
+ QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
+ if (w->layout()) {
+ return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth();
+ }
+ }
+ }
+ return q->sizePolicy().hasHeightForWidth();
+}
+
+bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const
+{
+ // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8)
+#if 1
+ return false;
+#else
+ Q_Q(const QGraphicsLayoutItem);
+ if (isLayout) {
+ const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q);
+ for (int i = l->count() - 1; i >= 0; --i) {
+ if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight())
+ return true;
+ }
+ } else if (QGraphicsItem *item = q->graphicsItem()) {
+ if (item->isWidget()) {
+ QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
+ if (w->layout()) {
+ return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight();
+ }
+ }
+ }
+ return q->sizePolicy().hasWidthForHeight();
+#endif
+}
+
/*!
\class QGraphicsLayoutItem
\brief The QGraphicsLayoutItem class can be inherited to allow your custom
diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h
index 15cc7a5..b752e03 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem_p.h
+++ b/src/gui/graphicsview/qgraphicslayoutitem_p.h
@@ -65,6 +65,9 @@ class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate
public:
virtual ~QGraphicsLayoutItemPrivate();
QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout);
+ static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();}
+ static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();}
+
void init();
QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
QGraphicsItem *parentItem() const;
@@ -73,6 +76,9 @@ public:
enum SizeComponent { Width, Height };
void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value);
+ bool hasHeightForWidth() const;
+ bool hasWidthForHeight() const;
+
QSizePolicy sizePolicy;
QGraphicsLayoutItem *parent;
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp
index 37408ef..1588364 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp
@@ -528,7 +528,8 @@ QSizeF QGraphicsLinearLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra
Q_D(const QGraphicsLinearLayout);
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
- return d->engine.sizeHint(d->styleInfo(), which , constraint) + QSizeF(left + right, top + bottom);
+ const QSizeF extraMargins(left + right, top + bottom);
+ return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins;
}
/*!
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp
index 7b69317..bd3f2ef 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/gui/graphicsview/qgraphicstransform.cpp
@@ -583,6 +583,27 @@ void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const
\sa QGraphicsRotation::axis
*/
+/*!
+ \fn QGraphicsScale::xScaleChanged()
+ \since 4.7
+
+ This signal is emitted whenever the \l xScale property changes.
+*/
+
+/*!
+ \fn QGraphicsScale::yScaleChanged()
+ \since 4.7
+
+ This signal is emitted whenever the \l yScale property changes.
+*/
+
+/*!
+ \fn QGraphicsScale::zScaleChanged()
+ \since 4.7
+
+ This signal is emitted whenever the \l zScale property changes.
+*/
+
#include "moc_qgraphicstransform.cpp"
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp
index a084647..f3b2026 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/graphicsview/qgridlayoutengine.cpp
@@ -250,6 +250,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
sumAvailable = targetSize - totalBox.q_preferredSize;
if (sumAvailable > 0.0) {
+ qreal sumCurrentAvailable = sumAvailable;
bool somethingHasAMaximumSize = false;
qreal sumPreferredSizes = 0.0;
@@ -308,12 +309,12 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
qreal ultimateFactor = (stretch * ultimateSumPreferredSizes
/ sumStretches)
- (box.q_preferredSize);
- qreal transitionalFactor = sumAvailable
+ qreal transitionalFactor = sumCurrentAvailable
* (ultimatePreferredSize - box.q_preferredSize)
/ (ultimateSumPreferredSizes
- sumPreferredSizes);
- qreal alpha = qMin(sumAvailable,
+ qreal alpha = qMin(sumCurrentAvailable,
ultimateSumPreferredSizes - sumPreferredSizes);
qreal beta = ultimateSumPreferredSizes - sumPreferredSizes;
@@ -321,7 +322,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
+ ((beta - alpha) * transitionalFactor)) / beta;
}
sumFactors += factors[i];
- if (desired < sumAvailable)
+ if (desired < sumCurrentAvailable)
somethingHasAMaximumSize = true;
newSizes[i] = -1.0;
@@ -337,12 +338,12 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
continue;
const QGridLayoutBox &box = boxes.at(start + i);
- qreal avail = sumAvailable * factors[i] / sumFactors;
+ qreal avail = sumCurrentAvailable * factors[i] / sumFactors;
if (sizes[i] + avail >= box.q_maximumSize) {
newSizes[i] = box.q_maximumSize;
- sumAvailable -= box.q_maximumSize - sizes[i];
+ sumCurrentAvailable -= box.q_maximumSize - sizes[i];
sumFactors -= factors[i];
- keepGoing = (sumAvailable > 0.0);
+ keepGoing = (sumCurrentAvailable > 0.0);
if (!keepGoing)
break;
}
@@ -352,7 +353,7 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz
for (int i = 0; i < n; ++i) {
if (newSizes[i] < 0.0) {
qreal delta = (sumFactors == 0.0) ? 0.0
- : sumAvailable * factors[i] / sumFactors;
+ : sumCurrentAvailable * factors[i] / sumFactors;
newSizes[i] = sizes[i] + delta;
}
}
@@ -545,6 +546,24 @@ QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) con
: sizePolicy.verticalPolicy();
}
+/*
+ returns true if the size policy returns true for either hasHeightForWidth()
+ or hasWidthForHeight()
+ */
+bool QGridLayoutItem::hasDynamicConstraint() const
+{
+ return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()
+ || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight();
+}
+
+Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const
+{
+ if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth())
+ return Qt::Vertical;
+ else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight())
+ return Qt::Horizontal;
+}
+
QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const
{
return q_layoutItem->sizePolicy().controlType();
@@ -613,7 +632,14 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig
qreal cellWidth = width;
qreal cellHeight = height;
- QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight));
+ QSize constraint;
+ if (hasDynamicConstraint()) {
+ if (dynamicConstraintOrientation() == Qt::Vertical)
+ constraint.setWidth(cellWidth);
+ else
+ constraint.setHeight(cellHeight);
+ }
+ QSizeF size = effectiveMaxSize(constraint).boundedTo(QSizeF(cellWidth, cellHeight));
width = size.width();
height = size.height();
@@ -675,13 +701,13 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori
Note that effectiveSizeHint does not take sizePolicy into consideration,
(since it only evaluates the hints, as the name implies)
*/
-QSizeF QGridLayoutItem::effectiveMaxSize() const
+QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const
{
- QSizeF size;
+ QSizeF size = constraint;
bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag;
bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag;
if (!vGrow || !hGrow) {
- QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize);
+ QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint);
if (!vGrow)
size.setHeight(pref.height());
if (!hGrow)
@@ -689,7 +715,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize() const
}
if (!size.isValid()) {
- QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize);
+ QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, constraint);
if (size.width() == -1)
size.setWidth(maxSize.width());
if (size.height() == -1)
@@ -1010,6 +1036,7 @@ void QGridLayoutEngine::invalidate()
q_cachedEffectiveLastRows[Ver] = -1;
q_cachedDataForStyleInfo.invalidate();
q_cachedSize = QSizeF();
+ q_cachedConstraintOrientation = UnknownConstraint;
}
static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
@@ -1074,10 +1101,13 @@ QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo,
}
QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which,
- const QSizeF & /* constraint */) const
+ const QSizeF &constraint) const
{
ensureColumnAndRowData(styleInfo);
+ if (hasDynamicConstraint())
+ return dynamicallyConstrainedSizeHint(which, constraint);
+
switch (which) {
case Qt::MinimumSize:
return QSizeF(q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize);
@@ -1375,7 +1405,11 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
box = &multiCell.q_box;
multiCell.q_stretch = itemStretch;
}
- box->combine(item->box(orientation));
+ // Items with constraints are not included in the orientation that
+ // they are constrained (since it depends on the hfw/constraint function).
+ // They must be combined at a later stage.
+ if (!item->hasDynamicConstraint() || orientation != item->dynamicConstraintOrientation())
+ box->combine(item->box(orientation));
if (effectiveRowSpan == 1) {
QSizePolicy::ControlTypes controls = item->controlTypes(top);
@@ -1532,6 +1566,138 @@ void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo
q_cachedDataForStyleInfo = styleInfo;
}
+QSizeF QGridLayoutEngine::dynamicallyConstrainedSizeHint(Qt::SizeHint which,
+ const QSizeF &constraint) const
+{
+ Q_ASSERT(hasDynamicConstraint());
+ if (constraint.width() < 0 && constraint.height() < 0) {
+ // Process the hfw / wfh items that we did not process in fillRowData()
+ const Qt::Orientation constraintOrient = constraintOrientation();
+
+ QGridLayoutRowData rowData = constraintOrient == Qt::Vertical ? q_rowData : q_columnData;
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+ if (item->hasDynamicConstraint()) {
+ QGridLayoutBox box = item->box(constraintOrient);
+ QGridLayoutBox &rowBox = rowData.boxes[item->firstRow(constraintOrient)];
+ rowBox.combine(box);
+ }
+ }
+
+ QGridLayoutBox totalBoxes[2];
+ if (constraintOrient == Qt::Vertical) {
+ totalBoxes[Hor] = q_columnData.totalBox(0, columnCount());
+ totalBoxes[Ver] = rowData.totalBox(0, rowCount());
+ } else {
+ totalBoxes[Hor] = rowData.totalBox(0, columnCount());
+ totalBoxes[Ver] = q_rowData.totalBox(0, rowCount());
+ }
+ return QSizeF(totalBoxes[Hor].q_sizes(which), totalBoxes[Ver].q_sizes(which));
+ }
+
+
+ Q_ASSERT(constraint.width() >= 0 || constraint.height() >= 0);
+ q_xx.resize(columnCount());
+ q_yy.resize(rowCount());
+ q_widths.resize(columnCount());
+ q_heights.resize(rowCount());
+ q_descents.resize(rowCount());
+
+
+ const Qt::Orientation orientation = constraintOrientation();
+ QGridLayoutRowData *colData;
+ QGridLayoutRowData constrainedRowData;
+ QGridLayoutBox *totalBox;
+ qreal *sizes;
+ qreal *pos;
+ qreal *descents;
+ qreal targetSize;
+ qreal cCount;
+ qreal rCount;
+
+ if (orientation == Qt::Vertical) {
+ // height for width
+ colData = &q_columnData;
+ totalBox = &q_totalBoxes[Hor];
+ sizes = q_widths.data();
+ pos = q_xx.data();
+ descents = 0;
+ targetSize = constraint.width();
+ cCount = columnCount();
+ rCount = rowCount();
+ constrainedRowData = q_rowData;
+ } else {
+ // width for height
+ colData = &q_rowData;
+ totalBox = &q_totalBoxes[Ver];
+ sizes = q_heights.data();
+ pos = q_yy.data();
+ descents = q_descents.data();
+ targetSize = constraint.height();
+ cCount = rowCount();
+ rCount = columnCount();
+ constrainedRowData = q_columnData;
+ }
+ colData->calculateGeometries(0, cCount, targetSize, pos, sizes, descents, *totalBox);
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+
+ if (item->hasDynamicConstraint()) {
+ const qreal size = sizes[item->firstColumn(orientation)];
+ QGridLayoutBox box = item->box(orientation, size);
+ QGridLayoutBox &rowBox = constrainedRowData.boxes[item->firstRow(orientation)];
+ rowBox.combine(box);
+ }
+ }
+ const qreal newSize = constrainedRowData.totalBox(0, rCount).q_sizes(which);
+
+ return (orientation == Qt::Vertical) ? QSizeF(targetSize, newSize) : QSizeF(newSize, targetSize);
+}
+
+
+/**
+ returns false if the layout has contradicting constraints (i.e. some items with a horizontal
+ constraint and other items with a vertical constraint)
+ */
+bool QGridLayoutEngine::ensureDynamicConstraint() const
+{
+ if (q_cachedConstraintOrientation == UnknownConstraint) {
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+ if (item->hasDynamicConstraint()) {
+ Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation();
+ if (q_cachedConstraintOrientation == UnknownConstraint) {
+ q_cachedConstraintOrientation = itemConstraintOrientation;
+ } else if (q_cachedConstraintOrientation != itemConstraintOrientation) {
+ q_cachedConstraintOrientation = UnfeasibleConstraint;
+ qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and"
+ " vertical constraint in the same layout");
+ return false;
+ }
+ }
+ }
+ if (q_cachedConstraintOrientation == UnknownConstraint)
+ q_cachedConstraintOrientation = NoConstraint;
+ }
+ return true;
+}
+
+bool QGridLayoutEngine::hasDynamicConstraint() const
+{
+ if (!ensureDynamicConstraint())
+ return false;
+ return q_cachedConstraintOrientation != NoConstraint;
+}
+
+/*
+ * return value is only valid if hasConstraint() returns true
+ */
+Qt::Orientation QGridLayoutEngine::constraintOrientation() const
+{
+ (void)ensureDynamicConstraint();
+ return (Qt::Orientation)q_cachedConstraintOrientation;
+}
+
void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
const QSizeF &size) const
{
@@ -1544,10 +1710,74 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_widths.resize(columnCount());
q_heights.resize(rowCount());
q_descents.resize(rowCount());
- q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
- 0, q_totalBoxes[Hor]);
- q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
- q_descents.data(), q_totalBoxes[Ver]);
+
+
+ Qt::Orientation orientation = Qt::Vertical;
+ if (hasDynamicConstraint())
+ orientation = constraintOrientation();
+
+ /*
+ In order to do hfw we need to first distribute the columns, then the rows.
+ In order to do wfh we need to first distribute the rows, then the columns.
+
+ If there is no constraint, the order of distributing the rows or columns first is irrelevant.
+ We choose horizontal just to keep the same behaviour as before (however, there shouldn't
+ be any behaviour difference).
+ */
+
+ QGridLayoutRowData *colData;
+ QGridLayoutRowData rowData;
+ qreal *widths;
+ qreal *heights;
+ qreal *xx;
+ qreal *yy;
+ qreal *xdescents = 0;
+ qreal *ydescents = 0;
+ qreal cCount;
+ qreal rCount;
+ QSizeF oSize = size;
+ if (orientation == Qt::Vertical) {
+ // height for width
+ colData = &q_columnData;
+ rowData = q_rowData;
+ widths = q_widths.data();
+ heights = q_heights.data();
+ xx = q_xx.data();
+ yy = q_yy.data();
+ cCount = columnCount();
+ rCount = rowCount();
+ ydescents = q_descents.data();
+ } else {
+ // width for height
+ colData = &q_rowData;
+ rowData = q_columnData;
+ widths = q_heights.data();
+ heights = q_widths.data();
+ xx = q_yy.data();
+ yy = q_xx.data();
+ cCount = rowCount();
+ rCount = columnCount();
+ xdescents = q_descents.data();
+ oSize.transpose();
+ }
+
+ colData->calculateGeometries(0, cCount, oSize.width(), xx, widths,
+ xdescents, q_totalBoxes[orientation == Qt::Horizontal]);
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+ const int col = item->firstColumn(orientation);
+ const int row = item->firstRow(orientation);
+ if (item->hasDynamicConstraint()) {
+ const qreal sz = widths[col];
+ QGridLayoutBox box = item->box(orientation, sz);
+ rowData.boxes[row].combine(box);
+ }
+ }
+
+ QGridLayoutBox &totalBox = q_totalBoxes[orientation == Qt::Vertical];
+ totalBox = rowData.totalBox(0, rCount);
+ rowData.calculateGeometries(0, rCount, oSize.height(), yy, heights,
+ ydescents, totalBox);
q_cachedSize = size;
}
diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h
index 9ac9a8e..580af7e 100644
--- a/src/gui/graphicsview/qgridlayoutengine_p.h
+++ b/src/gui/graphicsview/qgridlayoutengine_p.h
@@ -91,6 +91,14 @@ enum LayoutSide {
Bottom
};
+enum {
+ NoConstraint,
+ HorizontalConstraint,
+ VerticalConstraint,
+ UnknownConstraint, // need to update cache
+ UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints
+};
+
template <typename T>
class QLayoutParameter
{
@@ -270,6 +278,10 @@ public:
inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; }
QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const;
+
+ bool hasDynamicConstraint() const;
+ Qt::Orientation dynamicConstraintOrientation() const;
+
QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const;
@@ -280,7 +292,7 @@ public:
void setGeometry(const QRectF &rect);
void transpose();
void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical);
- QSizeF effectiveMaxSize() const;
+ QSizeF effectiveMaxSize(const QSizeF &constraint) const;
#ifdef QT_DEBUG
void dump(int indent = 0) const;
@@ -372,6 +384,14 @@ public:
int column, int rowSpan, int columnSpan) const;
QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which,
const QSizeF &constraint) const;
+
+ // heightForWidth / widthForHeight support
+ QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
+ bool ensureDynamicConstraint() const;
+ bool hasDynamicConstraint() const;
+ Qt::Orientation constraintOrientation() const;
+
+
QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
void transpose();
void setVisualDirection(Qt::LayoutDirection direction);
@@ -405,6 +425,7 @@ private:
// Lazily computed from the above user input
mutable int q_cachedEffectiveFirstRows[NOrientations];
mutable int q_cachedEffectiveLastRows[NOrientations];
+ mutable quint8 q_cachedConstraintOrientation : 2;
// Layout item input
mutable QLayoutStyleInfo q_cachedDataForStyleInfo;
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 28440cc..3943e26 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -77,6 +77,25 @@ symbian {
DEPLOYMENT = partial_upgrade $$DEPLOYMENT
}
+neon:*-g++* {
+ DEFINES += QT_HAVE_NEON
+ QMAKE_CXXFLAGS *= -mfpu=neon
+ HEADERS += $$NEON_HEADERS
+ SOURCES += $$NEON_SOURCES
+
+ DRAWHELPER_NEON_ASM_FILES = $$NEON_ASM
+
+ neon_compiler.commands = $$QMAKE_CXX -c
+ neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ neon_compiler.dependency_type = TYPE_C
+ neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ neon_compiler.input = DRAWHELPER_NEON_ASM_FILES
+ neon_compiler.variable_out = OBJECTS
+ neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN}
+ silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands
+ QMAKE_EXTRA_COMPILERS += neon_compiler
+}
+
contains(QMAKE_MAC_XARCH, no) {
DEFINES += QT_NO_MAC_XARCH
} else {
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index b20a04f..f89706c 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -94,5 +94,6 @@ contains(QT_CONFIG, tiff):include($$PWD/qtiffhandler.pri)
contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD
+NEON_SOURCES += image/qimage_neon.cpp
SSE2_SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.cpp
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index cb834c0..ac148ee 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3769,6 +3769,14 @@ void qInitImageConversions()
converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
}
#endif
+#ifdef QT_HAVE_NEON
+ if (features & NEON) {
+ extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
+ converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
+ converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
+ }
+#endif
}
/*!
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
new file mode 100644
index 0000000..15bf472
--- /dev/null
+++ b/src/gui/image/qimage_neon.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qimage.h>
+#include <private/qimage_p.h>
+#include <private/qsimd_p.h>
+
+#ifdef QT_HAVE_NEON
+
+QT_BEGIN_NAMESPACE
+
+Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len)
+{
+ if (!len)
+ return;
+
+ const quint32 *const end = dst + len;
+
+ // align dst on 64 bits
+ const int offsetToAlignOn8Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x1;
+ for (int i = 0; i < offsetToAlignOn8Bytes; ++i) {
+ *dst++ = qRgb(src[0], src[1], src[2]);
+ src += 3;
+ }
+
+ if ((len - offsetToAlignOn8Bytes) >= 8) {
+ const quint32 *const simdEnd = end - 7;
+ register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
+ do {
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ asm volatile (
+ "vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t"
+ "vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "d4", "d5", "d6"
+ );
+#else
+ asm volatile (
+ "vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t"
+ "vswp d0, d2\n\t"
+ "vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t"
+ : [DST]"+r" (dst), [SRC]"+r" (src)
+ : "w"(fullVector)
+ : "memory", "d0", "d1", "d2"
+ );
+#endif
+ } while (dst < simdEnd);
+ }
+
+ while (dst != end) {
+ *dst++ = qRgb(src[0], src[1], src[2]);
+ src += 3;
+ }
+}
+
+void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB888);
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const uchar *src_data = (uchar *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ qt_convert_rgb888_to_rgb32_neon(dest_data, src_data, src->width);
+ src_data += src->bytes_per_line;
+ dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_HAVE_NEON
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index d358a5e..eda5efb 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -803,9 +803,16 @@ bool QJpegHandlerPrivate::read(QImage *image)
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(QT_HAVE_SSSE3)
const uint features = qDetectCPUFeatures();
-
+ Q_UNUSED(features);
+#if defined(QT_HAVE_NEON)
+ // from qimage_neon.cpp
+ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len);
+
+ if (features & NEON)
+ rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
+#endif // QT_HAVE_NEON
+#if defined(QT_HAVE_SSSE3)
// from qimage_ssse3.cpp
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index bbc9e0b..eade02e 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4281,6 +4281,11 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
QGestureEvent::accept() for each of them, or an event filter consumes the
event.
+ \section1 Further Reading
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
\sa QGesture, QGestureRecognizer,
QWidget::grabGesture(), QGraphicsObject::grabGesture()
*/
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 4a4452a..13274c4 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE
the QGestureRecognizer object that is registered with the application; see
QGestureRecognizer::registerRecognizer().
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
\section1 Gesture Properties
The class has a list of properties that can be queried by the user to get
@@ -219,7 +222,10 @@ QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
\image pangesture.png
- \sa {Gestures Programming}, QPinchGesture, QSwipeGesture
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPinchGesture, QSwipeGesture
*/
/*!
@@ -314,6 +320,9 @@ void QPanGesture::setAcceleration(qreal value)
them closer together or further apart to change the scale factor, zoom, or level
of detail of the user interface.
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
\image pinchgesture.png
Instead of repeatedly applying the same pinching gesture, the user may
@@ -322,7 +331,7 @@ void QPanGesture::setAcceleration(qreal value)
will continue to be delivered to the target object, containing an instance
of QPinchGesture in the Qt::GestureUpdated state.
- \sa {Gestures Programming}, QPanGesture, QSwipeGesture
+ \sa QPanGesture, QSwipeGesture
*/
/*!
@@ -572,7 +581,10 @@ void QPinchGesture::setRotationAngle(qreal value)
\image swipegesture.png
- \sa {Gestures Programming}, QPanGesture, QPinchGesture
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
*/
/*!
@@ -667,7 +679,10 @@ void QSwipeGesture::setSwipeAngle(qreal value)
\brief The QTapGesture class describes a tap gesture made by the user.
\ingroup gestures
- \sa {Gestures Programming}, QPanGesture, QPinchGesture
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
*/
/*!
@@ -700,7 +715,10 @@ void QTapGesture::setPosition(const QPointF &value)
gesture made by the user.
\ingroup gestures
- \sa {Gestures Programming}, QPanGesture, QPinchGesture
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
*/
/*!
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index 3e23bbf..e0e7784 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -62,6 +62,9 @@ QT_BEGIN_NAMESPACE
need to use this class directly. Instances will be created behind the scenes by the
framework.
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
\section1 Recognizing Gestures
The process of recognizing gestures involves filtering input events sent to specific
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 4023f65..dfa4a48 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -246,23 +246,8 @@ symbian {
QMAKE_CXXFLAGS.ARMCC *= -O3
}
-neon:*-g++* {
- DEFINES += QT_HAVE_NEON
- HEADERS += painting/qdrawhelper_neon_p.h
- SOURCES += painting/qdrawhelper_neon.cpp
- QMAKE_CXXFLAGS *= -mfpu=neon
-
- DRAWHELPER_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
-
- neon_compiler.commands = $$QMAKE_CXX -c
- neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
- neon_compiler.dependency_type = TYPE_C
- neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
- neon_compiler.input = DRAWHELPER_NEON_ASM_FILES
- neon_compiler.variable_out = OBJECTS
- neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN}
- silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands
- QMAKE_EXTRA_COMPILERS += neon_compiler
-}
+NEON_SOURCES += painting/qdrawhelper_neon.cpp
+NEON_HEADERS += painting/qdrawhelper_neon_p.h
+NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
include($$PWD/../../3rdparty/zlib_dependency.pri)
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 7ab9eda..22c0384 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -112,9 +112,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
int x = 0;
// First, align dest to 16 bytes:
- const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;
- const int prologLength = qMin(w, offsetToAlignOn16Bytes);
- for (; x < prologLength; ++x) {
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) {
quint32 s = src[x];
s = BYTE_MUL(s, const_alpha);
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
@@ -182,12 +180,10 @@ inline int comp_func_Plus_one_pixel(uint d, const uint s)
void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha)
{
int x = 0;
- const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;
- const int prologLength = qMin(length, offsetToAlignOn16Bytes);
if (const_alpha == 255) {
// 1) Prologue: align destination on 16 bytes
- for (; x < prologLength; ++x)
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length)
dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]);
// 2) composition with SSE2
@@ -208,7 +204,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin
const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha);
// 1) Prologue: align destination on 16 bytes
- for (; x < prologLength; ++x)
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length)
dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha);
const __m128i half = _mm_set1_epi16(0x80);
@@ -239,9 +235,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u
int x = 0;
// 1) prologue, align on 16 bytes
- const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;
- const int prologLength = qMin(length, offsetToAlignOn16Bytes);
- for (; x < prologLength; ++x)
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length)
dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
// 2) interpolate pixels with SSE2
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index 18355c2..d8f6bf5 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -143,9 +143,7 @@ QT_BEGIN_NAMESPACE
int x = 0; \
\
/* First, get dst aligned. */ \
- const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\
- const int prologLength = qMin(length, offsetToAlignOn16Bytes);\
- for (; x < prologLength; ++x) { \
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \
uint s = src[x]; \
if (s >= 0xff000000) \
dst[x] = s; \
@@ -202,9 +200,7 @@ QT_BEGIN_NAMESPACE
{ \
int x = 0; \
\
- const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\
- const int prologLength = qMin(length, offsetToAlignOn16Bytes);\
- for (; x < prologLength; ++x) { \
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \
quint32 s = src[x]; \
if (s != 0) { \
s = BYTE_MUL(s, const_alpha); \
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 9dadbd5..b694d9c 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -90,6 +90,15 @@ void qt_format_text(const QFont &font,
const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
int tabstops, int* tabarray, int tabarraylen,
QPainter *painter);
+static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
+ QTextCharFormat::UnderlineStyle underlineStyle,
+ const QTextItem::RenderFlags flags, qreal width,
+ const QTextCharFormat &charFormat);
+// Helper function to calculate left most position, width and flags for decoration drawing
+static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat);
static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
@@ -5923,6 +5932,10 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
currentColor = item->color;
}
d->extended->drawStaticTextItem(item);
+
+ drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions,
+ item->numGlyphs, item->fontEngine, staticText_d->font,
+ QTextCharFormat());
}
if (currentColor != oldPen.color())
setPen(oldPen);
@@ -6290,15 +6303,15 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
return pixmap;
}
-static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti)
+static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
+ QTextCharFormat::UnderlineStyle underlineStyle,
+ const QTextItem::RenderFlags flags, qreal width,
+ const QTextCharFormat &charFormat)
{
- QTextCharFormat::UnderlineStyle underlineStyle = ti.underlineStyle;
if (underlineStyle == QTextCharFormat::NoUnderline
- && !(ti.flags & (QTextItem::StrikeOut | QTextItem::Overline)))
+ && !(flags & (QTextItem::StrikeOut | QTextItem::Overline)))
return;
- QFontEngine *fe = ti.fontEngine;
-
const QPen oldPen = painter->pen();
const QBrush oldBrush = painter->brush();
painter->setBrush(Qt::NoBrush);
@@ -6307,7 +6320,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
pen.setWidthF(fe->lineThickness().toReal());
pen.setCapStyle(Qt::FlatCap);
- QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y());
+ QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y());
const qreal underlineOffset = fe->underlinePosition().toReal();
// deliberately ceil the offset to avoid the underline coming too close to
@@ -6322,21 +6335,21 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->save();
painter->translate(0, pos.y() + 1);
- QColor uc = ti.charFormat.underlineColor();
+ QColor uc = charFormat.underlineColor();
if (uc.isValid())
pen.setColor(uc);
// Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
- const int descent = (int) ti.descent.toReal();
+ const int descent = (int) fe->descent().toReal();
painter->setBrushOrigin(painter->brushOrigin().x(), 0);
- painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave);
+ painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
painter->restore();
} else if (underlineStyle != QTextCharFormat::NoUnderline) {
QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
- QColor uc = ti.charFormat.underlineColor();
+ QColor uc = charFormat.underlineColor();
if (uc.isValid())
pen.setColor(uc);
@@ -6348,14 +6361,14 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
pen.setStyle(Qt::SolidLine);
pen.setColor(oldPen.color());
- if (ti.flags & QTextItem::StrikeOut) {
+ if (flags & QTextItem::StrikeOut) {
QLineF strikeOutLine = line;
strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
painter->setPen(pen);
painter->drawLine(strikeOutLine);
}
- if (ti.flags & QTextItem::Overline) {
+ if (flags & QTextItem::Overline) {
QLineF overLine = line;
overLine.translate(0., - fe->ascent().toReal());
painter->setPen(pen);
@@ -6366,6 +6379,50 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setBrush(oldBrush);
}
+static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat)
+{
+ if (!(font.underline() || font.strikeOut() || font.overline()))
+ return;
+
+ QFixed leftMost;
+ QFixed rightMost;
+ QFixed baseLine;
+ for (int i=0; i<glyphCount; ++i) {
+ glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
+ if (i == 0 || leftMost > positions[i].x)
+ leftMost = positions[i].x;
+
+ // We don't support glyphs that do not share a common baseline. If this turns out to
+ // be a relevant use case, then we need to find clusters of glyphs that share a baseline
+ // and do a drawTextItemDecorations call per cluster.
+ if (i == 0 || baseLine < positions[i].y)
+ baseLine = positions[i].y;
+
+ // We use the advance rather than the actual bounds to match the algorithm in drawText()
+ if (i == 0 || rightMost < positions[i].x + gm.xoff)
+ rightMost = positions[i].x + gm.xoff;
+ }
+
+ QFixed width = rightMost - leftMost;
+ QTextItem::RenderFlags flags = 0;
+
+ if (font.underline())
+ flags |= QTextItem::Underline;
+ if (font.overline())
+ flags |= QTextItem::Overline;
+ if (font.strikeOut())
+ flags |= QTextItem::StrikeOut;
+
+ drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
+ fontEngine,
+ font.underline() ? QTextCharFormat::SingleUnderline
+ : QTextCharFormat::NoUnderline, flags,
+ width.toReal(), charFormat);
+}
+
void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
{
#ifdef QT_DEBUG_DRAW
@@ -6496,7 +6553,8 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
else
d->engine->drawTextItem(p, ti);
}
- drawTextItemDecoration(this, p, ti);
+ drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(),
+ ti.charFormat);
if (d->state->renderHints != oldRenderHints) {
d->state->renderHints = oldRenderHints;
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 7396bcd..21c2e02 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -109,10 +109,18 @@ QT_BEGIN_NAMESPACE
QPainter::drawStaticText() and can change from call to call with a minimal impact on
performance.
- QStaticText will attempt to guess the format of the input text using Qt::mightBeRichText().
- To force QStaticText to display its contents as either plain text or rich text, use the
- function QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and
- Qt::RichText.
+ For extra convenience, it is possible to apply formatting to the text using the HTML subset
+ supported by QTextDocument. QStaticText will attempt to guess the format of the input text using
+ Qt::mightBeRichText(), and interpret it as rich text if this function returns true. To force
+ QStaticText to display its contents as either plain text or rich text, use the function
+ QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and Qt::RichText.
+
+ QStaticText can only represent text, so only HTML tags which alter the layout or appearance of
+ the text will be respected. Adding an image to the input HTML, for instance, will cause the
+ image to be included as part of the layout, affecting the positions of the text glyphs, but it
+ will not be displayed. The result will be an empty area the size of the image in the output.
+ Similarly, using tables will cause the text to be laid out in table format, but the borders
+ will not be drawn.
If it's the first time the static text is drawn, or if the static text, or the painter's font
has been altered since the last time it was drawn, the text's layout has to be
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 439f2a4..5670e29 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -923,6 +923,13 @@ void QTextEngine::shapeText(int item) const
si.width += glyphs.advances_x[i];
}
+static inline bool hasCaseChange(const QScriptItem &si)
+{
+ return si.analysis.flags == QScriptAnalysis::SmallCaps ||
+ si.analysis.flags == QScriptAnalysis::Uppercase ||
+ si.analysis.flags == QScriptAnalysis::Lowercase;
+}
+
#if defined(Q_WS_WINCE) //TODO
// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
// and no reordering.
@@ -1050,14 +1057,15 @@ void QTextEngine::shapeTextWithCE(int item) const
if (option.useDesignMetrics())
flags |= DesignMetrics;
- attributes(); // pre-initialize char attributes
+ // pre-initialize char attributes
+ if (! attributes())
+ return;
const int len = length(item);
int num_glyphs = length(item);
const QChar *str = layoutData->string.unicode() + si.position;
ushort upperCased[256];
- if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase) {
+ if (hasCaseChange(si)) {
ushort *uc = upperCased;
if (len > 256)
uc = new ushort[len];
@@ -1071,7 +1079,14 @@ void QTextEngine::shapeTextWithCE(int item) const
}
while (true) {
- ensureSpace(num_glyphs);
+ if (! ensureSpace(num_glyphs)) {
+ // If str is converted to uppercase/lowercase form with a new buffer,
+ // we need to delete that buffer before return for error
+ const ushort *uc = reinterpret_cast<const ushort *>(str);
+ if (hasCaseChange(si) && uc != upperCased)
+ delete [] uc;
+ return;
+ }
num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
QGlyphLayout g = availableGlyphs(&si);
@@ -1092,9 +1107,7 @@ void QTextEngine::shapeTextWithCE(int item) const
layoutData->used += si.num_glyphs;
const ushort *uc = reinterpret_cast<const ushort *>(str);
- if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase)
- && uc != upperCased)
+ if (hasCaseChange(si) && uc != upperCased)
delete [] uc;
}
#endif
@@ -1133,8 +1146,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel;
HB_UChar16 upperCased[256]; // XXX what about making this 4096, so we don't have to extend it ever.
- if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase) {
+ if (hasCaseChange(si)) {
HB_UChar16 *uc = upperCased;
if (entire_shaper_item.item.length > 256)
uc = new HB_UChar16[entire_shaper_item.item.length];
@@ -1156,17 +1168,24 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics;
entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length));
- ensureSpace(entire_shaper_item.num_glyphs);
+ if (! ensureSpace(entire_shaper_item.num_glyphs)) {
+ if (hasCaseChange(si))
+ delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
+ return;
+ }
QGlyphLayout initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
- ensureSpace(entire_shaper_item.num_glyphs);
+ if (! ensureSpace(entire_shaper_item.num_glyphs)) {
+ if (hasCaseChange(si))
+ delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
+ return;
+ }
initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
if (!stringToGlyphs(&entire_shaper_item, &initialGlyphs, font)) {
// ############ if this happens there's a bug in the fontengine
- if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase
- || si.analysis.flags == QScriptAnalysis::Lowercase) && entire_shaper_item.string != upperCased)
+ if (hasCaseChange(si) && entire_shaper_item.string != upperCased)
delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
return;
}
@@ -1231,7 +1250,11 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
remaining_glyphs -= shaper_item.initialGlyphCount;
do {
- ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs);
+ if (! ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs)) {
+ if (hasCaseChange(si))
+ delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
+ return;
+ }
const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
@@ -1271,8 +1294,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
layoutData->used += si.num_glyphs;
- if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase)
- && entire_shaper_item.string != upperCased)
+ if (hasCaseChange(si) && entire_shaper_item.string != upperCased)
delete [] const_cast<HB_UChar16 *>(entire_shaper_item.string);
}
@@ -1317,7 +1339,8 @@ const HB_CharAttributes *QTextEngine::attributes() const
return (HB_CharAttributes *) layoutData->memory;
itemize();
- ensureSpace(layoutData->string.length());
+ if (! ensureSpace(layoutData->string.length()))
+ return NULL;
QVarLengthArray<HB_ScriptItem> hbScriptItems(layoutData->items.size());
@@ -1864,7 +1887,10 @@ void QTextEngine::justify(const QScriptLine &line)
// don't include trailing white spaces when doing justification
int line_length = line.length;
- const HB_CharAttributes *a = attributes()+line.from;
+ const HB_CharAttributes *a = attributes();
+ if (! a)
+ return;
+ a += line.from;
while (line_length && a[line_length-1].whiteSpace)
--line_length;
// subtract one char more, as we can't justfy after the last character
@@ -2045,7 +2071,7 @@ QTextEngine::LayoutData::LayoutData()
memory_on_stack = false;
used = 0;
hasBidi = false;
- inLayout = false;
+ layoutState = LayoutEmpty;
haveCharAttributes = false;
logClustersPtr = 0;
available_glyphs = 0;
@@ -2079,7 +2105,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int
}
used = 0;
hasBidi = false;
- inLayout = false;
+ layoutState = LayoutEmpty;
haveCharAttributes = false;
}
@@ -2090,12 +2116,12 @@ QTextEngine::LayoutData::~LayoutData()
memory = 0;
}
-void QTextEngine::LayoutData::reallocate(int totalGlyphs)
+bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
{
Q_ASSERT(totalGlyphs >= glyphLayout.numGlyphs);
if (memory_on_stack && available_glyphs >= totalGlyphs) {
glyphLayout.grow(glyphLayout.data(), totalGlyphs);
- return;
+ return true;
}
int space_charAttributes = sizeof(HB_CharAttributes)*string.length()/sizeof(void*) + 1;
@@ -2103,7 +2129,14 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs)
int space_glyphs = QGlyphLayout::spaceNeededForGlyphLayout(totalGlyphs)/sizeof(void*) + 2;
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
- Q_ASSERT(newAllocated >= allocated);
+ // These values can be negative if the length of string/glyphs causes overflow,
+ // we can't layout such a long string all at once, so return false here to
+ // indicate there is a failure
+ if (space_charAttributes < 0 || space_logClusters < 0 || space_glyphs < 0 || newAllocated < allocated) {
+ layoutState = LayoutFailed;
+ return false;
+ }
+
void **newMem = memory;
newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *));
Q_CHECK_PTR(newMem);
@@ -2124,6 +2157,7 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs)
glyphLayout.grow(reinterpret_cast<char *>(m), totalGlyphs);
allocated = newAllocated;
+ return true;
}
// grow to the new size, copying the existing data to the new layout
@@ -2155,7 +2189,7 @@ void QTextEngine::freeMemory()
} else {
layoutData->used = 0;
layoutData->hasBidi = false;
- layoutData->inLayout = false;
+ layoutData->layoutState = LayoutEmpty;
layoutData->haveCharAttributes = false;
}
for (int i = 0; i < lines.size(); ++i) {
@@ -2314,6 +2348,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
shape(i);
HB_CharAttributes *attributes = const_cast<HB_CharAttributes *>(this->attributes());
+ if (!attributes)
+ return QString();
+
unsigned short *logClusters = this->logClusters(&si);
QGlyphLayout glyphs = shapedGlyphs(&si);
@@ -2385,6 +2422,8 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
return QString();
const HB_CharAttributes *attributes = this->attributes();
+ if (!attributes)
+ return QString();
if (mode == Qt::ElideRight) {
QFixed currentWidth;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index e623fa5..4cbe81f 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -416,6 +416,11 @@ class QTextFormatCollection;
class Q_GUI_EXPORT QTextEngine {
public:
+ enum LayoutState {
+ LayoutEmpty,
+ InLayout,
+ LayoutFailed,
+ };
struct LayoutData {
LayoutData(const QString &str, void **stack_memory, int mem_size);
LayoutData();
@@ -428,11 +433,11 @@ public:
QGlyphLayout glyphLayout;
mutable int used;
uint hasBidi : 1;
- uint inLayout : 1;
+ uint layoutState : 2;
uint memory_on_stack : 1;
bool haveCharAttributes;
QString string;
- void reallocate(int totalGlyphs);
+ bool reallocate(int totalGlyphs);
};
QTextEngine(LayoutData *data);
@@ -520,9 +525,10 @@ public:
return layoutData->glyphLayout.mid(si->glyph_data_offset, si->num_glyphs);
}
- inline void ensureSpace(int nGlyphs) const {
+ inline bool ensureSpace(int nGlyphs) const {
if (layoutData->glyphLayout.numGlyphs - layoutData->used < nGlyphs)
- layoutData->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4);
+ return layoutData->reallocate((((layoutData->used + nGlyphs)*3/2 + 15) >> 4) << 4);
+ return true;
}
void freeMemory();
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 674064e..7d5fa43 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -74,6 +74,8 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line
int pos = line.length;
const HB_CharAttributes *attributes = eng->attributes();
+ if (!attributes)
+ return QFixed();
while (pos > 0 && attributes[line.from + pos - 1].whiteSpace)
--pos;
return eng->width(line.from + pos, line.length - pos);
@@ -601,7 +603,7 @@ bool QTextLayout::cacheEnabled() const
void QTextLayout::beginLayout()
{
#ifndef QT_NO_DEBUG
- if (d->layoutData && d->layoutData->inLayout) {
+ if (d->layoutData && d->layoutData->layoutState == QTextEngine::InLayout) {
qWarning("QTextLayout::beginLayout: Called while already doing layout");
return;
}
@@ -609,7 +611,7 @@ void QTextLayout::beginLayout()
d->invalidate();
d->clearLineData();
d->itemize();
- d->layoutData->inLayout = true;
+ d->layoutData->layoutState = QTextEngine::InLayout;
}
/*!
@@ -618,7 +620,7 @@ void QTextLayout::beginLayout()
void QTextLayout::endLayout()
{
#ifndef QT_NO_DEBUG
- if (!d->layoutData || !d->layoutData->inLayout) {
+ if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) {
qWarning("QTextLayout::endLayout: Called without beginLayout()");
return;
}
@@ -627,7 +629,7 @@ void QTextLayout::endLayout()
if (l && d->lines.at(l-1).length < 0) {
QTextLine(l-1, d).setNumColumns(INT_MAX);
}
- d->layoutData->inLayout = false;
+ d->layoutData->layoutState = QTextEngine::LayoutEmpty;
if (!d->cacheGlyphs)
d->freeMemory();
}
@@ -757,11 +759,14 @@ bool QTextLayout::isValidCursorPosition(int pos) const
QTextLine QTextLayout::createLine()
{
#ifndef QT_NO_DEBUG
- if (!d->layoutData || !d->layoutData->inLayout) {
+ if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) {
qWarning("QTextLayout::createLine: Called without layouting");
return QTextLine();
}
#endif
+ if (d->layoutData->layoutState == QTextEngine::LayoutFailed)
+ return QTextLine();
+
int l = d->lines.size();
if (l && d->lines.at(l-1).length < 0) {
QTextLine(l-1, d).setNumColumns(INT_MAX);
@@ -1704,14 +1709,18 @@ namespace {
return glyphs.glyphs[logClusters[currentPosition - 1]];
}
+ inline void adjustRightBearing(glyph_t glyph)
+ {
+ qreal rb;
+ fontEngine->getGlyphBearings(glyph, 0, &rb);
+ rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+ }
+
inline void adjustRightBearing()
{
if (currentPosition <= 0)
return;
-
- qreal rb;
- fontEngine->getGlyphBearings(currentGlyph(), 0, &rb);
- rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+ adjustRightBearing(currentGlyph());
}
inline void resetRightBearing()
@@ -1801,6 +1810,8 @@ void QTextLine::layout_helper(int maxGlyphs)
Qt::Alignment alignment = eng->option.alignment();
const HB_CharAttributes *attributes = eng->attributes();
+ if (!attributes)
+ return;
lbh.currentPosition = line.from;
int end = 0;
lbh.logClusters = eng->layoutData->logClustersPtr;
@@ -1814,6 +1825,8 @@ void QTextLine::layout_helper(int maxGlyphs)
if (!current.num_glyphs) {
eng->shape(item);
attributes = eng->attributes();
+ if (!attributes)
+ return;
lbh.logClusters = eng->layoutData->logClustersPtr;
}
lbh.currentPosition = qMax(line.from, current.position);
@@ -1892,6 +1905,9 @@ void QTextLine::layout_helper(int maxGlyphs)
} else {
lbh.whiteSpaceOrObject = false;
bool sb_or_ws = false;
+ glyph_t previousGlyph = 0;
+ if (lbh.currentPosition > 0 && lbh.logClusters[lbh.currentPosition - 1] <lbh.glyphs.numGlyphs)
+ previousGlyph = lbh.currentGlyph(); // needed to calculate right bearing later
do {
addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
current, lbh.logClusters, lbh.glyphs);
@@ -1935,9 +1951,17 @@ void QTextLine::layout_helper(int maxGlyphs)
// We ignore the right bearing if the minimum negative bearing is too little to
// expand the text beyond the edge.
if (sb_or_ws|breakany) {
+ QFixed rightBearing = lbh.rightBearing; // store previous right bearing
+#if !defined(Q_WS_MAC)
if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
+#endif
lbh.adjustRightBearing();
if (lbh.checkFullOtherwiseExtend(line)) {
+ // we are too wide, fix right bearing
+ if (rightBearing <= 0)
+ lbh.rightBearing = rightBearing; // take from cache
+ else if (previousGlyph > 0)
+ lbh.adjustRightBearing(previousGlyph);
if (!breakany) {
line.textWidth += lbh.softHyphenWidth;
}
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 38cae8b..d3084cf 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -175,12 +175,12 @@ QT_BEGIN_NAMESPACE
When using this flag with sequential upload data, the ContentLengthHeader
header must be set.
- \value HttpPipeliningAllowedAttribute
+ \value HttpPipeliningAllowedAttribute
Requests only, type: QVariant::Bool (default: false)
Indicates whether the QNetworkAccessManager code is
allowed to use HTTP pipelining with this request.
- \value HttpPipeliningWasUsedAttribute
+ \value HttpPipeliningWasUsedAttribute
Replies only, type: QVariant::Bool
Indicates whether the HTTP pipelining was used for receiving
this reply.
@@ -192,25 +192,31 @@ QT_BEGIN_NAMESPACE
when calling QNetworkAccessManager::sendCustomRequest().
\value CookieLoadControlAttribute
- Requests only, type: QVariant::Int (default:
- QNetworkRequest::Automatic) Indicates whether to send 'Cookie'
- headers in the request. This attribute is set to false by
- QtWebKit when creating a cross-origin XMLHttpRequest where
- withCredentials has not been set explicitly to true by the
- Javascript that created the request. See
- \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}
- {here} for more information.
-
- \value CookieSaveControlAttribute
+ Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic)
+ Indicates whether to send 'Cookie' headers in the request.
+
+ This attribute is set to false by QtWebKit when creating a cross-origin
+ XMLHttpRequest where withCredentials has not been set explicitly to true by the
+ Javascript that created the request.
+
+ See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag}{here} for more information.
+
+ (This value was introduced in 4.7.)
+
+
+ \value CookieSaveControlAttribute
Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic)
Indicates whether to save 'Cookie' headers received from the server in reply
to the request.
This attribute is set to false by QtWebKit when creating a cross-origin
XMLHttpRequest where withCredentials has not been set explicitly to true by the
Javascript that created the request.
+
See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information.
- \value AuthenticationReuseAttribute
+ (This value was introduced in 4.7.)
+
+ \value AuthenticationReuseAttribute
Requests only, type: QVariant::Int (default: QNetworkRequest::Automatic)
Indicates whether to use cached authorization credentials in the request,
if available. If this is set to QNetworkRequest::Manual and the authentication
@@ -219,11 +225,16 @@ QT_BEGIN_NAMESPACE
This attribute is set to QNetworkRequest::Manual by QtWebKit when creating a cross-origin
XMLHttpRequest where withCredentials has not been set explicitly to true by the
Javascript that created the request.
+
See \l{http://www.w3.org/TR/XMLHttpRequest2/#credentials-flag} {here} for more information.
+ (This value was introduced in 4.7.)
+
\omitvalue MaximumDownloadBufferSizeAttribute
+ (This value was introduced in 4.7.)
\omitvalue DownloadBufferAttribute
+ (This value was introduced in 4.7.)
\value User
Special type. Additional information can be passed in
diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h
index e4f762a..18b92a9 100644
--- a/src/network/bearer/qnetworkconfiguration.h
+++ b/src/network/bearer/qnetworkconfiguration.h
@@ -120,7 +120,9 @@ public:
Purpose purpose() const;
// Required to maintain source compatibility with Qt Mobility.
+#ifdef QT_DEPRECATED
QT_DEPRECATED QString bearerName() const;
+#endif
BearerType bearerType() const;
QString bearerTypeName() const;
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 1267e7e..662c796 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -7418,8 +7418,10 @@ bool QDomHandler::startElement(const QString& nsURI, const QString&, const QStri
n = doc->createElement(qName);
}
- if (n)
- n->setLocation(locator->lineNumber(), locator->columnNumber());
+ if (!n)
+ return false;
+
+ n->setLocation(locator->lineNumber(), locator->columnNumber());
node->appendChild(n);
node = n;
diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
index 7f2ad9f..0f9760d 100644
--- a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
+++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp
@@ -1355,7 +1355,7 @@ bool QXmlItem::isNull() const
QAbstractXmlNodeModel for its existence, the only way you can create
an instance of QXmlNodeModelIndex is by asking the node model to
create one for you with QAbstractXmlNodeModel::createIndex(). Since
- that function is protected, it is usually a good ide to write a
+ that function is protected, it is usually a good idea to write a
public function that creates a QXmlNodeModelIndex from arguments that
are appropriate for your particular node model.