summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@nokia.com>2010-08-19 09:52:55 (GMT)
committerPaul Olav Tvete <paul.tvete@nokia.com>2010-08-19 09:52:55 (GMT)
commit872ccdcc090cec252cea2109d2fc9f2f2ee4c795 (patch)
tree7b14b977528cb6e833a765afce3c9bf6e55c94af /src/gui
parent74d519f87e804b624ac76337fe2905d512d363fc (diff)
parentf6cfafde26b4735965be8df0d11e9d7c297c75b9 (diff)
downloadQt-872ccdcc090cec252cea2109d2fc9f2f2ee4c795.zip
Qt-872ccdcc090cec252cea2109d2fc9f2f2ee4c795.tar.gz
Qt-872ccdcc090cec252cea2109d2fc9f2f2ee4c795.tar.bz2
Merge remote branch 'qt/4.7' into lighthouse-4.7
Conflicts: src/opengl/qgl_p.h
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm11
-rw-r--r--src/gui/egl/qegl_x11.cpp2
-rw-r--r--src/gui/embedded/qkbdlinuxinput_qws.cpp2
-rw-r--r--src/gui/embedded/qkbdqnx_qws.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp38
-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/qgraphicsscene.cpp5
-rw-r--r--src/gui/graphicsview/qgraphicstransform.cpp39
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp3
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp266
-rw-r--r--src/gui/graphicsview/qgridlayoutengine_p.h23
-rw-r--r--src/gui/gui.pro30
-rw-r--r--src/gui/image/image.pri1
-rw-r--r--src/gui/image/qimage.cpp84
-rw-r--r--src/gui/image/qimage_neon.cpp114
-rw-r--r--src/gui/image/qimage_ssse3.cpp5
-rw-r--r--src/gui/image/qjpeghandler.cpp36
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp49
-rw-r--r--src/gui/inputmethod/qinputcontextfactory.cpp2
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp8
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp2
-rw-r--r--src/gui/kernel/qapplication.cpp33
-rw-r--r--src/gui/kernel/qapplication.h3
-rw-r--r--src/gui/kernel/qapplication_p.h1
-rw-r--r--src/gui/kernel/qapplication_s60.cpp132
-rw-r--r--src/gui/kernel/qapplication_win.cpp6
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm5
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac_p.h1
-rw-r--r--src/gui/kernel/qevent.cpp5
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm12
-rw-r--r--src/gui/kernel/qgesture.cpp28
-rw-r--r--src/gui/kernel/qgesturemanager.cpp7
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp3
-rw-r--r--src/gui/kernel/qpalette.cpp4
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm24
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h1
-rw-r--r--src/gui/kernel/qt_s60_p.h3
-rw-r--r--src/gui/kernel/qwidget.cpp61
-rw-r--r--src/gui/kernel/qwidget_mac.mm18
-rw-r--r--src/gui/kernel/qwidget_p.h17
-rw-r--r--src/gui/kernel/qwidget_s60.cpp6
-rw-r--r--src/gui/kernel/qwidget_win.cpp4
-rw-r--r--src/gui/painting/painting.pri22
-rw-r--r--src/gui/painting/qbackingstore.cpp9
-rw-r--r--src/gui/painting/qdrawhelper.cpp13
-rw-r--r--src/gui/painting/qdrawhelper_p.h140
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp41
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp253
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h8
-rw-r--r--src/gui/painting/qgraphicssystem_runtime.cpp109
-rw-r--r--src/gui/painting/qgraphicssystem_runtime_p.h17
-rw-r--r--src/gui/painting/qgrayraster.c80
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp24
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp84
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp6
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp12
-rw-r--r--src/gui/s60framework/qs60mainapplication.cpp9
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp45
-rw-r--r--src/gui/s60framework/qs60maindocument.cpp6
-rw-r--r--src/gui/s60framework/qs60maindocument.h2
-rw-r--r--src/gui/styles/qmacstyle_mac.h4
-rw-r--r--src/gui/styles/qmacstyle_mac.mm13
-rw-r--r--src/gui/styles/qmacstyle_mac_p.h2
-rw-r--r--src/gui/styles/qs60style_s60.cpp6
-rw-r--r--src/gui/styles/qstyle.cpp2
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp2
-rw-r--r--src/gui/text/qfontengine_mac.mm32
-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/gui/text/qtextobject.cpp4
-rw-r--r--src/gui/util/qcompleter.cpp2
-rw-r--r--src/gui/widgets/qcocoamenu_mac.mm12
-rw-r--r--src/gui/widgets/qcocoamenu_mac_p.h1
-rw-r--r--src/gui/widgets/qcombobox.cpp2
-rw-r--r--src/gui/widgets/qcommandlinkbutton.cpp2
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp1
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp2
-rw-r--r--src/gui/widgets/qmenu.cpp4
-rw-r--r--src/gui/widgets/qmenubar.cpp2
-rw-r--r--src/gui/widgets/qprintpreviewwidget.cpp2
-rw-r--r--src/gui/widgets/qpushbutton.cpp8
-rw-r--r--src/gui/widgets/qtoolbarextension.cpp2
88 files changed, 1735 insertions, 570 deletions
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
index bb8ef3f..9c63dfa 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -131,6 +131,7 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
- (QFont)qtFont;
- (void)finishOffWithCode:(NSInteger)result;
- (void)cleanUpAfterMyself;
+- (void)setSubwindowStacking;
@end
static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
@@ -187,6 +188,12 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
[cancelButton setTarget:self];
}
+ mQtFont = new QFont();
+ return self;
+}
+
+- (void)setSubwindowStacking
+{
#ifdef QT_MAC_USE_COCOA
// Stack the native dialog in front of its parent, if any:
QFontDialog *q = mPriv->fontDialog();
@@ -199,9 +206,6 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
}
}
#endif
-
- mQtFont = new QFont();
- return self;
}
- (void)dealloc
@@ -610,6 +614,7 @@ void QFontDialogPrivate::createNSFontPanelDelegate()
[ourPanel setFrame:frameRect display:NO];
[ourPanel center];
}
+ [del setSubwindowStacking];
NSString *title = @"Select font";
[ourPanel setTitle:title];
}
diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp
index fea6e8d..15cc109 100644
--- a/src/gui/egl/qegl_x11.cpp
+++ b/src/gui/egl/qegl_x11.cpp
@@ -165,7 +165,7 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config)
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"))
+ if (QEgl::hasExtension("EGL_NV_post_convert_rounding"))
return visualId;
int visualRedSize = countBits(chosenVisualInfo->red_mask);
diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp
index 6c91a08..f53c444 100644
--- a/src/gui/embedded/qkbdlinuxinput_qws.cpp
+++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp
@@ -138,7 +138,7 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h,
// record the original mode so we can restore it again in the destructor.
::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode);
- // setting this tranlation mode is even needed in INPUT mode to prevent
+ // setting this translation mode is even needed in INPUT mode to prevent
// the shell from also interpreting codes, if the process has a tty
// attached: e.g. Ctrl+C wouldn't copy, but kill the application.
::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW);
diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp
index fbc683e..72d1cb5 100644
--- a/src/gui/embedded/qkbdqnx_qws.cpp
+++ b/src/gui/embedded/qkbdqnx_qws.cpp
@@ -150,7 +150,7 @@ void QWSQnxKeyboardHandler::socketActivated()
// figure out whether it's a press
bool isPress = packet.data.key_cap & KEY_DOWN;
- // figure out wheter the key is still pressed and the key event is repeated
+ // figure out whether the key is still pressed and the key event is repeated
bool isRepeat = packet.data.key_cap & KEY_REPEAT;
Qt::Key key = Qt::Key_unknown;
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 1626d83..0b3b164 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3259,8 +3259,12 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
QGraphicsItem *p = parent;
while (p) {
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
p->d_ptr->focusScopeItem = q_ptr;
if (!p->focusItem() && !focusFromShow) {
+ if (oldFocusScopeItem)
+ oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
+ focusScopeItemChange(true);
// If you call setFocus on a child of a focus scope that
// doesn't currently have a focus item, then stop.
return;
@@ -5595,6 +5599,7 @@ void QGraphicsItemPrivate::subFocusItemChange()
*/
void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
{
+ Q_UNUSED(isSubFocusItem);
}
/*!
@@ -7753,6 +7758,21 @@ void QGraphicsItemPrivate::resetHeight()
}
/*!
+ \property QGraphicsObject::children
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::width
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::height
+ \internal
+*/
+
+/*!
\property QGraphicsObject::parent
\brief the parent of the item
@@ -7965,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/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 48a0093..a98ce6f 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -831,6 +831,11 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
#endif //QT_NO_IM
}
+ // This handles the case that the item has been removed from the
+ // scene in response to the FocusOut event.
+ if (item && item->scene() != q)
+ item = 0;
+
if (item)
focusItem = item;
updateInputMethodSensitivityInViews();
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp
index 986bee6..bd3f2ef 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/gui/graphicsview/qgraphicstransform.cpp
@@ -345,6 +345,24 @@ void QGraphicsScale::applyTo(QMatrix4x4 *matrix) const
*/
/*!
+ \fn QGraphicsScale::xScaleChanged()
+
+ QGraphicsScale emits this signal when its xScale changes.
+*/
+
+/*!
+ \fn QGraphicsScale::yScaleChanged()
+
+ QGraphicsScale emits this signal when its yScale changes.
+*/
+
+/*!
+ \fn QGraphicsScale::zScaleChanged()
+
+ QGraphicsScale emits this signal when its zScale changes.
+*/
+
+/*!
\fn QGraphicsScale::scaleChanged()
This signal is emitted whenever the xScale, yScale, or zScale
@@ -565,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/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index c486c45..0fabd18 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -385,12 +385,12 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
if (wd->inSetPos) {
//set the new pos
d->geom.moveTopLeft(pos());
+ emit geometryChanged();
return;
}
}
QSizeF oldSize = size();
QGraphicsLayoutItem::setGeometry(newGeom);
- emit geometryChanged();
// Send resize event
bool resized = newGeom.size() != oldSize;
if (resized) {
@@ -403,6 +403,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
emit heightChanged();
QApplication::sendEvent(this, &re);
}
+ emit geometryChanged();
}
/*!
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 41de3f2..ad79130 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -77,20 +77,28 @@ 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 {
- mmx:DEFINES += QT_HAVE_MMX
- 3dnow:DEFINES += QT_HAVE_3DNOW
- sse:DEFINES += QT_HAVE_SSE QT_HAVE_MMXEXT
- sse2:DEFINES += QT_HAVE_SSE2
- sse3:DEFINES += QT_HAVE_SSE3
- ssse3:DEFINES += QT_HAVE_SSSE3
- sse4_1:DEFINES += QT_HAVE_SSE4_1
- sse4_2:DEFINES += QT_HAVE_SSE4_2
- avx:DEFINES += QT_HAVE_AVX
- iwmmxt:DEFINES += QT_HAVE_IWMMXT
-
win32-g++*|!win32:!*-icc* {
mmx {
mmx_compiler.commands = $$QMAKE_CXX -c -Winline
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 1d89a68..92ea397 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -99,5 +99,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 30cf758..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
}
/*!
@@ -4829,7 +4837,7 @@ QImage QImage::rgbSwapped() const
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
uint *q = (uint*)res.scanLine(i);
- uint *p = (uint*)scanLine(i);
+ uint *p = (uint*)constScanLine(i);
uint *end = p + d->width;
while (p < end) {
*q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
@@ -4843,7 +4851,7 @@ QImage QImage::rgbSwapped() const
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
ushort *q = (ushort*)res.scanLine(i);
- const ushort *p = (const ushort*)scanLine(i);
+ const ushort *p = (const ushort*)constScanLine(i);
const ushort *end = p + d->width;
while (p < end) {
*q = ((*p << 11) & 0xf800) | ((*p >> 11) & 0x1f) | (*p & 0x07e0);
@@ -4856,12 +4864,15 @@ QImage QImage::rgbSwapped() const
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- quint8 *p = (quint8*)scanLine(i);
+ const quint8 *p = constScanLine(i);
+ quint8 *q = res.scanLine(i);
const quint8 *end = p + d->width * sizeof(qargb8565);
while (p < end) {
- quint16 *q = reinterpret_cast<quint16*>(p + 1);
- *q = ((*q << 11) & 0xf800) | ((*q >> 11) & 0x1f) | (*q & 0x07e0);
+ q[0] = p[0];
+ q[1] = (p[1] & 0xe0) | (p[2] >> 3);
+ q[2] = (p[2] & 0x07) | (p[1] << 3);
p += sizeof(qargb8565);
+ q += sizeof(qargb8565);
}
}
break;
@@ -4870,7 +4881,7 @@ QImage QImage::rgbSwapped() const
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i));
- const qrgb666 *p = reinterpret_cast<const qrgb666*>(scanLine(i));
+ const qrgb666 *p = reinterpret_cast<const qrgb666*>(constScanLine(i));
const qrgb666 *end = p + d->width;
while (p < end) {
const QRgb rgb = quint32(*p++);
@@ -4882,12 +4893,15 @@ QImage QImage::rgbSwapped() const
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i));
- const qargb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i));
- const qargb6666 *end = p + d->width;
+ const quint8 *p = constScanLine(i);
+ const quint8 *end = p + d->width * sizeof(qargb6666);
+ quint8 *q = res.scanLine(i);
while (p < end) {
- const QRgb rgb = quint32(*p++);
- *q++ = qRgba(qBlue(rgb), qGreen(rgb), qRed(rgb), qAlpha(rgb));
+ q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0);
+ q[1] = (p[1] & 0xf) | (p[0] << 4);
+ q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3);
+ p += sizeof(qargb6666);
+ q += sizeof(qargb6666);
}
}
break;
@@ -4895,11 +4909,11 @@ QImage QImage::rgbSwapped() const
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- ushort *q = (ushort*)res.scanLine(i);
- const ushort *p = (const ushort*)scanLine(i);
- const ushort *end = p + d->width;
+ quint16 *q = (quint16*)res.scanLine(i);
+ const quint16 *p = (const quint16*)constScanLine(i);
+ const quint16 *end = p + d->width;
while (p < end) {
- *q = ((*p << 10) & 0x7800) | ((*p >> 10) & 0x1f) | (*p & 0x83e0);
+ *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0);
p++;
q++;
}
@@ -4909,12 +4923,15 @@ QImage QImage::rgbSwapped() const
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- quint8 *p = (quint8*)scanLine(i);
+ const quint8 *p = constScanLine(i);
+ quint8 *q = res.scanLine(i);
const quint8 *end = p + d->width * sizeof(qargb8555);
while (p < end) {
- quint16 *q = reinterpret_cast<quint16*>(p + 1);
- *q = ((*q << 10) & 0x7800) | ((*q >> 10) & 0x1f) | (*q & 0x83e0);
+ q[0] = p[0];
+ q[1] = (p[1] & 0xe0) | (p[2] >> 2);
+ q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f);
p += sizeof(qargb8555);
+ q += sizeof(qargb8555);
}
}
break;
@@ -4922,8 +4939,8 @@ QImage QImage::rgbSwapped() const
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
- const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
+ quint8 *q = res.scanLine(i);
+ const quint8 *p = constScanLine(i);
const quint8 *end = p + d->width * sizeof(qrgb888);
while (p < end) {
q[0] = p[2];
@@ -4935,32 +4952,17 @@ QImage QImage::rgbSwapped() const
}
break;
case Format_RGB444:
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- for (int i = 0; i < d->height; i++) {
- quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
- const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
- const quint8 *end = p + d->width * sizeof(qrgb444);
- while (p < end) {
- q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8);
- q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0);
- q += sizeof(qrgb444);
- p += sizeof(qrgb444);
- }
- }
- break;
case Format_ARGB4444_Premultiplied:
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
- const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
- const quint8 *end = p + d->width * sizeof(qargb4444);
+ quint16 *q = reinterpret_cast<quint16*>(res.scanLine(i));
+ const quint16 *p = reinterpret_cast<const quint16*>(constScanLine(i));
+ const quint16 *end = p + d->width;
while (p < end) {
- q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8);
- q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0);
- q += sizeof(qargb4444);
- p += sizeof(qargb4444);
+ *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8);
+ p++;
+ q++;
}
}
break;
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/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp
index 1c664f2..9aed011 100644
--- a/src/gui/image/qimage_ssse3.cpp
+++ b/src/gui/image/qimage_ssse3.cpp
@@ -45,13 +45,12 @@
#ifdef QT_HAVE_SSSE3
-#include <stdio.h>
QT_BEGIN_NAMESPACE
// Convert a scanline of RGB888 (src) to RGB32 (dst)
// src must be at least len * 3 bytes
// dst must be at least len * 4 bytes
-inline void convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len)
+Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len)
{
quint32 *const end = dst + len;
@@ -139,7 +138,7 @@ void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::
quint32 *dest_data = (quint32 *) dest->data;
for (int i = 0; i < src->height; ++i) {
- convert_rgb888_to_rgb32_ssse3(dest_data, src_data, src->width);
+ qt_convert_rgb888_to_rgb32_ssse3(dest_data, src_data, src->width);
src_data += src->bytes_per_line;
dest_data = (quint32 *)((uchar*)dest_data + dest->bytes_per_line);
}
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 972dd65..eda5efb 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -45,6 +45,7 @@
#include <qvariant.h>
#include <qvector.h>
#include <qbuffer.h>
+#include <private/qsimd_p.h>
#include <stdio.h> // jpeglib needs this to be pre-included
#include <setjmp.h>
@@ -75,6 +76,19 @@ extern "C" {
QT_BEGIN_NAMESPACE
+void QT_FASTCALL convert_rgb888_to_rgb32_C(quint32 *dst, const uchar *src, int len)
+{
+ // Expand 24->32 bpp.
+ for (int i = 0; i < len; ++i) {
+ *dst++ = qRgb(src[0], src[1], src[2]);
+ src += 3;
+ }
+}
+
+typedef void (QT_FASTCALL *Rgb888ToRgb32Converter)(quint32 *dst, const uchar *src, int len);
+
+static Rgb888ToRgb32Converter rgb888ToRgb32ConverterPtr = convert_rgb888_to_rgb32_C;
+
struct my_error_mgr : public jpeg_error_mgr {
jmp_buf setjmp_buffer;
};
@@ -393,13 +407,9 @@ static bool read_jpeg_image(QImage *outImage,
continue; // Haven't reached the starting line yet.
if (info->output_components == 3) {
- // Expand 24->32 bpp.
uchar *in = rows[0] + clip.x() * 3;
QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- *out++ = qRgb(in[0], in[1], in[2]);
- in += 3;
- }
+ rgb888ToRgb32ConverterPtr(out, in, clip.width());
} else if (info->out_color_space == JCS_CMYK) {
// Convert CMYK->RGB.
uchar *in = rows[0] + clip.x() * 4;
@@ -793,6 +803,22 @@ bool QJpegHandlerPrivate::read(QImage *image)
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
+ 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);
+
+ if (features & SSSE3)
+ rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3;
+#endif // QT_HAVE_SSSE3
}
QJpegHandler::~QJpegHandler()
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 394d374..c4d60a5 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -364,10 +364,10 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
commitTemporaryPreeditString();
- bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly;
- bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly
- || hints & ImhLowercaseOnly);
+ const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
+ const bool anytextmodes = hints & (ImhUppercaseOnly | ImhLowercaseOnly | ImhEmailCharactersOnly | ImhUrlCharactersOnly);
+ const bool numbersOnly = anynumbermodes && !anytextmodes;
+ const bool noOnlys = !(hints & ImhExclusiveInputMask);
TInt flags;
Qt::InputMethodHints oldHints = hints;
@@ -379,8 +379,7 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
}
if (!noOnlys) {
// Make sure that the preference is within the permitted set.
- if (hints & ImhPreferNumbers && !(hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly)) {
+ if (hints & ImhPreferNumbers && !anynumbermodes) {
hints &= ~ImhPreferNumbers;
} else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
hints &= ~ImhPreferUppercase;
@@ -393,8 +392,7 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
hints |= ImhPreferLowercase;
} else if (hints & ImhUppercaseOnly) {
hints |= ImhPreferUppercase;
- } else if (hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
- || hints & ImhDialableCharactersOnly) {
+ } else if (numbersOnly) {
hints |= ImhPreferNumbers;
}
}
@@ -408,13 +406,21 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
m_fepState->SetCurrentInputMode(EAknEditorTextInputMode);
}
flags = 0;
- if (numbersOnly) {
+ if (noOnlys || (anynumbermodes && anytextmodes)) {
+ flags = EAknEditorAllInputModes;
+ }
+ else if (anynumbermodes) {
flags |= EAknEditorNumericInputMode;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0
+ && ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly))) {
+ //workaround - the * key does not launch the symbols menu, making it impossible to use these modes unless text mode is enabled.
+ flags |= EAknEditorTextInputMode;
+ }
}
- if (hints & ImhUppercaseOnly || hints & ImhLowercaseOnly) {
+ else if (anytextmodes) {
flags |= EAknEditorTextInputMode;
}
- if (flags == 0) {
+ else {
flags = EAknEditorAllInputModes;
}
m_fepState->SetPermittedInputModes(flags);
@@ -461,24 +467,33 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
if (hints & ImhNoPredictiveText || hints & ImhHiddenText) {
flags |= EAknEditorFlagNoT9;
}
+ // if alphanumeric input, or if multiple incompatible number modes are selected;
+ // then make all symbols available in numeric mode too.
+ if (!numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly)))
+ flags |= EAknEditorFlagUseSCTNumericCharmap;
m_fepState->SetFlags(flags);
ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
- if (hints & ImhFormattedNumbersOnly) {
+ if (hints & ImhDialableCharactersOnly) {
+ // This is first, because if (ImhDialableCharactersOnly | ImhFormattedNumbersOnly)
+ // is specified, this one is more natural (# key enters a #)
+ flags = EAknEditorStandardNumberModeKeymap;
+ } else if (hints & ImhFormattedNumbersOnly) {
+ // # key enters decimal point
flags = EAknEditorCalculatorNumberModeKeymap;
} else if (hints & ImhDigitsOnly) {
+ // This is last, because it is most restrictive (# key is inactive)
flags = EAknEditorPlainNumberModeKeymap;
} else {
- // ImhDialableCharactersOnly is the fallback as well, so we don't need to check for
- // that flag.
flags = EAknEditorStandardNumberModeKeymap;
}
m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
- if (hints & ImhEmailCharactersOnly) {
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else if (hints & ImhUrlCharactersOnly) {
+ if (hints & ImhUrlCharactersOnly) {
+ // URL characters is everything except space, so a superset of the other restrictions
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if (hints & ImhEmailCharactersOnly) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
} else {
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
}
diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp
index ec8d8e2..865c1b2 100644
--- a/src/gui/inputmethod/qinputcontextfactory.cpp
+++ b/src/gui/inputmethod/qinputcontextfactory.cpp
@@ -73,7 +73,7 @@
#endif
#ifdef Q_WS_S60
#include "qcoefepinputcontext_p.h"
-#include "akninputlanguageinfo.h"
+#include "AknInputLanguageInfo.h"
#endif
#include "private/qfactoryloader_p.h"
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 97499f3..4ffd284 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -2270,9 +2270,11 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
} else {
d->selectionModel->setCurrentIndex(newCurrent, command);
d->pressedPosition = visualRect(newCurrent).center() + d->offset();
- // We copy the same behaviour as for mousePressEvent().
- QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
- setSelection(rect, command);
+ if (newCurrent.isValid()) {
+ // We copy the same behaviour as for mousePressEvent().
+ QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
+ setSelection(rect, command);
+ }
}
event->accept();
return;
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index f9b6b94..953a7f1 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -774,7 +774,7 @@ void QSortFilterProxyModelPrivate::source_items_inserted(
if (model->rowCount(source_parent) == delta_item_count) {
// Items were inserted where there were none before.
// If it was new rows make sure to create mappings for columns so that a
- // valid mapping can be retreived later and vice-versa.
+ // valid mapping can be retrieved later and vice-versa.
QVector<int> &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns;
QVector<int> &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns;
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 08852af..b5af8b6 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -477,7 +477,7 @@ int qt_antialiasing_threshold = -1;
static int drag_time = 500;
#ifdef Q_OS_SYMBIAN
// The screens are a bit too small to for your thumb when using only 4 pixels drag distance.
-static int drag_distance = 8;
+static int drag_distance = 12;
#else
static int drag_distance = 4;
#endif
@@ -1060,6 +1060,18 @@ QApplication::~QApplication()
QApplicationPrivate::is_app_closing = true;
QApplicationPrivate::is_app_running = false;
+ // delete all widgets
+ if (QWidgetPrivate::allWidgets) {
+ QWidgetSet *mySet = QWidgetPrivate::allWidgets;
+ QWidgetPrivate::allWidgets = 0;
+ for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (!w->parent()) // window
+ w->destroy(true, true);
+ }
+ delete mySet;
+ }
+
delete qt_desktopWidget;
qt_desktopWidget = 0;
@@ -1080,18 +1092,6 @@ QApplication::~QApplication()
delete QWidgetPrivate::mapper;
QWidgetPrivate::mapper = 0;
- // delete all widgets
- if (QWidgetPrivate::allWidgets) {
- QWidgetSet *mySet = QWidgetPrivate::allWidgets;
- QWidgetPrivate::allWidgets = 0;
- for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
- register QWidget *w = *it;
- if (!w->parent()) // window
- w->destroy(true, true);
- }
- delete mySet;
- }
-
delete QApplicationPrivate::app_pal;
QApplicationPrivate::app_pal = 0;
delete QApplicationPrivate::sys_pal;
@@ -2549,6 +2549,13 @@ void QApplication::setActiveWindow(QWidget* act)
sendSpontaneousEvent(w, &activationChange);
}
+#ifdef QT_MAC_USE_COCOA
+ // In case the user clicked on a child window, we need to
+ // reestablish the stacking order of the window so
+ // it pops in front of other child windows in cocoa:
+ qt_cocoaStackChildWindowOnTopOfOtherChildren(window);
+#endif
+
for(int i = 0; i < toBeDeactivated.size(); ++i) {
QWidget *w = toBeDeactivated.at(i);
sendSpontaneousEvent(w, &windowDeactivate);
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 799d4c2..0242582 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -412,6 +412,9 @@ private:
#if defined(QT_RX71_MULTITOUCH)
Q_PRIVATE_SLOT(d_func(), void _q_readRX71MultiTouchEvents())
#endif
+#if defined(Q_OS_SYMBIAN)
+ Q_PRIVATE_SLOT(d_func(), void _q_aboutToQuit())
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 44aa20a..416ac06 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -561,6 +561,7 @@ public:
int symbianHandleCommand(const QSymbianEvent *symbianEvent);
int symbianResourceChange(const QSymbianEvent *symbianEvent);
+ void _q_aboutToQuit();
#endif
#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
void sendSyntheticEnterLeave(QWidget *widget);
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index f8734b2..670bf34 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -87,6 +87,10 @@
#include <hal.h>
#include <hal_data.h>
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+#include <graphics/wstfxconst.h>
+#endif
+
QT_BEGIN_NAMESPACE
// Goom Events through Window Server
@@ -131,6 +135,38 @@ void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, boo
}
#endif
+void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
+{
+ if (QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control)) {
+ QWidget *const widget = QWidgetPrivate::mapper->value(control);
+ QWidget *const window = widget->window();
+ if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
+ QWidgetBackingStoreTracker &backingStore = topData->backingStore;
+ if (visible) {
+ if (backingStore.data()) {
+ backingStore.registerWidget(widget);
+ } else {
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdRestoreLayer);
+#endif
+ backingStore.create(window);
+ backingStore.registerWidget(widget);
+ qt_widget_private(widget)->invalidateBuffer(widget->rect());
+ widget->repaint();
+ }
+ } else {
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdDeallocateLayer);
+#endif
+ backingStore.unregisterWidget(widget);
+ // In order to ensure that any resources used by the window surface
+ // are immediately freed, we flush the WSERV command buffer.
+ S60->wsSession().Flush();
+ }
+ }
+ }
+}
+
bool qt_nograb() // application no-grab option
{
#if defined(QT_DEBUG)
@@ -372,7 +408,7 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
{
if (!desktop)
{
- if (isWindowOwning or !qwidget->parentWidget())
+ if (isWindowOwning || !qwidget->parentWidget())
CreateWindowL(S60->windowGroup());
else
/**
@@ -395,6 +431,34 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
DrawableWindow()->SetPointerGrab(ETrue);
}
+
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ if (OwnsWindow()) {
+ TTfxWindowPurpose windowPurpose(ETfxPurposeNone);
+ switch (qwidget->windowType()) {
+ case Qt::Dialog:
+ windowPurpose = ETfxPurposeDialogWindow;
+ break;
+ case Qt::Popup:
+ windowPurpose = ETfxPurposePopupWindow;
+ break;
+ case Qt::Tool:
+ windowPurpose = ETfxPurposeToolWindow;
+ break;
+ case Qt::ToolTip:
+ windowPurpose = ETfxPurposeToolTipWindow;
+ break;
+ case Qt::SplashScreen:
+ windowPurpose = ETfxPurposeSplashScreenWindow;
+ break;
+ default:
+ windowPurpose = (isWindowOwning || !qwidget->parentWidget())
+ ? ETfxPurposeWindow : ETfxPurposeChildWindow;
+ break;
+ }
+ Window().SetPurpose(windowPurpose);
+ }
+#endif
}
QSymbianControl::~QSymbianControl()
@@ -1035,7 +1099,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
if (QApplicationPrivate::runtime_graphics_system) {
QRuntimeWindowSurface *rtSurface =
static_cast<QRuntimeWindowSurface*>(qwidget->windowSurface());
- s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface);
+ s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface.data());
} else
#endif
s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
@@ -1055,7 +1119,8 @@ void QSymbianControl::Draw(const TRect& controlRect) const
break;
case QWExtra::ZeroFill:
- if (Window().DisplayMode() == EColor16MA) {
+ if (Window().DisplayMode() == EColor16MA
+ || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) {
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.SetBrushColor(TRgb::Color16MA(0));
@@ -1328,7 +1393,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
// framework destruction.
TTrapHandler *origTrapHandler = User::TrapHandler();
- // The S60 framework has not been initalized. We need to do it.
+ // The S60 framework has not been initialized. We need to do it.
TApaApplicationFactory factory(S60->s60ApplicationFactory ?
S60->s60ApplicationFactory : newS60Application);
CApaCommandLine* commandLine = 0;
@@ -1442,6 +1507,8 @@ void qt_init(QApplicationPrivate * /* priv */, int)
S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
}
}
+ delete repository;
+ repository = 0;
#endif
#ifdef QT_KEYPAD_NAVIGATION
@@ -1483,6 +1550,10 @@ void qt_init(QApplicationPrivate * /* priv */, int)
systemFont.setFamily(systemFont.defaultFamily());
QApplicationPrivate::setSystemFont(systemFont);
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
+#endif
+
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
@@ -1506,7 +1577,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
*/
// Register WId with the metatype system. This is to enable
- // QWidgetPrivate::create_sys to used delayed slot invokation in order
+ // QWidgetPrivate::create_sys to used delayed slot invocation in order
// to destroy WId objects during reparenting.
qRegisterMetaType<WId>("WId");
}
@@ -1572,6 +1643,9 @@ bool QApplicationPrivate::modalState()
void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeEnter);
+#endif
if (widget) {
static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
// Modal partial screen dialogs (like queries) capture pointer events.
@@ -1587,6 +1661,9 @@ void QApplicationPrivate::enterModal_sys(QWidget *widget)
void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeExit);
+#endif
if (widget) {
static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
// ### FixMe: Add specialized behaviour for fullscreen modal dialogs
@@ -1877,29 +1954,10 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if (callSymbianEventFilters(symbianEvent))
return 1;
const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
- QWidget *w = QWidgetPrivate::mapper->value(control);
- QWidget *const window = w->window();
- if (!window->d_func()->maybeTopData())
- break;
- QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore;
- if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
- // Decrement backing store reference count
- backingStore.deref();
- // In order to ensure that any resources used by the window surface
- // are immediately freed, we flush the WSERV command buffer.
- S60->wsSession().Flush();
- } else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) {
- if (backingStore.data()) {
- // Increment backing store reference count
- backingStore.ref();
- } else {
- // Create backing store with an initial reference count of 1
- backingStore.create(window);
- backingStore.ref();
- w->d_func()->invalidateBuffer(w->rect());
- w->repaint();
- }
- }
+ if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
+ S60->controlVisibilityChanged(control, false);
+ else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+ S60->controlVisibilityChanged(control, true);
return 1;
}
break;
@@ -1953,13 +2011,6 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if (switchToSwRendering) {
QRuntimeGraphicsSystem *gs =
static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
-
- uint memoryUsage = gs->memoryUsage();
- uint memoryForFullscreen = ( S60->screenDepth / 8 )
- * S60->screenWidthInPixels
- * S60->screenHeightInPixels;
-
- S60->memoryLimitForHwRendering = memoryUsage - memoryForFullscreen;
gs->setGraphicsSystem(QLatin1String("raster"));
}
}
@@ -1975,8 +2026,7 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
if(QApplicationPrivate::runtime_graphics_system) {
QRuntimeGraphicsSystem *gs =
static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- gs->setGraphicsSystem(QLatin1String("openvg"), S60->memoryLimitForHwRendering);
- S60->memoryLimitForHwRendering = 0;
+ gs->setGraphicsSystem(QLatin1String("openvg"));
}
#endif
break;
@@ -2276,6 +2326,14 @@ void QApplication::restoreOverrideCursor()
#endif // QT_NO_CURSOR
+void QApplicationPrivate::_q_aboutToQuit()
+{
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ // Send the shutdown tfx command
+ S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
+#endif
+}
+
QS60ThreadLocalData::QS60ThreadLocalData()
{
CCoeEnv *env = CCoeEnv::Static();
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index ec26e81..0c48bfd 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -716,8 +716,10 @@ static void qt_set_windows_updateScrollBar(QWidget *widget)
if (QWidget *w = static_cast<QWidget *>(o))
qt_set_windows_updateScrollBar(w);
}
+#ifndef QT_NO_SCROLLBAR
if (qobject_cast<QScrollBar*>(widget))
widget->updateGeometry();
+#endif
}
@@ -1499,6 +1501,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
switch (message) {
#ifndef Q_WS_WINCE
+#ifndef QT_NO_SESSIONMANAGER
case WM_QUERYENDSESSION: {
if (sm_smActive) // bogus message from windows
RETURN(true);
@@ -1531,6 +1534,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
RETURN(0);
}
+#endif
case WM_DISPLAYCHANGE:
if (QApplication::type() == QApplication::Tty)
break;
@@ -2236,6 +2240,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
}
break;
+#ifndef QT_NO_CONTEXTMENU
case WM_CONTEXTMENU:
{
// it's not VK_APPS or Shift+F10, but a click in the NC area
@@ -2264,6 +2269,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
}
break;
#endif
+#endif
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
index 8d65aa1..8d38f45 100644
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ b/src/gui/kernel/qcocoamenuloader_mac.mm
@@ -255,5 +255,10 @@ QT_USE_NAMESPACE
qApp->quit();
}
}
+
+ - (void)orderFrontCharacterPalette:(id)sender
+ {
+ [NSApp orderFrontCharacterPalette:sender];
+ }
@end
#endif // QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h
index a75ad0a..edacfa5 100644
--- a/src/gui/kernel/qcocoamenuloader_mac_p.h
+++ b/src/gui/kernel/qcocoamenuloader_mac_p.h
@@ -88,6 +88,7 @@
- (IBAction)hide:(id)sender;
- (IBAction)qtDispatcherToQAction:(id)sender;
- (void)qtUpdateMenubar;
+- (void)orderFrontCharacterPalette:(id)sender;
@end
#endif // QT_MAC_USE_COCOA
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/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index e26fbde..89f01d8 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -785,7 +785,7 @@ void QEventDispatcherMacPrivate::temporarilyStopAllModalSessions()
// the stacking order of the windows while doing so, we put
// up a block that is used in QCocoaWindow and QCocoaPanel:
int stackSize = cocoaModalSessionStack.size();
- for (int i=stackSize-1; i>=0; --i) {
+ for (int i=0; i<stackSize; ++i) {
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
if (info.session) {
[NSApp endModalSession:info.session];
@@ -822,12 +822,12 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession()
QBoolBlocker block1(blockSendPostedEvents, true);
info.nswindow = window;
[(NSWindow*) info.nswindow retain];
- // When creating a modal session cocoa will rearrange the windows.
- // In order to avoid windows to be put behind another we need to
- // keep the window level.
- int level = [window level];
+ int levelBeforeEnterModal = [window level];
info.session = [NSApp beginModalSessionForWindow:window];
- [window setLevel:level];
+ // Make sure we don't stack the window lower that it was before
+ // entering modal, in case it e.g. had the stays-on-top flag set:
+ if (levelBeforeEnterModal > [window level])
+ [window setLevel:levelBeforeEnterModal];
}
currentModalSessionCached = info.session;
}
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/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index fe9dd8a..e768a21 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -129,7 +129,12 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
{
QList<QGestureRecognizer *> list = m_recognizers.values(type);
- m_recognizers.remove(type);
+ while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
+ if (!m_obsoleteGestures.contains(recognizer)) {
+ // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
+ m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
+ }
+ }
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
if (list.contains(recognizer)) {
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/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 38ec806..55d5727 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -872,7 +872,7 @@ void QPalette::detach()
\note The current ColorGroup is not taken into account when
comparing palettes
- \sa operator==
+ \sa operator==()
*/
/*!
@@ -882,7 +882,7 @@ void QPalette::detach()
\note The current ColorGroup is not taken into account when
comparing palettes
- \sa operator!=
+ \sa operator!=()
*/
bool QPalette::operator==(const QPalette &p) const
{
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 3fc27f4..7d23abf 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -685,9 +685,11 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve
unsigned int info = 0;
if ([event type] == NSKeyDown) {
NSString *characters = [event characters];
- unichar value = [characters characterAtIndex:0];
- qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
- info = value;
+ if ([characters length]) {
+ unichar value = [characters characterAtIndex:0];
+ qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
+ info = value;
+ }
}
// Redirect keys to alien widgets.
@@ -1527,6 +1529,22 @@ void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window)
[theWindow display];
}
}
+
+void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *childWidget)
+{
+ if (!childWidget)
+ return;
+
+ QWidget *parent = childWidget->parentWidget();
+ if (childWidget->isWindow() && parent) {
+ if ([[qt_mac_window_for(parent) childWindows] containsObject:qt_mac_window_for(childWidget)]) {
+ QWidgetPrivate *d = qt_widget_private(childWidget);
+ d->setSubWindowStacking(false);
+ d->setSubWindowStacking(true);
+ }
+ }
+}
+
#endif // QT_MAC_USE_COCOA
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 44fb4f0..c6c2db2 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -148,6 +148,7 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor);
// These methods exists only for supporting unified mode.
void macDrawRectOnTop(void * /*OSWindowRef */ window);
void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window);
+void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *widget);
#endif
void qt_mac_menu_collapseSeparators(void * /*NSMenu */ menu, bool collapse);
bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 7f0c99e..ad6a99a 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -141,7 +141,6 @@ public:
int supportsPremultipliedAlpha : 1;
int avkonComponentsSupportTransparency : 1;
int menuBeingConstructed : 1;
- int memoryLimitForHwRendering;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
enum ScanCodeState {
@@ -165,6 +164,7 @@ public:
static inline CEikButtonGroupContainer* buttonGroupContainer();
static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible);
#endif
+ static void controlVisibilityChanged(CCoeControl *control, bool visible);
#ifdef Q_OS_SYMBIAN
TTrapHandler *s60InstalledTrapHandler;
@@ -291,7 +291,6 @@ inline QS60Data::QS60Data()
supportsPremultipliedAlpha(0),
avkonComponentsSupportTransparency(0),
menuBeingConstructed(0),
- memoryLimitForHwRendering(0),
s60ApplicationFactory(0)
#ifdef Q_OS_SYMBIAN
,s60InstalledTrapHandler(0)
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 9946d5d..7ea81bb 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -165,47 +165,76 @@ static inline bool hasBackingStoreSupport()
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+/*!
+ \internal
+ \class QWidgetBackingStoreTracker
+ \brief Class which allows tracking of which widgets are using a given backing store
-QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore()
+ QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
+ which maintains a list of the QWidgets which are currently using the backing
+ store. This list is modified via the registerWidget and unregisterWidget functions.
+ */
+
+QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
: m_ptr(0)
- , m_count(0)
{
}
-QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore()
+QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
{
delete m_ptr;
}
-void QRefCountedWidgetBackingStore::create(QWidget *widget)
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store, then create a new QWidgetBackingStore, providing
+ the QWidget.
+ */
+void QWidgetBackingStoreTracker::create(QWidget *widget)
{
destroy();
m_ptr = new QWidgetBackingStore(widget);
- m_count = 0;
}
-void QRefCountedWidgetBackingStore::destroy()
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store.
+ */
+void QWidgetBackingStoreTracker::destroy()
{
delete m_ptr;
m_ptr = 0;
- m_count = 0;
+ m_widgets.clear();
}
-void QRefCountedWidgetBackingStore::ref()
+/*!
+ \internal
+ Add the widget to the list of widgets currently using the backing store.
+ If the widget was already in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
{
Q_ASSERT(m_ptr);
- ++m_count;
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_widgets.insert(w);
}
-void QRefCountedWidgetBackingStore::deref()
+/*!
+ \internal
+ Remove the widget from the list of widgets currently using the backing store.
+ If the widget was in the list, and removing it causes the list to be empty,
+ the backing store is deleted.
+ If the widget was not in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
{
- if (m_count) {
- Q_ASSERT(m_ptr);
- if (0 == --m_count) {
- delete m_ptr;
- m_ptr = 0;
- }
+ if (m_widgets.remove(w) && m_widgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
}
}
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 8ae6a99..1979c84 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2796,10 +2796,14 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
if (QWidget *parent = q->parentWidget()) {
if (parent->testAttribute(Qt::WA_WState_Created)) {
- if (set)
- [qt_mac_window_for(parent) addChildWindow:qt_mac_window_for(q) ordered:NSWindowAbove];
- else
+ if (set) {
+ if (parent->isVisible()) {
+ NSWindow *childwin = qt_mac_window_for(q);
+ [qt_mac_window_for(parent) addChildWindow:childwin ordered:NSWindowAbove];
+ }
+ } else {
[qt_mac_window_for(parent) removeChildWindow:qt_mac_window_for(q)];
+ }
}
}
@@ -2807,10 +2811,12 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
for (int i=0; i<widgets.size(); ++i) {
QWidget *child = widgets.at(i);
if (child->isWindow() && child->testAttribute(Qt::WA_WState_Created) && child->isVisibleTo(q)) {
- if (set)
- [qt_mac_window_for(q) addChildWindow:qt_mac_window_for(child) ordered:NSWindowAbove];
- else
+ if (set) {
+ NSWindow *childwin = qt_mac_window_for(child);
+ [qt_mac_window_for(q) addChildWindow:childwin ordered:NSWindowAbove];
+ } else {
[qt_mac_window_for(q) removeChildWindow:qt_mac_window_for(child)];
+ }
}
}
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 3903124..de0d5e0 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -113,17 +113,18 @@ class QWidgetItemV2;
class QStyle;
-class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore
+class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
{
+
public:
- QRefCountedWidgetBackingStore();
- ~QRefCountedWidgetBackingStore();
+ QWidgetBackingStoreTracker();
+ ~QWidgetBackingStoreTracker();
void create(QWidget *tlw);
void destroy();
- void ref();
- void deref();
+ void registerWidget(QWidget *w);
+ void unregisterWidget(QWidget *w);
inline QWidgetBackingStore* data()
{
@@ -146,11 +147,11 @@ public:
}
private:
- Q_DISABLE_COPY(QRefCountedWidgetBackingStore)
+ Q_DISABLE_COPY(QWidgetBackingStoreTracker)
private:
QWidgetBackingStore* m_ptr;
- int m_count;
+ QSet<QWidget *> m_widgets;
};
struct QTLWExtra {
@@ -159,7 +160,7 @@ struct QTLWExtra {
// Regular pointers (keep them together to avoid gaps on 64 bits architectures).
QIcon *icon; // widget icon
QPixmap *iconPixmap;
- QRefCountedWidgetBackingStore backingStore;
+ QWidgetBackingStoreTracker backingStore;
QWindowSurface *windowSurface;
QPainter *sharedPainter;
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 56349ad..319f330 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -684,6 +684,12 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
QSymbianControl *old_winid = static_cast<QSymbianControl *>(wasCreated ? data.winid : 0);
if ((q->windowType() == Qt::Desktop))
old_winid = 0;
+
+ // old_winid may not have received a 'not visible' visibility
+ // changed event before being destroyed; make sure that it is
+ // removed from the backing store's list of visible windows.
+ S60->controlVisibilityChanged(old_winid, false);
+
setWinId(0);
// hide and reparent our own window away. Otherwise we might get
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 23f57da..59035b1 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -166,7 +166,7 @@ static void qt_tablet_init()
qt_tablet_widget = new QWidget(0);
qt_tablet_widget->createWinId();
qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget"));
- // We dont need this internal widget to appear in QApplication::topLevelWidgets()
+ // We don't need this internal widget to appear in QApplication::topLevelWidgets()
if (QWidgetPrivate::allWidgets)
QWidgetPrivate::allWidgets->remove(qt_tablet_widget);
LOGCONTEXT lcMine;
@@ -1547,7 +1547,7 @@ bool QWidgetPrivate::shouldShowMaximizeButton()
{
if (data.window_flags & Qt::MSWindowsFixedSizeDialogHint)
return false;
- // if the user explicitely asked for the maximize button, we try to add
+ // if the user explicitly asked for the maximize button, we try to add
// it even if the window has fixed size.
if (data.window_flags & Qt::CustomizeWindowHint &&
data.window_flags & Qt::WindowMaximizeButtonHint)
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 92c4e84..1f76b6f 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -225,6 +225,7 @@ if(mmx|3dnow|sse|sse2|iwmmxt) {
SSE3DNOW_SOURCES += painting/qdrawhelper_sse3dnow.cpp
SSE_SOURCES += painting/qdrawhelper_sse.cpp
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
+ SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
}
@@ -259,23 +260,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/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index a73d63f..dc7b808 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -371,7 +371,7 @@ void QWidgetBackingStore::beginPaint(QRegion &toClean, QWidget *widget, QWindowS
// Always flush repainted areas.
dirtyOnScreen += toClean;
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) && !defined(Q_BACKINGSTORE_SUBSURFACES)
toClean.translate(tlwOffset);
#endif
@@ -1329,7 +1329,12 @@ void QWidgetBackingStore::sync()
#ifdef Q_BACKINGSTORE_SUBSURFACES
QWindowSurface *subSurface = w->windowSurface();
BeginPaintInfo beginPaintInfo;
- beginPaint(toBePainted, w, subSurface, &beginPaintInfo, false);
+
+ QPoint off = w->mapTo(tlw, QPoint());
+ toBePainted.translate(off);
+ beginPaint(toBePainted, w, subSurface, &beginPaintInfo, true);
+ toBePainted.translate(-off);
+
if (beginPaintInfo.nothingToPaint)
continue;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 4ce2bee..276da93 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -7820,8 +7820,10 @@ void qInitDrawhelperAsm()
uint const_alpha);
extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha);
extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha);
+ extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha);
functionForModeAsm[0] = comp_func_SourceOver_sse2;
+ functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2;
functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2;
functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2;
@@ -7838,6 +7840,17 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+
+#if defined(QT_HAVE_SSSE3)
+ if (features & SSSE3) {
+ extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
+ }
+#endif // QT_HAVE_SSSE3
} else
#endif
{
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 1a87127..d04c70d 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -314,18 +314,61 @@ struct QSpanData
void adjustSpanMethods();
};
+#if defined(Q_CC_RVCT)
+# pragma push
+# pragma arm
+#endif
+Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {
+ uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
-Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) {
- a += 1;
- uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
- t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f;
- return t;
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
}
+#if defined(Q_CC_RVCT)
+# pragma pop
+#endif
-Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) {
- uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0;
- t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f;
- return t;
+#if QT_POINTER_SIZE == 8 // 64-bit versions
+
+Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
+ quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
+ t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
+ t >>= 8;
+ t &= 0x00ff00ff00ff00ff;
+ return (uint(t)) | (uint(t >> 24));
+}
+
+Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) {
+ quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
+ t &= 0x00ff00ff00ff00ff;
+ return (uint(t)) | (uint(t >> 24));
+}
+
+Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {
+ uint a = x >> 24;
+ quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
+ t &= 0x000000ff00ff00ff;
+ return (uint(t)) | (uint(t >> 24)) | (a << 24);
+}
+
+#else // 32-bit versions
+
+Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
+ uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
}
#if defined(Q_CC_RVCT)
@@ -359,6 +402,21 @@ Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {
x |= t | (a << 24);
return x;
}
+#endif
+
+
+Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) {
+ a += 1;
+ uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
+ t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f;
+ return t;
+}
+
+Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) {
+ uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0;
+ t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f;
+ return t;
+}
#define INV_PREMUL(p) \
(qAlpha(p) == 0 ? 0 : \
@@ -1847,70 +1905,6 @@ inline int qBlue565(quint16 rgb) {
return (b << 3) | (b >> 2);
}
-#if 1
-Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
- uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
- t >>= 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
- x &= 0xff00ff00;
- x |= t;
- return x;
-}
-
-#if defined(Q_CC_RVCT)
-# pragma push
-# pragma arm
-#endif
-Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {
- uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
- x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
- x &= 0xff00ff00;
- x |= t;
- return x;
-}
-#if defined(Q_CC_RVCT)
-# pragma pop
-#endif
-#else
-// possible implementation for 64 bit
-Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
- ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
- t >>= 8;
- t &= 0x00ff00ff00ff00ff;
- return (uint(t)) | (uint(t >> 24));
-}
-
-Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {
- ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
- t &= 0x00ff00ff00ff00ff;
- return (uint(t)) | (uint(t >> 24));
-}
-
-Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) {
- ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
- t &= 0x00ff00ff00ff00ff;
- return (uint(t)) | (uint(t >> 24));
-}
-
-Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {
- uint a = x >> 24;
- ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);
- t &= 0x00ff00ff00ff00ff;
- return (uint(t)) | (uint(t >> 24)) | 0xff000000;
-}
-#endif
-
const uint qt_bayer_matrix[16][16] = {
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index e090ae5..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);
@@ -229,6 +225,37 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin
}
}
+void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha)
+{
+ if (const_alpha == 255) {
+ ::memcpy(dst, src, length * sizeof(uint));
+ } else {
+ const int ialpha = 255 - const_alpha;
+
+ int x = 0;
+
+ // 1) prologue, align on 16 bytes
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
+
+ // 2) interpolate pixels with SSE2
+ const __m128i half = _mm_set1_epi16(0x80);
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+ const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
+ const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha);
+ for (; x < length - 3; x += 4) {
+ const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
+ __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]);
+ INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half)
+ _mm_store_si128((__m128i *)&dst[x], dstVector);
+ }
+
+ // 3) Epilogue
+ for (; x < length; ++x)
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha);
+ }
+}
+
void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
{
if (count < 7) {
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
new file mode 100644
index 0000000..9c02009
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+
+#ifdef QT_HAVE_SSSE3
+
+#include <private/qsimd_p.h>
+#include <private/qdrawhelper_x86_p.h>
+#include <private/qdrawingprimitive_sse2_p.h>
+
+QT_BEGIN_NAMESPACE
+
+inline static void blend_pixel(quint32 &dst, const quint32 src)
+{
+ if (src >= 0xff000000)
+ dst = src;
+ else if (src != 0)
+ dst = src + BYTE_MUL(dst, qAlpha(~src));
+}
+
+
+/* The instruction palignr uses direct arguments, so we have to generate the code fo the different
+ shift (4, 8, 12). Checking the alignment inside the loop is unfortunatelly way too slow.
+ */
+#define BLENDING_LOOP(palignrOffset, length)\
+ for (; x < length-3; x += 4) { \
+ const __m128i srcVectorLastLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes + 4]);\
+ const __m128i srcVector = _mm_alignr_epi8(srcVectorLastLoaded, srcVectorPrevLoaded, palignrOffset); \
+ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
+ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
+ _mm_store_si128((__m128i *)&dst[x], srcVector); \
+ } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \
+ __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \
+ alphaChannel = _mm_sub_epi16(one, alphaChannel); \
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \
+ __m128i destMultipliedByOneMinusAlpha; \
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \
+ const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \
+ _mm_store_si128((__m128i *)&dst[x], result); \
+ } \
+ srcVectorPrevLoaded = srcVectorLastLoaded;\
+ }
+
+
+#define BLEND_SOURCE_OVER_ARGB32_FIRST_ROW_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \
+ 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) {\
+ blend_pixel(dst[x], src[x]); \
+ } \
+\
+ const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast<quintptr>(&(src[x])) >> 2) & 0x3;\
+\
+ if (!minusOffsetToAlignSrcOn16Bytes) {\
+ /* src is aligned, usual algorithm but with aligned operations.\
+ See the SSE2 version for more documentation on the algorithm itself. */\
+ const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\
+ for (; x < length-3; x += 4) { \
+ const __m128i srcVector = _mm_load_si128((__m128i *)&src[x]); \
+ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
+ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
+ _mm_store_si128((__m128i *)&dst[x], srcVector); \
+ } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \
+ __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \
+ alphaChannel = _mm_sub_epi16(one, alphaChannel); \
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \
+ __m128i destMultipliedByOneMinusAlpha; \
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \
+ const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \
+ _mm_store_si128((__m128i *)&dst[x], result); \
+ } \
+ } /* end for() */\
+ } else if ((length - x) >= 8) {\
+ /* We are at the first line, so "x - minusOffsetToAlignSrcOn16Bytes" could go before src, and\
+ generate an invalid access. */\
+\
+ /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\
+ __m128i srcVectorPrevLoaded;\
+ if (minusOffsetToAlignSrcOn16Bytes > prologLength) {\
+ /* We go forward 4 pixels to avoid reading before src. */\
+ for (; x < prologLength + 4; ++x)\
+ blend_pixel(dst[x], src[x]); \
+ }\
+ srcVectorPrevLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\
+ const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\
+\
+ const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\
+ switch (palignrOffset) {\
+ case 4:\
+ BLENDING_LOOP(4, length)\
+ break;\
+ case 8:\
+ BLENDING_LOOP(8, length)\
+ break;\
+ case 12:\
+ BLENDING_LOOP(12, length)\
+ break;\
+ }\
+ }\
+ for (; x < length; ++x) \
+ blend_pixel(dst[x], src[x]); \
+}
+
+// Basically blend src over dst with the const alpha defined as constAlphaVector.
+// nullVector, half, one, colorMask are constant accross the whole image/texture, and should be defined as:
+//const __m128i nullVector = _mm_set1_epi32(0);
+//const __m128i half = _mm_set1_epi16(0x80);
+//const __m128i one = _mm_set1_epi16(0xff);
+//const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+//const __m128i alphaMask = _mm_set1_epi32(0xff000000);
+//
+// The computation being done is:
+// result = s + d * (1-alpha)
+// with shortcuts if fully opaque or fully transparent.
+#define BLEND_SOURCE_OVER_ARGB32_MAIN_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \
+ int x = 0; \
+\
+ /* First, get dst aligned. */ \
+ ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \
+ blend_pixel(dst[x], src[x]); \
+ } \
+\
+ const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast<quintptr>(&(src[x])) >> 2) & 0x3;\
+\
+ if (!minusOffsetToAlignSrcOn16Bytes) {\
+ /* src is aligned, usual algorithm but with aligned operations.\
+ See the SSE2 version for more documentation on the algorithm itself. */\
+ const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\
+ for (; x < length-3; x += 4) { \
+ const __m128i srcVector = _mm_load_si128((__m128i *)&src[x]); \
+ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \
+ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \
+ _mm_store_si128((__m128i *)&dst[x], srcVector); \
+ } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \
+ __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \
+ alphaChannel = _mm_sub_epi16(one, alphaChannel); \
+ const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \
+ __m128i destMultipliedByOneMinusAlpha; \
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \
+ const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \
+ _mm_store_si128((__m128i *)&dst[x], result); \
+ } \
+ } /* end for() */\
+ } else if ((length - x) >= 8) {\
+ /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\
+ __m128i srcVectorPrevLoaded = _mm_load_si128((__m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\
+ const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\
+\
+ const __m128i alphaShuffleMask = _mm_set_epi8(0xff,15,0xff,15,0xff,11,0xff,11,0xff,7,0xff,7,0xff,3,0xff,3);\
+ switch (palignrOffset) {\
+ case 4:\
+ BLENDING_LOOP(4, length)\
+ break;\
+ case 8:\
+ BLENDING_LOOP(8, length)\
+ break;\
+ case 12:\
+ BLENDING_LOOP(12, length)\
+ break;\
+ }\
+ }\
+ for (; x < length; ++x) \
+ blend_pixel(dst[x], src[x]); \
+}
+
+void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ const quint32 *src = (const quint32 *) srcPixels;
+ quint32 *dst = (quint32 *) destPixels;
+ if (const_alpha == 256) {
+ const __m128i alphaMask = _mm_set1_epi32(0xff000000);
+ const __m128i nullVector = _mm_setzero_si128();
+ const __m128i half = _mm_set1_epi16(0x80);
+ const __m128i one = _mm_set1_epi16(0xff);
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+
+ // We have to unrol the first row in order to deal with the load on unaligned data
+ // prior to the src pointer.
+ BLEND_SOURCE_OVER_ARGB32_FIRST_ROW_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask);
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+
+ for (int y = 1; y < h; ++y) {
+ BLEND_SOURCE_OVER_ARGB32_MAIN_SSSE3(dst, src, w, nullVector, half, one, colorMask, alphaMask);
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ } else if (const_alpha != 0) {
+ // dest = (s + d * sia) * ca + d * cia
+ // = s * ca + d * (sia * ca + cia)
+ // = s * ca + d * (1 - sa*ca)
+ const_alpha = (const_alpha * 255) >> 8;
+ const __m128i nullVector = _mm_setzero_si128();
+ const __m128i half = _mm_set1_epi16(0x80);
+ const __m128i one = _mm_set1_epi16(0xff);
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+ const __m128i constAlphaVector = _mm_set1_epi16(const_alpha);
+ for (int y = 0; y < h; ++y) {
+ BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, w, nullVector, half, one, colorMask, constAlphaVector)
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_HAVE_SSSE3
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/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp
index 3438137..2828e9d 100644
--- a/src/gui/painting/qgraphicssystem_runtime.cpp
+++ b/src/gui/painting/qgraphicssystem_runtime.cpp
@@ -53,10 +53,8 @@ QT_BEGIN_NAMESPACE
static int qt_pixmap_serial = 0;
#define READBACK(f) \
- m_graphicsSystem->decreaseMemoryUsage(memoryUsage()); \
f \
- readBackInfo(); \
- m_graphicsSystem->increaseMemoryUsage(memoryUsage()); \
+ readBackInfo();
class QDeferredGraphicsSystemChange : public QObject
@@ -252,16 +250,8 @@ QPixmapData* QRuntimePixmapData::runtimeData() const
return m_data;
}
-uint QRuntimePixmapData::memoryUsage() const
-{
- if(is_null || d == 0)
- return 0;
- return w * h * (d / 8);
-}
-
-
QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
- : QWindowSurface(window), m_windowSurface(0), m_pendingWindowSurface(0), m_graphicsSystem(gs)
+ : QWindowSurface(window), m_graphicsSystem(gs)
{
}
@@ -269,7 +259,6 @@ QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, Q
QRuntimeWindowSurface::~QRuntimeWindowSurface()
{
m_graphicsSystem->removeWindowSurface(this);
- delete m_windowSurface;
}
QPaintDevice *QRuntimeWindowSurface::paintDevice()
@@ -288,16 +277,13 @@ void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion &region,
#ifdef QT_DEBUG
qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface";
#endif
- delete m_pendingWindowSurface;
- m_pendingWindowSurface = 0;
+ m_pendingWindowSurface.reset();
}
}
void QRuntimeWindowSurface::setGeometry(const QRect &rect)
{
- m_graphicsSystem->decreaseMemoryUsage(memoryUsage());
m_windowSurface->setGeometry(rect);
- m_graphicsSystem->increaseMemoryUsage(memoryUsage());
}
bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
@@ -330,27 +316,21 @@ QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
return m_windowSurface->offset(widget);
}
-uint QRuntimeWindowSurface::memoryUsage() const
-{
- QPaintDevice *pdev = m_windowSurface->paintDevice();
- if (pdev && pdev->depth() != 0)
- return pdev->width() * pdev->height() * (pdev->depth()/8);
-
- return 0;
-}
-
QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
- : m_memoryUsage(0), m_windowSurfaceDestroyPolicy(DestroyImmediately),
- m_graphicsSystem(0), m_graphicsSystemChangeMemoryLimit(0)
+ : m_windowSurfaceDestroyPolicy(DestroyImmediately),
+ m_graphicsSystem(0)
{
QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
QApplicationPrivate::runtime_graphics_system = true;
+#ifdef QT_DEFAULT_RUNTIME_SYSTEM
+ m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM);
+ if (m_graphicsSystemName.isNull())
+#endif
+ m_graphicsSystemName = QLatin1String("raster");
+
#ifdef Q_OS_SYMBIAN
- m_graphicsSystemName = QLatin1String("openvg");
m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
-#else
- m_graphicsSystemName = QLatin1String("raster");
#endif
m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
@@ -373,51 +353,30 @@ QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) con
{
Q_ASSERT(m_graphicsSystem);
QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
- rtSurface->m_windowSurface = m_graphicsSystem->createWindowSurface(widget);
+ rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
widget->setWindowSurface(rtSurface);
m_windowSurfaces << rtSurface;
- increaseMemoryUsage(rtSurface->memoryUsage());
return rtSurface;
}
-/*!
- Sets graphics system when resource memory consumption is under /a memoryUsageLimit.
-*/
-void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name, uint memoryUsageLimit)
-{
-#ifdef QT_DEBUG
- qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( "<< name <<", " << memoryUsageLimit << ")";
- qDebug() << " current approximated graphics system memory usage " << memoryUsage() << " bytes";
-#endif
- if (memoryUsage() >= memoryUsageLimit) {
- m_graphicsSystemChangeMemoryLimit = memoryUsageLimit;
- m_pendingGraphicsSystemName = name;
- } else {
- setGraphicsSystem(name);
- }
-}
-
void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
{
if (m_graphicsSystemName == name)
return;
#ifdef QT_DEBUG
qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
- qDebug() << " current approximated graphics system memory usage "<< memoryUsage() << " bytes";
#endif
- delete m_graphicsSystem;
+ QGraphicsSystem *oldSystem = m_graphicsSystem;
m_graphicsSystem = QGraphicsSystemFactory::create(name);
m_graphicsSystemName = name;
Q_ASSERT(m_graphicsSystem);
- m_graphicsSystemChangeMemoryLimit = 0;
m_pendingGraphicsSystemName = QString();
for (int i = 0; i < m_pixmapDatas.size(); ++i) {
QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
- // ### TODO Optimize. Openvg and s60raster graphics systems could switch internal ARGB32_PRE QImage buffers.
newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
delete proxy->m_data;
proxy->m_data = newData;
@@ -428,58 +387,26 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
QWidget *widget = proxy->m_windowSurface->window();
- if(m_windowSurfaceDestroyPolicy == DestroyImmediately) {
- delete proxy->m_windowSurface;
- proxy->m_pendingWindowSurface = 0;
- } else {
- proxy->m_pendingWindowSurface = proxy->m_windowSurface;
- }
+ if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
+ proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
- proxy->m_windowSurface = m_graphicsSystem->createWindowSurface(widget);
+ proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
qt_widget_private(widget)->invalidateBuffer(widget->rect());
}
+
+ delete oldSystem;
}
void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
{
int index = m_pixmapDatas.lastIndexOf(pixmapData);
m_pixmapDatas.removeAt(index);
- decreaseMemoryUsage(pixmapData->memoryUsage(), true);
}
void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
{
int index = m_windowSurfaces.lastIndexOf(windowSurface);
m_windowSurfaces.removeAt(index);
- decreaseMemoryUsage(windowSurface->memoryUsage(), true);
-}
-
-void QRuntimeGraphicsSystem::increaseMemoryUsage(uint amount) const
-{
- m_memoryUsage += amount;
-
- if (m_graphicsSystemChangeMemoryLimit &&
- m_memoryUsage < m_graphicsSystemChangeMemoryLimit) {
-
- QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this);
- QDeferredGraphicsSystemChange *deferredChange =
- new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName);
- deferredChange->launch();
- }
-}
-
-void QRuntimeGraphicsSystem::decreaseMemoryUsage(uint amount, bool persistent) const
-{
- m_memoryUsage -= amount;
-
- if (persistent && m_graphicsSystemChangeMemoryLimit &&
- m_memoryUsage < m_graphicsSystemChangeMemoryLimit) {
-
- QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this);
- QDeferredGraphicsSystemChange *deferredChange =
- new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName);
- deferredChange->launch();
- }
}
#include "qgraphicssystem_runtime.moc"
diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h
index 7aab89c..0232241 100644
--- a/src/gui/painting/qgraphicssystem_runtime_p.h
+++ b/src/gui/painting/qgraphicssystem_runtime_p.h
@@ -104,8 +104,6 @@ public:
virtual QPixmapData *runtimeData() const;
- virtual uint memoryUsage() const;
-
private:
const QRuntimeGraphicsSystem *m_graphicsSystem;
@@ -131,10 +129,8 @@ public:
virtual QPoint offset(const QWidget *widget) const;
- virtual uint memoryUsage() const;
-
- QWindowSurface *m_windowSurface;
- QWindowSurface *m_pendingWindowSurface;
+ QScopedPointer<QWindowSurface> m_windowSurface;
+ QScopedPointer<QWindowSurface> m_pendingWindowSurface;
private:
const QRuntimeGraphicsSystem *m_graphicsSystem;
@@ -159,7 +155,6 @@ public:
void removePixmapData(QRuntimePixmapData *pixmapData) const;
void removeWindowSurface(QRuntimeWindowSurface *windowSurface) const;
- void setGraphicsSystem(const QString &name, uint memoryUsageLimit);
void setGraphicsSystem(const QString &name);
QString graphicsSystemName() const { return m_graphicsSystemName; }
@@ -170,22 +165,14 @@ public:
int windowSurfaceDestroyPolicy() const { return m_windowSurfaceDestroyPolicy; }
- uint memoryUsage() const { return m_memoryUsage; }
-
-private:
-
- void increaseMemoryUsage(uint amount) const;
- void decreaseMemoryUsage(uint amount, bool persistent = false) const;
private:
- mutable uint m_memoryUsage;
int m_windowSurfaceDestroyPolicy;
QGraphicsSystem *m_graphicsSystem;
mutable QList<QRuntimePixmapData *> m_pixmapDatas;
mutable QList<QRuntimeWindowSurface *> m_windowSurfaces;
QString m_graphicsSystemName;
- uint m_graphicsSystemChangeMemoryLimit;
QString m_pendingGraphicsSystemName;
friend class QRuntimePixmapData;
diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c
index 5e7c67a..94039fb 100644
--- a/src/gui/painting/qgrayraster.c
+++ b/src/gui/painting/qgrayraster.c
@@ -956,53 +956,49 @@
const QT_FT_Vector* control2,
const QT_FT_Vector* to )
{
- TPos dx, dy, da, db;
int top, level;
int* levels;
QT_FT_Vector* arc;
+ int mid_x = ( DOWNSCALE( ras.x ) + to->x +
+ 3 * (control1->x + control2->x ) ) / 8;
+ int mid_y = ( DOWNSCALE( ras.y ) + to->y +
+ 3 * (control1->y + control2->y ) ) / 8;
+ TPos dx = DOWNSCALE( ras.x ) + to->x - ( mid_x << 1 );
+ TPos dy = DOWNSCALE( ras.y ) + to->y - ( mid_y << 1 );
- dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
if ( dx < 0 )
dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
if ( dy < 0 )
dy = -dy;
if ( dx < dy )
dx = dy;
- da = dx;
-
- dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
- if ( dx < 0 )
- dx = -dx;
- dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
- if ( dy < 0 )
- dy = -dy;
- if ( dx < dy )
- dx = dy;
- db = dx;
level = 1;
- da = da / ras.cubic_level;
- db = db / ras.conic_level;
- while ( da > 0 || db > 0 )
+ dx /= ras.cubic_level;
+ while ( dx > 0 )
{
- da >>= 2;
- db >>= 3;
+ dx >>= 2;
level++;
}
if ( level <= 1 )
{
- TPos to_x, to_y, mid_x, mid_y;
+ TPos to_x, to_y;
to_x = UPSCALE( to->x );
to_y = UPSCALE( to->y );
+
+ /* Recalculation of midpoint is needed only if */
+ /* UPSCALE and DOWNSCALE have any effect. */
+
+#if ( PIXEL_BITS != 6 )
mid_x = ( ras.x + to_x +
3 * UPSCALE( control1->x + control2->x ) ) / 8;
mid_y = ( ras.y + to_y +
3 * UPSCALE( control1->y + control2->y ) ) / 8;
+#endif
gray_render_line( RAS_VAR_ mid_x, mid_y );
gray_render_line( RAS_VAR_ to_x, to_y );
@@ -1359,10 +1355,6 @@
/* <Input> */
/* outline :: A pointer to the source target. */
/* */
- /* func_interface :: A table of `emitters', i.e,. function pointers */
- /* called during decomposition to indicate path */
- /* operations. */
- /* */
/* user :: A typeless pointer which is passed to each */
/* emitter during the decomposition. It can be */
/* used to store the state during the */
@@ -1373,15 +1365,10 @@
/* */
static
int QT_FT_Outline_Decompose( const QT_FT_Outline* outline,
- const QT_FT_Outline_Funcs* func_interface,
void* user )
{
#undef SCALED
-#if 0
-#define SCALED( x ) ( ( (x) << shift ) - delta )
-#else
#define SCALED( x ) (x)
-#endif
QT_FT_Vector v_last;
QT_FT_Vector v_control;
@@ -1396,12 +1383,6 @@
int error;
char tag; /* current point's state */
-#if 0
- int shift = func_interface->shift;
- TPos delta = func_interface->delta;
-#endif
-
-
first = 0;
for ( n = 0; n < outline->n_contours; n++ )
@@ -1455,7 +1436,7 @@
tags--;
}
- error = func_interface->move_to( &v_start, user );
+ error = gray_move_to( &v_start, user );
if ( error )
goto Exit;
@@ -1475,7 +1456,7 @@
vec.x = SCALED( point->x );
vec.y = SCALED( point->y );
- error = func_interface->line_to( &vec, user );
+ error = gray_line_to( &vec, user );
if ( error )
goto Exit;
continue;
@@ -1502,7 +1483,7 @@
if ( tag == QT_FT_CURVE_TAG_ON )
{
- error = func_interface->conic_to( &v_control, &vec,
+ error = gray_conic_to( &v_control, &vec,
user );
if ( error )
goto Exit;
@@ -1515,7 +1496,7 @@
v_middle.x = ( v_control.x + vec.x ) / 2;
v_middle.y = ( v_control.y + vec.y ) / 2;
- error = func_interface->conic_to( &v_control, &v_middle,
+ error = gray_conic_to( &v_control, &v_middle,
user );
if ( error )
goto Exit;
@@ -1524,7 +1505,7 @@
goto Do_Conic;
}
- error = func_interface->conic_to( &v_control, &v_start,
+ error = gray_conic_to( &v_control, &v_start,
user );
goto Close;
}
@@ -1555,20 +1536,20 @@
vec.x = SCALED( point->x );
vec.y = SCALED( point->y );
- error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
+ error = gray_cubic_to( &vec1, &vec2, &vec, user );
if ( error )
goto Exit;
continue;
}
- error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
+ error = gray_cubic_to( &vec1, &vec2, &v_start, user );
goto Close;
}
}
}
/* close the contour with a line segment */
- error = func_interface->line_to( &v_start, user );
+ error = gray_line_to( &v_start, user );
Close:
if ( error )
@@ -1596,22 +1577,11 @@
static int
gray_convert_glyph_inner( RAS_ARG )
{
- static
- const QT_FT_Outline_Funcs func_interface =
- {
- (QT_FT_Outline_MoveTo_Func) gray_move_to,
- (QT_FT_Outline_LineTo_Func) gray_line_to,
- (QT_FT_Outline_ConicTo_Func)gray_conic_to,
- (QT_FT_Outline_CubicTo_Func)gray_cubic_to,
- 0,
- 0
- };
-
volatile int error = 0;
if ( qt_ft_setjmp( ras.jump_buffer ) == 0 )
{
- error = QT_FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
+ error = QT_FT_Outline_Decompose( &ras.outline, &ras );
gray_record_cell( RAS_VAR );
}
else
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index e521e01..fecf25f 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -696,10 +696,11 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount)
linef = d->matrix.map(QLineF(lines[i]));
}
if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qFloor(linef.x1() + aliasedCoordinateDelta);
- int y1 = qFloor(linef.y1() + aliasedCoordinateDelta);
- int x2 = qFloor(linef.x2() + aliasedCoordinateDelta);
- int y2 = qFloor(linef.y2() + aliasedCoordinateDelta);
+ int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
+ int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
+ int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
+ int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
+
XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
}
}
@@ -729,10 +730,11 @@ void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount)
for (int i = 0; i < lineCount; ++i) {
QLineF linef = d->matrix.map(lines[i]);
if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qFloor(linef.x1() + aliasedCoordinateDelta);
- int y1 = qFloor(linef.y1() + aliasedCoordinateDelta);
- int x2 = qFloor(linef.x2() + aliasedCoordinateDelta);
- int y2 = qFloor(linef.y2() + aliasedCoordinateDelta);
+ int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
+ int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
+ int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
+ int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
+
XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
}
}
@@ -1688,8 +1690,8 @@ void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int
if (clippedCount > 0) {
QVarLengthArray<XPoint> xpoints(clippedCount);
for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qFloor(clippedPoints[i].x + aliasedCoordinateDelta);
- xpoints[i].y = qFloor(clippedPoints[i].y + aliasedCoordinateDelta);
+ xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta);
+ xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta);
}
uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);
XPoint *pts = xpoints.data();
@@ -1914,6 +1916,8 @@ void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRect
int sh = qRound(sr.height());
QPixmap pixmap = qt_toX11Pixmap(px);
+ if(pixmap.isNull())
+ return;
if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
|| (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index e0746fb..881bd6e 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -831,7 +831,7 @@ void QPaintEngineEx::drawEllipse(const QRectF &r)
int point_count = 0;
x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count);
- QVectorPath vp((qreal *) pts, 13, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
+ QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
draw(vp);
}
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/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
index a816ed2..170668b 100644
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ b/src/gui/painting/qwindowsurface_qws.cpp
@@ -882,7 +882,11 @@ void QWSMemorySurface::beginPaint(const QRegion &rgn)
const QVector<QRect> rects = rgn.rects();
const QColor blank = Qt::transparent;
for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
+ QRect r = *it;
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+ r.translate(painterOffset());
+#endif
+ p.fillRect(r, blank);
}
}
QWSWindowSurface::beginPaint(rgn);
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 477bd93..8bac1f5 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -67,10 +67,14 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
TDisplayMode mode = S60->screenDevice()->DisplayMode();
bool isOpaque = qt_widget_private(widget)->isOpaque;
- if (mode == EColor16MA && isOpaque)
- mode = EColor16MU; // Faster since 16MU -> 16MA is typically accelerated
- else if (mode == EColor16MU && !isOpaque)
- mode = EColor16MA; // Try for transparency anyway
+ if (isOpaque) {
+ mode = EColor16MU;
+ } else {
+ if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3)
+ mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE
+ else
+ mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA
+ }
// We create empty CFbsBitmap here -> it will be resized in setGeometry
CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp
index 0f9367e..5d4c54e 100644
--- a/src/gui/s60framework/qs60mainapplication.cpp
+++ b/src/gui/s60framework/qs60mainapplication.cpp
@@ -136,16 +136,25 @@ TFileName QS60MainApplication::ResourceFileName() const
return KNullDesC();
}
+/*!
+ \internal
+*/
void QS60MainApplication::PreDocConstructL()
{
QS60MainApplicationBase::PreDocConstructL();
}
+/*!
+ \internal
+*/
CDictionaryStore *QS60MainApplication::OpenIniFileLC(RFs &aFs) const
{
return QS60MainApplicationBase::OpenIniFileLC(aFs);
}
+/*!
+ \internal
+*/
void QS60MainApplication::NewAppServerL(CApaAppServer *&aAppServer)
{
QS60MainApplicationBase::NewAppServerL(aAppServer);
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 40c2d03..ea9dbb3 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -281,76 +281,121 @@ void QS60MainAppUi::RestoreMenuL(CCoeControl *menuWindow, TInt resourceId, TMenu
}
}
+/*!
+ \internal
+*/
void QS60MainAppUi::Exit()
{
QS60MainAppUiBase::Exit();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::SetFadedL(TBool aFaded)
{
QS60MainAppUiBase::SetFadedL(aFaded);
}
+/*!
+ \internal
+*/
TRect QS60MainAppUi::ApplicationRect() const
{
return QS60MainAppUiBase::ApplicationRect();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleScreenDeviceChangedL()
{
QS60MainAppUiBase::HandleScreenDeviceChangedL();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleApplicationSpecificEventL(TInt aType, const TWsEvent &aEvent)
{
QS60MainAppUiBase::HandleApplicationSpecificEventL(aType, aEvent);
}
+/*!
+ \internal
+*/
TTypeUid::Ptr QS60MainAppUi::MopSupplyObject(TTypeUid aId)
{
return QS60MainAppUiBase::MopSupplyObject(aId);
}
+/*!
+ \internal
+*/
void QS60MainAppUi::ProcessCommandL(TInt aCommand)
{
QS60MainAppUiBase::ProcessCommandL(aCommand);
}
+/*!
+ \internal
+*/
TErrorHandlerResponse QS60MainAppUi::HandleError (TInt aError, const SExtendedError &aExtErr, TDes &aErrorText, TDes &aContextText)
{
return QS60MainAppUiBase::HandleError(aError, aExtErr, aErrorText, aContextText);
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleViewDeactivation(const TVwsViewId &aViewIdToBeDeactivated, const TVwsViewId &aNewlyActivatedViewId)
{
QS60MainAppUiBase::HandleViewDeactivation(aViewIdToBeDeactivated, aNewlyActivatedViewId);
}
+/*!
+ \internal
+*/
void QS60MainAppUi::PrepareToExit()
{
QS60MainAppUiBase::PrepareToExit();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleTouchPaneSizeChange()
{
QS60MainAppUiBase::HandleTouchPaneSizeChange();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleSystemEventL(const TWsEvent &aEvent)
{
QS60MainAppUiBase::HandleSystemEventL(aEvent);
}
+/*!
+ \internal
+*/
void QS60MainAppUi::Reserved_MtsmPosition()
{
QS60MainAppUiBase::Reserved_MtsmPosition();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::Reserved_MtsmObject()
{
QS60MainAppUiBase::Reserved_MtsmObject();
}
+/*!
+ \internal
+*/
void QS60MainAppUi::HandleForegroundEventL(TBool aForeground)
{
QS60MainAppUiBase::HandleForegroundEventL(aForeground);
diff --git a/src/gui/s60framework/qs60maindocument.cpp b/src/gui/s60framework/qs60maindocument.cpp
index ed33a41..26e2d00 100644
--- a/src/gui/s60framework/qs60maindocument.cpp
+++ b/src/gui/s60framework/qs60maindocument.cpp
@@ -105,11 +105,17 @@ CEikAppUi *QS60MainDocument::CreateAppUiL()
return (static_cast <CEikAppUi*>(new(ELeave)QS60MainAppUi));
}
+/*!
+ \internal
+ */
CFileStore *QS60MainDocument::OpenFileL(TBool aDoOpen, const TDesC &aFilename, RFs &aFs)
{
return QS60MainDocumentBase::OpenFileL(aDoOpen, aFilename, aFs);
}
+/*!
+ \internal
+ */
void QS60MainDocument::OpenFileL(CFileStore *&aFileStore, RFile &aFile)
{
QS60MainDocumentBase::OpenFileL(aFileStore, aFile);
diff --git a/src/gui/s60framework/qs60maindocument.h b/src/gui/s60framework/qs60maindocument.h
index 2f0564f..fc32d8b 100644
--- a/src/gui/s60framework/qs60maindocument.h
+++ b/src/gui/s60framework/qs60maindocument.h
@@ -47,7 +47,7 @@
#ifdef Q_OS_SYMBIAN
#ifdef Q_WS_S60
-#include <akndoc.h>
+#include <AknDoc.h>
typedef CAknDocument QS60MainDocumentBase;
#else
#include <eikdoc.h>
diff --git a/src/gui/styles/qmacstyle_mac.h b/src/gui/styles/qmacstyle_mac.h
index bcebb1d..d5fcdae 100644
--- a/src/gui/styles/qmacstyle_mac.h
+++ b/src/gui/styles/qmacstyle_mac.h
@@ -60,6 +60,8 @@ class QPalette;
#define Q_GUI_EXPORT_STYLE_MAC Q_GUI_EXPORT
#endif
+class QPushButton;
+class QStyleOptionButton;
class QMacStylePrivate;
class Q_GUI_EXPORT_STYLE_MAC QMacStyle : public QWindowsStyle
{
@@ -133,6 +135,8 @@ private:
Q_DISABLE_COPY(QMacStyle)
QMacStylePrivate *d;
+
+ friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
};
#endif // Q_WS_MAC
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index d18383c..671a888 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -1059,6 +1059,16 @@ void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn,
}
}
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
+{
+ QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style());
+ if (!macStyle)
+ return false;
+ HIThemeButtonDrawInfo bdi;
+ macStyle->d->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi);
+ return bdi.kind == kThemeBevelButton;
+}
+
/**
Creates a HIThemeButtonDrawInfo structure that specifies the correct button
kind and other details to use for drawing the given combobox. Which button
@@ -1430,6 +1440,9 @@ QMacStylePrivate::QMacStylePrivate(QMacStyle *style)
bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget *w) const
{
+ if (!w)
+ return false;
+
if (as == AquaPushButton) {
QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
if (w->window()->isActiveWindow() && pb && !mouseDown) {
diff --git a/src/gui/styles/qmacstyle_mac_p.h b/src/gui/styles/qmacstyle_mac_p.h
index 5a0ba4c..f9b9d30 100644
--- a/src/gui/styles/qmacstyle_mac_p.h
+++ b/src/gui/styles/qmacstyle_mac_p.h
@@ -150,6 +150,8 @@ enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2
return sizes[controlSize]; \
} while (0)
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
+
class QMacStylePrivate : public QObject
{
Q_OBJECT
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 2527662..f44b85e 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -58,12 +58,12 @@
#include <AknsSkinInstance.h>
#include <AknsBasicBackgroundControlContext.h>
#include <avkon.mbg>
-#include <aknfontaccess.h>
-#include <aknlayoutfont.h>
+#include <AknFontAccess.h>
+#include <AknLayoutFont.h>
#include <AknUtils.h>
#include <aknnavi.h>
#include <gulicon.h>
-#include <aknbitmapanimation.h>
+#include <AknBitmapAnimation.h>
#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
index 687e587..0a75492 100644
--- a/src/gui/styles/qstyle.cpp
+++ b/src/gui/styles/qstyle.cpp
@@ -325,7 +325,7 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
control over size of header items and row and column sizes.
\sa QStyleOption, QStylePainter, {Styles Example},
- {Styles &amp Style Aware Widgets}, QStyledItemDelegate
+ {Styles and Style Aware Widgets}, QStyledItemDelegate
*/
/*!
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index dff525e..92e2c81 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -4094,7 +4094,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (pe1 != PseudoElement_None) {
QRenderRule subRule = renderRule(w, opt, pe1);
if (subRule.bg != 0 || subRule.hasDrawable()) {
- //We test subRule.bg dirrectly because hasBackground() would return false for background:none.
+ //We test subRule.bg directly because hasBackground() would return false for background:none.
//But we still don't want the default drawning in that case (example for QScrollBar::add-page) (task 198926)
subRule.drawRule(p, opt->rect);
} else if (fallback) {
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index deaad57..91b6082 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -349,11 +349,32 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
int *nglyphs, QTextEngine::ShaperFlags flags) const
{
*nglyphs = len;
+ QCFType<CFStringRef> cfstring;
+
QVarLengthArray<CGGlyph> cgGlyphs(len);
CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
- for (int i = 0; i < len; ++i)
- glyphs->glyphs[i] = cgGlyphs[i];
+ for (int i = 0; i < len; ++i) {
+ if (cgGlyphs[i]) {
+ glyphs->glyphs[i] = cgGlyphs[i];
+ } else {
+ if (!cfstring)
+ cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), len, kCFAllocatorNull);
+ QCFType<CTFontRef> substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1));
+ CGGlyph substituteGlyph = 0;
+ CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1);
+ if (substituteGlyph) {
+ const uint fontIndex = (fontIndexForFont(substituteFont) << 24);
+ glyphs->glyphs[i] = substituteGlyph | fontIndex;
+ if (!(flags & QTextEngine::GlyphIndicesOnly)) {
+ CGSize advance;
+ CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1);
+ glyphs->advances_x[i] = QFixed::fromReal(advance.width);
+ glyphs->advances_y[i] = QFixed::fromReal(advance.height);
+ }
+ }
+ }
+ }
if (flags & QTextEngine::GlyphIndicesOnly)
return true;
@@ -362,9 +383,14 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len);
for (int i = 0; i < len; ++i) {
+ if (glyphs->glyphs[i] & 0xff000000)
+ continue;
glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ }
+
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ for (int i = 0; i < len; ++i) {
glyphs->advances_x[i] = glyphs->advances_x[i].round();
glyphs->advances_y[i] = glyphs->advances_y[i].round();
}
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/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index 5fb3384..d25fb05 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -1156,6 +1156,10 @@ Qt::LayoutDirection QTextBlock::textDirection() const
if (dir != Qt::LayoutDirectionAuto)
return dir;
+ dir = p->defaultTextOption.textDirection();
+ if (dir != Qt::LayoutDirectionAuto)
+ return dir;
+
const QString buffer = p->buffer();
const int pos = position();
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
index 04d6de9..e718212 100644
--- a/src/gui/util/qcompleter.cpp
+++ b/src/gui/util/qcompleter.cpp
@@ -921,10 +921,12 @@ void QCompleterPrivate::showPopup(const QRect& rect)
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
{
Q_Q(QCompleter);
+#ifndef QT_NO_LINEEDIT
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
//the path given by QFileSystemModel does not end with /
if (lineEdit && !lineEdit->text().isEmpty() && !q->completionPrefix().isEmpty() && q->completionPrefix() != path + QLatin1Char('/'))
q->complete();
+#endif
}
/*!
diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm
index ce85919..15fae23 100644
--- a/src/gui/widgets/qcocoamenu_mac.mm
+++ b/src/gui/widgets/qcocoamenu_mac.mm
@@ -188,6 +188,18 @@ QT_USE_NAMESPACE
return NO;
}
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector
+{
+ NSInteger index = [super indexOfItemWithTarget:anObject andAction:actionSelector];
+ static SEL selForOFCP = NSSelectorFromString(@"orderFrontCharacterPalette:");
+ if (index == -1 && selForOFCP == actionSelector) {
+ // Check if the 'orderFrontCharacterPalette' SEL exists for QCocoaMenuLoader object
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+ return [super indexOfItemWithTarget:loader andAction:actionSelector];
+ }
+ return index;
+}
+
@end
QT_BEGIN_NAMESPACE
diff --git a/src/gui/widgets/qcocoamenu_mac_p.h b/src/gui/widgets/qcocoamenu_mac_p.h
index d6ac8c5..1a42642 100644
--- a/src/gui/widgets/qcocoamenu_mac_p.h
+++ b/src/gui/widgets/qcocoamenu_mac_p.h
@@ -76,6 +76,7 @@ QT_FORWARD_DECLARE_CLASS(QAction)
}
- (id)initWithQMenu:(QMenu*)menu;
- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector;
@end
#endif
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index dcc328f..917a325 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -910,7 +910,7 @@ QComboBox::QComboBox(bool rw, QWidget *parent, const char *name)
interaction. The highlighted() signal is emitted when the user
highlights an item in the combobox popup list. All three signals
exist in two versions, one with a QString argument and one with an
- \c int argument. If the user selectes or highlights a pixmap, only
+ \c int argument. If the user selects or highlights a pixmap, only
the \c int signals are emitted. Whenever the text of an editable
combobox is changed the editTextChanged() signal is emitted.
diff --git a/src/gui/widgets/qcommandlinkbutton.cpp b/src/gui/widgets/qcommandlinkbutton.cpp
index d3b5869..a6f5f7d 100644
--- a/src/gui/widgets/qcommandlinkbutton.cpp
+++ b/src/gui/widgets/qcommandlinkbutton.cpp
@@ -349,7 +349,7 @@ void QCommandLinkButton::paintEvent(QPaintEvent *)
QStyleOptionButton option;
initStyleOption(&option);
- //Enable command link appearence on Vista
+ //Enable command link appearance on Vista
option.features |= QStyleOptionButton::CommandLinkButton;
option.text = QString();
option.icon = QIcon(); //we draw this ourselves
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index 50fa9c9..7a61dc7 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -754,6 +754,7 @@ QCalendarWidget *QDateTimeEdit::calendarWidget() const
Sets the given \a calendarWidget as the widget to be used for the calendar
pop-up. The editor does not automatically take ownership of the calendar widget.
+ \note calendarPopup must be set to true before setting the calendar widget.
\sa calendarPopup
*/
void QDateTimeEdit::setCalendarWidget(QCalendarWidget *calendarWidget)
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index 593e391..62ee398 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -943,7 +943,7 @@ void QMainWindowLayout::toggleToolBarsVisible()
#ifdef Q_WS_MAC
if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) {
// If we hit this case, someone has pressed the "toolbar button" which will
- // toggle the unified toolbar visiblity, because that's what the user wants.
+ // toggle the unified toolbar visibility, because that's what the user wants.
// We might be in a situation where someone has hidden all the toolbars
// beforehand (maybe in construction), but now they've hit this button and
// and are expecting the items to show. What do we do?
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 7941c4e..4bea6de 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -262,7 +262,7 @@ void QMenuPrivate::updateActionRects() const
const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
- //for compatability now - will have to refactor this away..
+ //for compatibility now - will have to refactor this away
tabWidth = 0;
maxIconWidth = 0;
hasCheckableItems = false;
@@ -1154,7 +1154,7 @@ void QMenuPrivate::_q_actionHovered()
bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
{
- //determines if the mouse has moved (ie its intial position has
+ //determines if the mouse has moved (ie its initial position has
//changed by more than QApplication::startDragDistance()
//or if there were at least 6 mouse motions)
return motions > 6 ||
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index e8e80b7..df16f7f 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -102,7 +102,7 @@ void QMenuBarExtension::paintEvent(QPaintEvent *)
QStylePainter p(this);
QStyleOptionToolButton opt;
initStyleOption(&opt);
- // We do not need to draw both extention arrows
+ // We do not need to draw both extension arrows
opt.features &= ~QStyleOptionToolButton::HasMenu;
p.drawComplexControl(QStyle::CC_ToolButton, opt);
}
diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp
index 45b15ef..ea311d3 100644
--- a/src/gui/widgets/qprintpreviewwidget.cpp
+++ b/src/gui/widgets/qprintpreviewwidget.cpp
@@ -469,7 +469,7 @@ void QPrintPreviewWidgetPrivate::setZoomFactor(qreal _zoomFactor)
\o Create the QPrintPreviewWidget
Construct the QPrintPreviewWidget either by passing in an
- exisiting QPrinter object, or have QPrintPreviewWidget create a
+ existing QPrinter object, or have QPrintPreviewWidget create a
default constructed QPrinter object for you.
\o Connect the paintRequested() signal to a slot.
diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp
index 8a18ed0..237c266 100644
--- a/src/gui/widgets/qpushbutton.cpp
+++ b/src/gui/widgets/qpushbutton.cpp
@@ -687,11 +687,11 @@ bool QPushButton::event(QEvent *e)
/*! \reimp */
bool QPushButton::hitButton(const QPoint &pos) const
{
- // This is only required if we are using the native style, so check that first.
- QMacStyle *macStyle = qobject_cast<QMacStyle *>(style());
- // If this is a flat button we just bail out.
- if(isFlat() || (0 == macStyle))
+ QStyleOptionButton opt;
+ initStyleOption(&opt);
+ if (qt_mac_buttonIsRenderedFlat(this, &opt))
return QAbstractButton::hitButton(pos);
+
// Now that we know we are using the native style, let's proceed.
Q_D(const QPushButton);
QPushButtonPrivate *nonConst = const_cast<QPushButtonPrivate *>(d);
diff --git a/src/gui/widgets/qtoolbarextension.cpp b/src/gui/widgets/qtoolbarextension.cpp
index 032c6f0..574a775 100644
--- a/src/gui/widgets/qtoolbarextension.cpp
+++ b/src/gui/widgets/qtoolbarextension.cpp
@@ -75,7 +75,7 @@ void QToolBarExtension::paintEvent(QPaintEvent *)
QStylePainter p(this);
QStyleOptionToolButton opt;
initStyleOption(&opt);
- // We do not need to draw both extention arrows
+ // We do not need to draw both extension arrows
opt.features &= ~QStyleOptionToolButton::HasMenu;
p.drawComplexControl(QStyle::CC_ToolButton, opt);
}