diff options
author | David Boddie <dboddie@trolltech.com> | 2010-08-04 16:50:23 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-08-04 16:50:23 (GMT) |
commit | e8b116e793d13204fb00b286becf95d2a933a784 (patch) | |
tree | 7d94b673694d5c9e7475faeae35f1268e518cca8 /src/gui | |
parent | 42f1e22bdfe2fe29f305dbf50e23933b8e1ef8d0 (diff) | |
parent | a214bb99775e898fd9233b932f08ff91a57fc053 (diff) | |
download | Qt-e8b116e793d13204fb00b286becf95d2a933a784.zip Qt-e8b116e793d13204fb00b286becf95d2a933a784.tar.gz Qt-e8b116e793d13204fb00b286becf95d2a933a784.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Conflicts:
doc/src/examples/qml-examples.qdoc
Diffstat (limited to 'src/gui')
63 files changed, 1302 insertions, 512 deletions
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index f1afaa9..64fc0ee 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -782,9 +782,11 @@ void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMess const QtMacFilterName &fn = fileDialogPrivate->filterInfo.filters.at( fileDialogPrivate->filterInfo.currentSelection); QStringList reg = fn.regexp.split(QLatin1String(";"), QString::SkipEmptyParts); - QString r = reg.first(); - r = r.right(r.length()-1); // Strip the * - base += r; //"." + QString::number(s->menuType); + if (reg.count()) { + QString r = reg.first(); + r = r.right(r.length()-1); // Strip the * + base += r; //"." + QString::number(s->menuType); + } NavDialogSetSaveFileName(p->context, QCFString::toCFStringRef(base)); } #ifdef DEBUG_FILEDIALOG_FILTERS diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index bf36d9b..1626d83 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1150,6 +1150,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) { parentFocusScopeItem = fsi; p->d_ptr->focusScopeItem = 0; + fsi->d_ptr->focusScopeItemChange(false); } break; } @@ -1182,6 +1183,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q while (p) { if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = newFocusScopeItem; + newFocusScopeItem->d_ptr->focusScopeItemChange(true); // Ensure the new item is no longer the subFocusItem. The // only way to set focus on a child of a focus scope is // by setting focus on the scope itself. @@ -1270,8 +1272,14 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q Returns the bounding rect of this item's children (excluding itself). */ -void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect) +void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip) { + Q_Q(QGraphicsItem); + + QRectF childrenRect; + QRectF *result = rect; + rect = &childrenRect; + for (int i = 0; i < children.size(); ++i) { QGraphicsItem *child = children.at(i); QGraphicsItemPrivate *childd = child->d_ptr.data(); @@ -1293,6 +1301,15 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec childd->childrenBoundingRectHelper(x, rect); } } + + if (doClip && (flags & QGraphicsItem::ItemClipsChildrenToShape)){ + if (x) + *rect &= x->mapRect(q->boundingRect()); + else + *rect &= q->boundingRect(); + } + + *result |= *rect; } void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, @@ -1436,9 +1453,10 @@ QGraphicsItem::~QGraphicsItem() #ifndef QT_NO_GESTURES if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) { QGraphicsObject *o = static_cast<QGraphicsObject *>(this); - QGestureManager *manager = QGestureManager::instance(); - foreach (Qt::GestureType type, d_ptr->gestureContext.keys()) - manager->cleanupCachedGestures(o, type); + if (QGestureManager *manager = QGestureManager::instance()) { + foreach (Qt::GestureType type, d_ptr->gestureContext.keys()) + manager->cleanupCachedGestures(o, type); + } } #endif @@ -3913,7 +3931,7 @@ void QGraphicsItem::setScale(qreal factor) Returns a list of graphics transforms that currently apply to this item. QGraphicsTransform is for applying and controlling a chain of individual - transformation operations on an item. It's particularily useful in + transformation operations on an item. It's particularly useful in animations, where each transform operation needs to be interpolated independently, or differently. @@ -3940,7 +3958,7 @@ QList<QGraphicsTransform *> QGraphicsItem::transformations() const an item, you can call setTransform(). QGraphicsTransform is for applying and controlling a chain of individual - transformation operations on an item. It's particularily useful in + transformation operations on an item. It's particularly useful in animations, where each transform operation needs to be interpolated independently, or differently. @@ -5134,7 +5152,7 @@ QPainterPath QGraphicsItem::opaqueArea() const The bounding region describes a coarse outline of the item's visual contents. Although it's expensive to calculate, it's also more precise than boundingRect(), and it can help to avoid unnecessary repainting when - an item is updated. This is particularily efficient for thin items (e.g., + an item is updated. This is particularly efficient for thin items (e.g., lines or simple polygons). You can tune the granularity for the bounding region by calling setBoundingRegionGranularity(). The default granularity is 0; in which the item's bounding region is the same as its bounding @@ -5572,6 +5590,16 @@ void QGraphicsItemPrivate::subFocusItemChange() /*! \internal + Subclasses can reimplement this function to be notified when an item + becomes a focusScopeItem (or is no longer a focusScopeItem). +*/ +void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem) +{ +} + +/*! + \internal + Subclasses can reimplement this function to be notified when its siblingIndex order is changed. */ @@ -7930,6 +7958,7 @@ void QGraphicsItemPrivate::resetHeight() /*! \property QGraphicsObject::effect + \since 4.7 \brief the effect attached to this item \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect() @@ -11111,8 +11140,14 @@ QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem syste } QRectF rect = item->boundingRect(); - if (!item->d_ptr->children.isEmpty()) - rect |= item->childrenBoundingRect(); + if (!item->d_ptr->children.isEmpty()) { + if (dirtyChildrenBoundingRect) { + childrenBoundingRect = QRectF(); + item->d_ptr->childrenBoundingRectHelper(0, &childrenBoundingRect, true); + dirtyChildrenBoundingRect = false; + } + rect |= childrenBoundingRect; + } if (deviceCoordinates) { Q_ASSERT(info->painter); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index f9f5d3d..d60dffb 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -300,7 +300,7 @@ public: QDeclarativeListProperty<QGraphicsObject> childrenList(); void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant); - void childrenBoundingRectHelper(QTransform *x, QRectF *rect); + void childrenBoundingRectHelper(QTransform *x, QRectF *rect, bool doClip = true); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; QRectF effectiveBoundingRect() const; @@ -482,6 +482,7 @@ public: void clearSubFocus(QGraphicsItem *rootItem = 0); void resetFocusProxy(); virtual void subFocusItemChange(); + virtual void focusScopeItemChange(bool isSubFocusItem); static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); static int children_count(QDeclarativeListProperty<QGraphicsObject> *list); @@ -659,7 +660,7 @@ class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate { public: QGraphicsItemEffectSourcePrivate(QGraphicsItem *i) - : QGraphicsEffectSourcePrivate(), item(i), info(0) + : QGraphicsEffectSourcePrivate(), dirtyChildrenBoundingRect(true), item(i), info(0) {} inline void detach() @@ -710,6 +711,9 @@ public: QGraphicsEffect::PixmapPadMode mode) const; QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const; + mutable bool dirtyChildrenBoundingRect; + mutable QRectF childrenBoundingRect; + QGraphicsItem *item; QGraphicsItemPaintInfo *info; QTransform lastEffectTransform; @@ -867,9 +871,12 @@ inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) #ifndef QT_NO_GRAPHICSEFFECT if (parentp->graphicsEffect) { if (updateBoundingRect) { + QGraphicsItemEffectSourcePrivate *sourcep = + static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() + ->source->d_func()); + parentp->dirtyChildrenBoundingRect = 1; parentp->notifyInvalidated = 1; - static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() - ->source->d_func())->invalidateCache(); + sourcep->invalidateCache(); } if (parentp->scene && parentp->graphicsEffect->isEnabled()) { parentp->dirty = 1; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4bc7f4c..48a0093 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5178,7 +5178,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool // Process children. if (itemHasChildren && item->d_ptr->dirtyChildren) { const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; - if (itemClipsChildrenToShape) { + // Items with no content are threated as 'dummy' items which means they are never drawn and + // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever + // such an item changes geometry, its children have to take care of the update regardless + // of whether the item clips children to shape or not. + const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects; + if (itemClipsChildrenToShape && !bypassUpdateClip) { // Make sure child updates are clipped to the item's bounding rect. for (int i = 0; i < views.size(); ++i) views.at(i)->d_func()->setUpdateClip(item); diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp index 4ab6975..986bee6 100644 --- a/src/gui/graphicsview/qgraphicstransform.cpp +++ b/src/gui/graphicsview/qgraphicstransform.cpp @@ -267,6 +267,7 @@ void QGraphicsScale::setXScale(qreal scale) return; d->xScale = scale; update(); + emit xScaleChanged(); emit scaleChanged(); } @@ -293,6 +294,7 @@ void QGraphicsScale::setYScale(qreal scale) return; d->yScale = scale; update(); + emit yScaleChanged(); emit scaleChanged(); } @@ -319,6 +321,7 @@ void QGraphicsScale::setZScale(qreal scale) return; d->zScale = scale; update(); + emit zScaleChanged(); emit scaleChanged(); } diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h index 58b201a..d8c9654 100644 --- a/src/gui/graphicsview/qgraphicstransform.h +++ b/src/gui/graphicsview/qgraphicstransform.h @@ -85,9 +85,9 @@ class Q_GUI_EXPORT QGraphicsScale : public QGraphicsTransform Q_OBJECT Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged) - Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY scaleChanged) - Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY scaleChanged) - Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY scaleChanged) + Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged) + Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged) + Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged) public: QGraphicsScale(QObject *parent = 0); ~QGraphicsScale(); @@ -108,6 +108,9 @@ public: Q_SIGNALS: void originChanged(); + void xScaleChanged(); + void yScaleChanged(); + void zScaleChanged(); void scaleChanged(); private: diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 41f1904..28440cc 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -80,12 +80,6 @@ symbian { 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 - iwmmxt:DEFINES += QT_HAVE_IWMMXT - win32-g++*|!win32:!*-icc* { mmx { mmx_compiler.commands = $$QMAKE_CXX -c -Winline @@ -182,6 +176,25 @@ contains(QMAKE_MAC_XARCH, no) { silent:sse2_compiler.commands = @echo compiling[sse2] ${QMAKE_FILE_IN} && $$sse2_compiler.commands QMAKE_EXTRA_COMPILERS += sse2_compiler } + ssse3 { + ssse3_compiler.commands = $$QMAKE_CXX -c -Winline + + mac { + ssse3_compiler.commands += -Xarch_i386 -mssse3 + ssse3_compiler.commands += -Xarch_x86_64 -mssse3 + } else { + ssse3_compiler.commands += -mssse3 + } + + ssse3_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + ssse3_compiler.dependency_type = TYPE_C + ssse3_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + ssse3_compiler.input = SSSE3_SOURCES + ssse3_compiler.variable_out = OBJECTS + ssse3_compiler.name = compiling[ssse3] ${QMAKE_FILE_IN} + silent:ssse3_compiler.commands = @echo compiling[ssse3] ${QMAKE_FILE_IN} && $$ssse3_compiler.commands + QMAKE_EXTRA_COMPILERS += ssse3_compiler + } iwmmxt { iwmmxt_compiler.commands = $$QMAKE_CXX -c -Winline iwmmxt_compiler.commands += -mcpu=iwmmxt @@ -200,6 +213,7 @@ contains(QMAKE_MAC_XARCH, no) { 3dnow:sse: SOURCES += $$SSE3DNOW_SOURCES sse: SOURCES += $$SSE_SOURCES sse2: SOURCES += $$SSE2_SOURCES + ssse3: SOURCES += $$SSSE3_SOURCES iwmmxt: SOURCES += $$IWMMXT_SOURCES } } diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index 3a02d56..b20a04f 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -95,3 +95,4 @@ contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri) # SIMD 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 e5930ac..cb834c0 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2343,8 +2343,15 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve data->colortable.resize(256); for (int i = 0; i < 256; ++i) data->colortable[i] = qRgb(i, i, i); + } else { + for (int i = 0; i < data->colortable.size(); ++i) + data->colortable[i] = PREMUL(data->colortable.at(i)); + + // Fill the rest of the table in case src_data > colortable.size() + const int oldSize = data->colortable.size(); + const QRgb lastColor = data->colortable.at(oldSize - 1); + data->colortable.insert(oldSize, 256 - oldSize, lastColor); } - const int tableSize = data->colortable.size() - 1; for (int i = 0; i < data->height; ++i) { src_data -= src_pad; @@ -2352,11 +2359,11 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve for (int pixI = 0; pixI < width; ++pixI) { --src_data; --dest_data; - const uint pixel = data->colortable[qMin<int>(tableSize, *src_data)]; - *dest_data = (quint32) PREMUL(pixel); + *dest_data = data->colortable.at(*src_data); } } + data->colortable = QVector<QRgb>(); data->format = QImage::Format_ARGB32_Premultiplied; data->bytes_per_line = dst_bytes_per_line; data->depth = depth; @@ -2388,8 +2395,12 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio data->colortable.resize(256); for (int i = 0; i < 256; ++i) data->colortable[i] = qRgb(i, i, i); + } else { + // Fill the rest of the table in case src_data > colortable.size() + const int oldSize = data->colortable.size(); + const QRgb lastColor = data->colortable.at(oldSize - 1); + data->colortable.insert(oldSize, 256 - oldSize, lastColor); } - const int tableSize = data->colortable.size() - 1; for (int i = 0; i < data->height; ++i) { src_data -= src_pad; @@ -2397,10 +2408,11 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio for (int pixI = 0; pixI < width; ++pixI) { --src_data; --dest_data; - *dest_data = (quint32) data->colortable[qMin<int>(tableSize, *src_data)]; + *dest_data = (quint32) data->colortable.at(*src_data); } } + data->colortable = QVector<QRgb>(); data->format = QImage::Format_RGB32; data->bytes_per_line = dst_bytes_per_line; data->depth = depth; @@ -2428,12 +2440,23 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers const int width = data->width; const int src_pad = data->bytes_per_line - width; const int dest_pad = (dst_bytes_per_line >> 1) - width; - if (data->colortable.size() == 0) { - data->colortable.resize(256); + + quint16 colorTableRGB16[256]; + if (data->colortable.isEmpty()) { for (int i = 0; i < 256; ++i) - data->colortable[i] = qRgb(i, i, i); + colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(qRgb(i, i, i), 0); + } else { + // 1) convert the existing colors to RGB16 + const int tableSize = data->colortable.size(); + for (int i = 0; i < tableSize; ++i) + colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(data->colortable.at(i), 0); + data->colortable = QVector<QRgb>(); + + // 2) fill the rest of the table in case src_data > colortable.size() + const quint16 lastColor = colorTableRGB16[tableSize - 1]; + for (int i = tableSize; i < 256; ++i) + colorTableRGB16[i] = lastColor; } - const int tableSize = data->colortable.size() - 1; for (int i = 0; i < data->height; ++i) { src_data -= src_pad; @@ -2441,8 +2464,7 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers for (int pixI = 0; pixI < width; ++pixI) { --src_data; --dest_data; - const uint pixel = data->colortable[qMin<int>(tableSize, *src_data)]; - *dest_data = qt_colorConvert<quint16, quint32>(pixel, 0); + *dest_data = colorTableRGB16[*src_data]; } } @@ -3332,7 +3354,7 @@ CONVERT_DECL(qargb4444, quint32) // first index source, second dest -static const Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] = +static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -3739,6 +3761,14 @@ void qInitImageConversions() inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2; } #endif +#ifdef QT_HAVE_SSSE3 + if (features & SSSE3) { + extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3; + converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3; + } +#endif } /*! @@ -4799,7 +4829,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); @@ -4813,7 +4843,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); @@ -4826,12 +4856,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; @@ -4840,7 +4873,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++); @@ -4852,12 +4885,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; @@ -4865,11 +4901,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++; } @@ -4879,12 +4915,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; @@ -4892,8 +4931,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]; @@ -4905,32 +4944,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_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp new file mode 100644 index 0000000..9aed011 --- /dev/null +++ b/src/gui/image/qimage_ssse3.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** 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_SSSE3 + +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 +Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len) +{ + quint32 *const end = dst + len; + + // Prologue, align dst to 16 bytes. The alignement is done on dst because it has 4 store() + // for each 3 load() of src. + const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; + const int prologLength = qMin(len, offsetToAlignOn16Bytes); + + for (int i = 0; i < prologLength; ++i) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } + + // Mask the 4 first colors of the RGB888 vector + const __m128i shuffleMask = _mm_set_epi8(0xff, 9, 10, 11, 0xff, 6, 7, 8, 0xff, 3, 4, 5, 0xff, 0, 1, 2); + + // Mask the 4 last colors of a RGB888 vector with an offset of 1 (so the last 3 bytes are RGB) + const __m128i shuffleMaskEnd = _mm_set_epi8(0xff, 13, 14, 15, 0xff, 10, 11, 12, 0xff, 7, 8, 9, 0xff, 4, 5, 6); + + // Mask to have alpha = 0xff + const __m128i alphaMask = _mm_set1_epi32(0xff000000); + + __m128i *inVectorPtr = (__m128i *)src; + __m128i *dstVectorPtr = (__m128i *)dst; + + const int simdRoundCount = (len - prologLength) / 16; // one iteration in the loop converts 16 pixels + for (int i = 0; i < simdRoundCount; ++i) { + /* + RGB888 has 5 pixels per vector, + 1 byte from the next pixel. The idea here is + to load vectors of RGB888 and use palignr to select a vector out of two vectors. + + After 3 loads of RGB888 and 3 stores of RGB32, we have 4 pixels left in the last + vector of RGB888, we can mask it directly to get a last store or RGB32. After that, + the first next byte is a R, and we can loop for the next 16 pixels. + + The conversion itself is done with a byte permutation (pshufb). + */ + __m128i firstSrcVector = _mm_lddqu_si128(inVectorPtr); + __m128i outputVector = _mm_shuffle_epi8(firstSrcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + + // There are 4 unused bytes left in srcVector, we need to load the next 16 bytes + // and load the next input with palignr + __m128i secondSrcVector = _mm_lddqu_si128(inVectorPtr); + __m128i srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 12); + outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + firstSrcVector = secondSrcVector; + + // We now have 8 unused bytes left in firstSrcVector + secondSrcVector = _mm_lddqu_si128(inVectorPtr); + srcVector = _mm_alignr_epi8(secondSrcVector, firstSrcVector, 8); + outputVector = _mm_shuffle_epi8(srcVector, shuffleMask); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++inVectorPtr; + ++dstVectorPtr; + + // There are now 12 unused bytes in firstSrcVector. + // We can mask them directly, almost there. + outputVector = _mm_shuffle_epi8(secondSrcVector, shuffleMaskEnd); + _mm_store_si128(dstVectorPtr, _mm_or_si128(outputVector, alphaMask)); + ++dstVectorPtr; + } + src = (uchar *)inVectorPtr; + dst = (quint32 *)dstVectorPtr; + + while (dst != end) { + *dst++ = qRgb(src[0], src[1], src[2]); + src += 3; + } +} + +void convert_RGB888_to_RGB32_ssse3(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_ssse3(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_SSSE3 diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 972dd65..d358a5e 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,15 @@ bool QJpegHandlerPrivate::read(QImage *image) QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) { +#if defined(QT_HAVE_SSSE3) + const uint features = qDetectCPUFeatures(); + + // 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/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index a13c8c8..9d571b5 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -157,10 +157,10 @@ class QSymbianBitmapDataAccess { public: - bool heapWasLocked; + static int heapRefCount; QSysInfo::SymbianVersion symbianVersion; - explicit QSymbianBitmapDataAccess() : heapWasLocked(false) + explicit QSymbianBitmapDataAccess() { symbianVersion = QSysInfo::symbianVersion(); }; @@ -169,16 +169,22 @@ public: inline void beginDataAccess(CFbsBitmap *bitmap) { - if (symbianVersion == QSysInfo::SV_9_2) - heapWasLocked = qt_symbianFbsClient()->lockHeap(); - else + if (symbianVersion == QSysInfo::SV_9_2) { + if (heapRefCount == 0) + qt_symbianFbsClient()->lockHeap(); + } else { bitmap->LockHeap(ETrue); + } + + heapRefCount++; } inline void endDataAccess(CFbsBitmap *bitmap) { + heapRefCount--; + if (symbianVersion == QSysInfo::SV_9_2) { - if (!heapWasLocked) + if (heapRefCount == 0) qt_symbianFbsClient()->unlockHeap(); } else { bitmap->UnlockHeap(ETrue); @@ -186,6 +192,8 @@ public: } }; +int QSymbianBitmapDataAccess::heapRefCount = 0; + #define UPDATE_BUFFER() \ { \ diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 2cf8222..dc54313 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -389,7 +389,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader() while (num_text--) { QString key, value; -#if defined(PNG_iTXt_SUPPORTED) +#if defined(PNG_iTXt_SUPPORTED) && !defined(QT_NO_TEXTCODEC) if (text_ptr->lang) { QTextCodec *codec = QTextCodec::codecForName(text_ptr->lang); if (codec) { diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 4cdc4ad..394d374 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -297,6 +297,10 @@ void QCoeFepInputContext::commitTemporaryPreeditString() return; commitCurrentString(false); + + //update cursor position, now this pre-edit text has been committed. + //this prevents next keypress overwriting it (QTBUG-11673) + m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); } void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) 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/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index cd9ee15..67854a3 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1871,7 +1871,7 @@ void QHeaderViewPrivate::_q_layoutChanged() for (int i = 0; i < oldSectionHidden.count(); ++i) { if (oldSectionHidden.testBit(i)) - q->setSectionHidden(logicalIndex(i), false); + q->setSectionHidden(i, false); } // the number of sections changed; we need to reread the state of the model diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 1869093..76d7642 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -2782,7 +2782,10 @@ QPoint QIconModeViewBase::initDynamicLayout(const QListViewLayoutInfo &info) y = info.bounds.y() + info.spacing; items.reserve(rowCount() - hiddenCount()); } else { - const QListViewItem item = items.at(info.first - 1); + int idx = info.first - 1; + while (idx > 0 && !items.at(idx).isValid()) + --idx; + const QListViewItem &item = items.at(idx); x = item.x; y = item.y; if (info.flow == QListView::LeftToRight) @@ -2913,6 +2916,8 @@ void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info) else contentsSize.rwidth() += info.spacing; } + if (rect.size().isEmpty()) + return; // resize tree int insertFrom = info.first; if (done || info.first == 0) { diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index aaf479f..3303800 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2540,6 +2540,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); @@ -5791,10 +5798,12 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, #ifndef QT_NO_GESTURES QGestureManager* QGestureManager::instance() { - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - if (!qAppPriv->gestureManager) - qAppPriv->gestureManager = new QGestureManager(qApp); - return qAppPriv->gestureManager; + if (QApplicationPrivate *qAppPriv = QApplicationPrivate::instance()) { + if (!qAppPriv->gestureManager) + qAppPriv->gestureManager = new QGestureManager(qApp); + return qAppPriv->gestureManager; + } + return 0; } #endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 3a3f816..53205b5 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -603,7 +603,7 @@ private: #endif #ifdef Q_OS_SYMBIAN - static QHash<TInt, TUint> scanCodeCache; + QHash<TInt, TUint> scanCodeCache; #endif static QApplicationPrivate *self; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 0d65811..f8734b2 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -112,6 +112,25 @@ QS60Data* qGlobalS60Data() return qt_s60Data(); } +#ifdef Q_WS_S60 +void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible) +{ + bool buttonGroupVisibilityChanged = false; + if (CEikButtonGroupContainer *const b = buttonGroupContainer()) { + buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible); + b->MakeVisible(buttonGroupVisible); + } + bool statusPaneVisibilityChanged = false; + if (CEikStatusPane *const s = statusPane()) { + statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible); + s->MakeVisible(statusPaneVisible); + } + if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged) + // Ensure that control rectangle is updated + static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange(); +} +#endif + bool qt_nograb() // application no-grab option { #if defined(QT_DEBUG) @@ -207,8 +226,6 @@ void QS60Beep::MatoPlayComplete(TInt aError) } -QHash<TInt, TUint> QApplicationPrivate::scanCodeCache; - static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers) { Qt::KeyboardModifiers result = Qt::NoModifier; @@ -382,6 +399,10 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop) QSymbianControl::~QSymbianControl() { + // Ensure backing store is deleted before the top-level + // window is destroyed + qt_widget_private(qwidget)->topData()->backingStore.destroy(); + if (S60->curWin == this) S60->curWin = 0; if (!QApplicationPrivate::is_app_closing) { @@ -621,251 +642,302 @@ TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCo TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type) { - switch (type) { - //case EEventKeyDown: // <-- Intentionally left out. See below. - case EEventKeyUp: - case EEventKey: - { + /* + S60 has a confusing way of delivering key events. There are three types of + events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed, + EEventKeyDown is first generated, followed by EEventKey. Then, when the key is + released, EEventKeyUp is generated. + However, it is possible that only the EEventKey is generated alone, typically + in relation to virtual keyboards. In that case we need to take care to + generate both press and release events in Qt, since applications expect that. + We do this by having three states for each used scan code, depending on the + events received. See the switch below for what happens in each state + transition. + */ + + if (type != EEventKeyDown) + if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed) + return EKeyWasConsumed; + + TKeyResponse ret = EKeyWasNotConsumed; +#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret) + + // This top level switch corresponds to the states, and the inner switches + // correspond to the transitions. + QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode]; + switch (scanCodeState) { + case QS60Data::Unpressed: + switch (type) { + case EEventKeyDown: + scanCodeState = QS60Data::KeyDown; + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + break; + case EEventKeyUp: + // No action. + break; + } + break; + case QS60Data::KeyDown: + switch (type) { + case EEventKeyDown: + // This should never happen, just stay in this state to be safe. + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + scanCodeState = QS60Data::KeyDownAndKey; + break; + case EEventKeyUp: + scanCodeState = QS60Data::Unpressed; + break; + } + break; + case QS60Data::KeyDownAndKey: + switch (type) { + case EEventKeyDown: + // This should never happen, just stay in this state to be safe. + break; + case EEventKey: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress)); + break; + case EEventKeyUp: + GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease)); + scanCodeState = QS60Data::Unpressed; + break; + } + break; + } + return ret; + +#undef GET_RETURN +} + +TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type) +{ + // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp + // events, we need to cache the keysyms from the EKeyEvent events. This is what + // resolveS60ScanCode does. + TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode, + keyEvent.iCode); + int keyCode; + if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used + keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode); + } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) { + // Normal characters keys. + keyCode = s60Keysym; + } else { + // Special S60 keys. + keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym); + } + + Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); + QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), + (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers); + QWidget *widget; + widget = QWidget::keyboardGrabber(); + if (!widget) { + if (QApplicationPrivate::popupWidgets != 0) { + widget = QApplication::activePopupWidget()->focusWidget(); + if (!widget) { + widget = QApplication::activePopupWidget(); + } + } else { + widget = QApplicationPrivate::focus_widget; + if (!widget) { + widget = qwidget; + } + } + } + + QEventDispatcherS60 *dispatcher; + // It is theoretically possible for someone to install a different event dispatcher. + if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) { + if (dispatcher->excludeUserInputEvents()) { + dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent)); + return EKeyWasConsumed; + } + } + return sendKeyEvent(widget, &qKeyEvent); +} + +TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type) +{ #ifndef QT_NO_CURSOR - if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) { - //translate keys to pointer - if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) || + if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) { + //translate keys to pointer + if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) || (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) || keyEvent.iScanCode == EStdKeyDevice3) { - QPoint pos = QCursor::pos(); - TPointerEvent fakeEvent; - fakeEvent.iType = (TPointerEvent::TType)(-1); - fakeEvent.iModifiers = keyEvent.iModifiers; - TInt x = pos.x(); - TInt y = pos.y(); - if (type == EEventKeyUp) { - S60->virtualMouseAccelTimeout.start(); - switch (keyEvent.iScanCode) { - case EStdKeyLeftArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Left; - break; - case EStdKeyRightArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Right; - break; - case EStdKeyUpArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Up; - break; - case EStdKeyDownArrow: - S60->virtualMousePressedKeys &= ~QS60Data::Down; - break; - // diagonal keys (named aliases don't exist in 3.1 SDK) - case EStdKeyDevice10: - S60->virtualMousePressedKeys &= ~QS60Data::LeftUp; - break; - case EStdKeyDevice11: - S60->virtualMousePressedKeys &= ~QS60Data::RightUp; - break; - case EStdKeyDevice12: - S60->virtualMousePressedKeys &= ~QS60Data::RightDown; - break; - case EStdKeyDevice13: - S60->virtualMousePressedKeys &= ~QS60Data::LeftDown; - break; - case EStdKeyDevice3: //select - if (S60->virtualMousePressedKeys & QS60Data::Select) - fakeEvent.iType = TPointerEvent::EButton1Up; - S60->virtualMousePressedKeys &= ~QS60Data::Select; - break; - } + QPoint pos = QCursor::pos(); + TPointerEvent fakeEvent; + fakeEvent.iType = (TPointerEvent::TType)(-1); + fakeEvent.iModifiers = keyEvent.iModifiers; + TInt x = pos.x(); + TInt y = pos.y(); + if (type == EEventKeyUp) { + S60->virtualMouseAccelTimeout.start(); + switch (keyEvent.iScanCode) { + case EStdKeyLeftArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Left; + break; + case EStdKeyRightArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Right; + break; + case EStdKeyUpArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Up; + break; + case EStdKeyDownArrow: + S60->virtualMousePressedKeys &= ~QS60Data::Down; + break; + // diagonal keys (named aliases don't exist in 3.1 SDK) + case EStdKeyDevice10: + S60->virtualMousePressedKeys &= ~QS60Data::LeftUp; + break; + case EStdKeyDevice11: + S60->virtualMousePressedKeys &= ~QS60Data::RightUp; + break; + case EStdKeyDevice12: + S60->virtualMousePressedKeys &= ~QS60Data::RightDown; + break; + case EStdKeyDevice13: + S60->virtualMousePressedKeys &= ~QS60Data::LeftDown; + break; + case EStdKeyDevice3: //select + if (S60->virtualMousePressedKeys & QS60Data::Select) + fakeEvent.iType = TPointerEvent::EButton1Up; + S60->virtualMousePressedKeys &= ~QS60Data::Select; + break; } - else if (type == EEventKey) { - int dx = 0; - int dy = 0; - if (keyEvent.iScanCode != EStdKeyDevice3) { - m_doubleClickTimer.invalidate(); - //reset mouse accelleration after a short time with no moves - const int maxTimeBetweenKeyEventsMs = 500; - if (S60->virtualMouseAccelTimeout.isValid() && + } + else if (type == EEventKey) { + int dx = 0; + int dy = 0; + if (keyEvent.iScanCode != EStdKeyDevice3) { + m_doubleClickTimer.invalidate(); + //reset mouse accelleration after a short time with no moves + const int maxTimeBetweenKeyEventsMs = 500; + if (S60->virtualMouseAccelTimeout.isValid() && S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) { - S60->virtualMouseAccelDX = 0; - S60->virtualMouseAccelDY = 0; - } - S60->virtualMouseAccelTimeout.invalidate(); + S60->virtualMouseAccelDX = 0; + S60->virtualMouseAccelDY = 0; } - switch (keyEvent.iScanCode) { - case EStdKeyLeftArrow: - S60->virtualMousePressedKeys |= QS60Data::Left; - dx = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyRightArrow: - S60->virtualMousePressedKeys |= QS60Data::Right; - dx = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyUpArrow: - S60->virtualMousePressedKeys |= QS60Data::Up; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDownArrow: - S60->virtualMousePressedKeys |= QS60Data::Down; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice10: - S60->virtualMousePressedKeys |= QS60Data::LeftUp; - dx = -1; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice11: - S60->virtualMousePressedKeys |= QS60Data::RightUp; - dx = 1; - dy = -1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice12: - S60->virtualMousePressedKeys |= QS60Data::RightDown; - dx = 1; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice13: - S60->virtualMousePressedKeys |= QS60Data::LeftDown; - dx = -1; - dy = 1; - fakeEvent.iType = TPointerEvent::EMove; - break; - case EStdKeyDevice3: - // Platform bug. If you start pressing several keys simultaneously (for - // example for drag'n'drop), Symbian starts producing spurious up and - // down messages for some keys. Therefore, make sure we have a clean slate - // of pressed keys before starting a new button press. - if (S60->virtualMousePressedKeys & QS60Data::Select) { - return EKeyWasConsumed; - } else { - S60->virtualMousePressedKeys |= QS60Data::Select; - fakeEvent.iType = TPointerEvent::EButton1Down; - if (m_doubleClickTimer.isValid() + S60->virtualMouseAccelTimeout.invalidate(); + } + switch (keyEvent.iScanCode) { + case EStdKeyLeftArrow: + S60->virtualMousePressedKeys |= QS60Data::Left; + dx = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyRightArrow: + S60->virtualMousePressedKeys |= QS60Data::Right; + dx = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyUpArrow: + S60->virtualMousePressedKeys |= QS60Data::Up; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDownArrow: + S60->virtualMousePressedKeys |= QS60Data::Down; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice10: + S60->virtualMousePressedKeys |= QS60Data::LeftUp; + dx = -1; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice11: + S60->virtualMousePressedKeys |= QS60Data::RightUp; + dx = 1; + dy = -1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice12: + S60->virtualMousePressedKeys |= QS60Data::RightDown; + dx = 1; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice13: + S60->virtualMousePressedKeys |= QS60Data::LeftDown; + dx = -1; + dy = 1; + fakeEvent.iType = TPointerEvent::EMove; + break; + case EStdKeyDevice3: + // Platform bug. If you start pressing several keys simultaneously (for + // example for drag'n'drop), Symbian starts producing spurious up and + // down messages for some keys. Therefore, make sure we have a clean slate + // of pressed keys before starting a new button press. + if (S60->virtualMousePressedKeys & QS60Data::Select) { + return EKeyWasConsumed; + } else { + S60->virtualMousePressedKeys |= QS60Data::Select; + fakeEvent.iType = TPointerEvent::EButton1Down; + if (m_doubleClickTimer.isValid() && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) { - fakeEvent.iModifiers |= EModifierDoubleClick; - m_doubleClickTimer.invalidate(); - } else { - m_doubleClickTimer.start(); - } + fakeEvent.iModifiers |= EModifierDoubleClick; + m_doubleClickTimer.invalidate(); + } else { + m_doubleClickTimer.start(); } - break; - } - if (dx) { - int cdx = S60->virtualMouseAccelDX; - //reset accel on change of sign, else double accel - if (dx * cdx <= 0) - cdx = dx; - else - cdx *= 4; - //cap accelleration - if (dx * cdx > S60->virtualMouseMaxAccel) - cdx = dx * S60->virtualMouseMaxAccel; - //move mouse position - x += cdx; - S60->virtualMouseAccelDX = cdx; } - - if (dy) { - int cdy = S60->virtualMouseAccelDY; - if (dy * cdy <= 0) - cdy = dy; - else - cdy *= 4; - if (dy * cdy > S60->virtualMouseMaxAccel) - cdy = dy * S60->virtualMouseMaxAccel; - y += cdy; - S60->virtualMouseAccelDY = cdy; - } - } - //clip to screen size (window server allows a sprite hotspot to be outside the screen) - if (x < 0) - x = 0; - else if (x >= S60->screenWidthInPixels) - x = S60->screenWidthInPixels - 1; - if (y < 0) - y = 0; - else if (y >= S60->screenHeightInPixels) - y = S60->screenHeightInPixels - 1; - TPoint epos(x, y); - TPoint cpos = epos - PositionRelativeToScreen(); - fakeEvent.iPosition = cpos; - fakeEvent.iParentPosition = epos; - if(fakeEvent.iType != -1) - HandlePointerEvent(fakeEvent); - return EKeyWasConsumed; - } - } -#endif - // S60 has a confusing way of delivering key events. There are three types of - // events: EKeyEvent, EKeyEventDown and EKeyEventUp. When a key is pressed, the - // two first events are generated. When releasing the key, the last one is - // generated. - // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp events, - // we need to do some special tricks to map it to the Qt way. First, we completely - // discard EKeyEventDown events, since they are redundant. Second, since - // EKeyEventUp does not give us a keysym, we need to cache the keysyms from - // the EKeyEvent events. This is what resolveS60ScanCode does. - - - // ### hackish way to send Qt application to background when pressing right softkey - /* - if( keyEvent.iScanCode == EStdKeyDevice1 ) { - S60->window_group->SetOrdinalPosition(-1); - qApp->setActiveWindow(0); - return EKeyWasNotConsumed; - } - */ - - TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode, - keyEvent.iCode); - int keyCode; - if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used - keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode); - } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) { - // Normal characters keys. - keyCode = s60Keysym; - } else { - // Special S60 keys. - keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym); - } - - Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); - QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode, - mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), - (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers); -// WId wid = reinterpret_cast<RWindowGroup *>(keyEvent.Handle())->Child(); -// if (!wid) -// Could happen if window isn't shown yet. -// return EKeyWasNotConsumed; - QWidget *widget; - widget = QWidget::keyboardGrabber(); - if (!widget) { - if (QApplicationPrivate::popupWidgets != 0) { - widget = QApplication::activePopupWidget()->focusWidget(); - if (!widget) { - widget = QApplication::activePopupWidget(); + break; } - } else { - widget = QApplicationPrivate::focus_widget; - if (!widget) { - widget = qwidget; + if (dx) { + int cdx = S60->virtualMouseAccelDX; + //reset accel on change of sign, else double accel + if (dx * cdx <= 0) + cdx = dx; + else + cdx *= 4; + //cap accelleration + if (dx * cdx > S60->virtualMouseMaxAccel) + cdx = dx * S60->virtualMouseMaxAccel; + //move mouse position + x += cdx; + S60->virtualMouseAccelDX = cdx; } - } - } - QEventDispatcherS60 *dispatcher; - // It is theoretically possible for someone to install a different event dispatcher. - if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) { - if (dispatcher->excludeUserInputEvents()) { - dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent)); - return EKeyWasConsumed; + if (dy) { + int cdy = S60->virtualMouseAccelDY; + if (dy * cdy <= 0) + cdy = dy; + else + cdy *= 4; + if (dy * cdy > S60->virtualMouseMaxAccel) + cdy = dy * S60->virtualMouseMaxAccel; + y += cdy; + S60->virtualMouseAccelDY = cdy; + } } + //clip to screen size (window server allows a sprite hotspot to be outside the screen) + if (x < 0) + x = 0; + else if (x >= S60->screenWidthInPixels) + x = S60->screenWidthInPixels - 1; + if (y < 0) + y = 0; + else if (y >= S60->screenHeightInPixels) + y = S60->screenHeightInPixels - 1; + TPoint epos(x, y); + TPoint cpos = epos - PositionRelativeToScreen(); + fakeEvent.iPosition = cpos; + fakeEvent.iParentPosition = epos; + if(fakeEvent.iType != -1) + HandlePointerEvent(fakeEvent); + return EKeyWasConsumed; } - return sendKeyEvent(widget, &qKeyEvent); - } } +#endif + return EKeyWasNotConsumed; } @@ -1096,17 +1168,12 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; - const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; - buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint)); - } + const bool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; + const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaVisibilityHint)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif } else if (QApplication::activeWindow() == qwidget->window()) { if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) { @@ -1456,6 +1523,8 @@ void qt_cleanup() qt_S60Beep = 0; } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles + QPixmapCache::clear(); // Has to happen now, since QS60PixmapData has FBS handles + qt_cleanup_symbianFontDatabaseExtras(); // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -2076,13 +2145,18 @@ void QApplication::setEffectEnabled(Qt::UIEffect /* effect */, bool /* enable */ TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym) { + if (!scanCode) + return keysym; + + QApplicationPrivate *d = QApplicationPrivate::instance(); + if (keysym) { // If keysym is specified, cache it. - scanCodeCache.insert(scanCode, keysym); + d->scanCodeCache.insert(scanCode, keysym); return keysym; } else { // If not, retrieve the cached version. - return scanCodeCache[scanCode]; + return d->scanCodeCache[scanCode]; } } diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 5dcf613..7a9dc70 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -196,7 +196,6 @@ static void cleanupCocoaApplicationDelegate() qAppInstance()->quit(); startedQuit = false; } - return NSTerminateNow; } if (qtPrivate->threadData->eventLoops.size() == 0) { diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 1935531..a552ce7 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -390,7 +390,10 @@ static int qCocoaViewCount = 0; if (QDragManager::self()->source()) mimeData = QDragManager::self()->dragPrivate()->data; QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers); - qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction); + if (QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction != Qt::IgnoreAction + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).buttons == qDMEvent.mouseButtons() + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).modifiers == qDMEvent.keyboardModifiers()) + qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction); qDMEvent.accept(); QApplication::sendEvent(qwidget, &qDMEvent); diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 2b9cf85..ffba6c2 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -394,5 +394,25 @@ static void cleanupCocoaWindowDelegate() } return NO; } + +- (void)syncContentViewFrame: (NSNotification *)notification +{ + NSView *cView = [notification object]; + if (cView) { + NSWindow *window = [cView window]; + QWidget *qwidget = m_windowHash->value(window); + if (qwidget) { + QWidgetData *widgetData = qt_qwidget_data(qwidget); + NSRect rect = [cView frame]; + const QSize newSize(rect.size.width, rect.size.height); + const QSize &oldSize = widgetData->crect.size(); + if (newSize != oldSize) { + [self syncSizeForWidget:qwidget toSize:newSize fromSize:oldSize]; + } + } + + } +} + @end #endif// QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindowdelegate_mac_p.h b/src/gui/kernel/qcocoawindowdelegate_mac_p.h index de9c946..2ca9b13 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac_p.h +++ b/src/gui/kernel/qcocoawindowdelegate_mac_p.h @@ -105,5 +105,6 @@ QT_FORWARD_DECLARE_CLASS(QWidgetData) - (NSSize)closestAcceptableSizeForWidget:(QWidget *)qwidget window:(NSWindow *)window withNewSize:(NSSize)proposedSize; - (QWidget *)qt_qwidgetForWindow:(NSWindow *)window; +- (void)syncContentViewFrame: (NSNotification *)notification; @end #endif diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp index e4d0bf3..a07f4a7 100644 --- a/src/gui/kernel/qdesktopwidget_s60.cpp +++ b/src/gui/kernel/qdesktopwidget_s60.cpp @@ -103,6 +103,10 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) rects->resize(QDesktopWidgetPrivate::screenCount); workrects->resize(QDesktopWidgetPrivate::screenCount); + + (*rects)[0].setRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels); + QRect wr = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()); + (*workrects)[0].setRect(wr.x(), wr.y(), wr.width(), wr.height()); } void QDesktopWidgetPrivate::cleanup() @@ -146,17 +150,23 @@ QWidget *QDesktopWidget::screen(int /* screen */) return this; } -const QRect QDesktopWidget::availableGeometry(int /* screen */) const +const QRect QDesktopWidget::availableGeometry(int screen) const { - TRect clientRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect(); - return qt_TRect2QRect(clientRect); + Q_D(const QDesktopWidget); + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; + + return d->workrects->at(screen); } -const QRect QDesktopWidget::screenGeometry(int /* screen */) const +const QRect QDesktopWidget::screenGeometry(int screen) const { Q_D(const QDesktopWidget); - return QRect(0, 0, S60->screenWidthInPixels, S60->screenHeightInPixels); - } + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; + + return d->rects->at(screen); +} int QDesktopWidget::screenNumber(const QWidget * /* widget */) const { diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 0c0eabb..eade02e 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3627,7 +3627,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \brief The QTouchEvent class contains parameters that describe a touch event. \since 4.6 \ingroup events - \ingroup multitouch + \ingroup touch \section1 Enabling Touch Events @@ -3641,7 +3641,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) Similarly to QMouseEvent, Qt automatically grabs each touch point on the first press inside a widget, and the widget will receive all updates for the touch point until it is released. - Note that it is possible for a widget to receive events for multiple touch points, and that + Note that it is possible for a widget to receive events for numerous touch points, and that multiple widgets may be receiving touch events at the same time. \section1 Event Handling @@ -3717,7 +3717,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \i As mentioned above, enabling touch events means multiple widgets can be receiving touch events simultaneously. Combined with the default QWidget::event() handling for QTouchEvents, - this gives you great flexibility in designing multi-touch user interfaces. Be aware of the + this gives you great flexibility in designing touch user interfaces. Be aware of the implications. For example, it is possible that the user is moving a QSlider with one finger and pressing a QPushButton with another. The signals emitted by these widgets will be interleaved. @@ -3729,7 +3729,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) \i QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an \l{QApplication::activePopupWidget()}{active pop-up widget}. The behavior of QTouchEvents is - undefined when opening a pop-up or grabbing the mouse while there are multiple active touch + undefined when opening a pop-up or grabbing the mouse while there are more than one active touch points. \endlist diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index de80f86..13274c4 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -312,10 +312,10 @@ void QPanGesture::setAcceleration(qreal value) \class QPinchGesture \since 4.6 \brief The QPinchGesture class describes a pinch gesture made my the user. - \ingroup multitouch + \ingroup touch \ingroup gestures - A pinch gesture is a form of multitouch user input in which the user typically + A pinch gesture is a form of touch user input in which the user typically touches two points on the input device with a thumb and finger, before moving them closer together or further apart to change the scale factor, zoom, or level of detail of the user interface. @@ -398,7 +398,7 @@ void QPanGesture::setAcceleration(qreal value) \brief the current scale factor The scale factor measures the scale factor associated with the distance - between two of the user's inputs on a multitouch device. + between two of the user's inputs on a touch device. \sa totalScaleFactor, lastScaleFactor */ diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 8f410b1..dcb0264 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -134,6 +134,7 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture { Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) + Q_FLAGS(ChangeFlags ChangeFlag) public: enum ChangeFlag { @@ -191,6 +192,8 @@ public: friend class QPinchGestureRecognizer; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QPinchGesture::ChangeFlags) + QT_END_NAMESPACE Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags) diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 98e8f66..55d5727 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -868,11 +868,21 @@ void QPalette::detach() Returns true (slowly) if this palette is different from \a p; otherwise returns false (usually quickly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator==() */ /*! Returns true (usually quickly) if this palette is equal to \a p; otherwise returns false (slowly). + + \note The current ColorGroup is not taken into account when + comparing palettes + + \sa operator!=() */ bool QPalette::operator==(const QPalette &p) const { diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index e05f8cc..127e150 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -515,11 +515,14 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, const QTouchEvent *ev = static_cast<const QTouchEvent *>(event); const QMouseEvent *me = static_cast<const QMouseEvent *>(event); +#ifndef QT_NO_GRAPHICSVIEW const QGraphicsSceneMouseEvent *gsme = static_cast<const QGraphicsSceneMouseEvent *>(event); +#endif enum { TapRadius = 40 }; switch (event->type()) { +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMousePress: d->position = gsme->screenPos(); q->setHotSpot(d->position); @@ -527,6 +530,7 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, q->killTimer(d->timerId); d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout); return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout +#endif case QEvent::MouseButtonPress: d->position = me->globalPos(); q->setHotSpot(d->position); @@ -541,7 +545,9 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, q->killTimer(d->timerId); d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout); return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMouseRelease: +#endif case QEvent::MouseButtonRelease: case QEvent::TouchEnd: return QGestureRecognizer::CancelGesture; // get out of the MayBeGesture state @@ -559,12 +565,14 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, return QGestureRecognizer::MayBeGesture; return QGestureRecognizer::CancelGesture; } +#ifndef QT_NO_GRAPHICSVIEW case QEvent::GraphicsSceneMouseMove: { QPoint delta = gsme->screenPos() - d->position.toPoint(); if (d->timerId && delta.manhattanLength() <= TapRadius) return QGestureRecognizer::MayBeGesture; return QGestureRecognizer::CancelGesture; } +#endif default: return QGestureRecognizer::Ignore; } 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 d8ef67d..7f0c99e 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -143,6 +143,14 @@ public: int menuBeingConstructed : 1; int memoryLimitForHwRendering; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type + + enum ScanCodeState { + Unpressed, + KeyDown, + KeyDownAndKey + }; + QHash<TInt, ScanCodeState> scanCodeStates; + static inline void updateScreenSize(); inline RWsSession& wsSession(); static inline RWindowGroup& windowGroup(); @@ -155,6 +163,7 @@ public: static inline CAknTitlePane* titlePane(); static inline CAknContextPane* contextPane(); static inline CEikButtonGroupContainer* buttonGroupContainer(); + static void setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible); #endif #ifdef Q_OS_SYMBIAN @@ -223,7 +232,9 @@ protected: private: void HandlePointerEvent(const TPointerEvent& aPointerEvent); TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType); + TKeyResponse sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type); TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); + TKeyResponse handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type); bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void sendMouseEvent( QWidget *receiver, @@ -236,6 +247,8 @@ private: #ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); #endif + +public: void handleClientAreaChange(); private: diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fed8d0a..aaa29a1 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -12049,8 +12049,8 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) { Q_D(QWidget); if (d->gestureContext.remove(gesture)) { - QGestureManager *manager = QGestureManager::instance(); - manager->cleanupCachedGestures(this, gesture); + if (QGestureManager *manager = QGestureManager::instance()) + manager->cleanupCachedGestures(this, gesture); } } #endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index c788711..8ae6a99 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1599,12 +1599,14 @@ void QWidgetPrivate::toggleDrawers(bool visible) continue; QWidget *widget = static_cast<QWidget*>(object); if(qt_mac_is_macdrawer(widget)) { + bool oldState = widget->testAttribute(Qt::WA_WState_ExplicitShowHide); if(visible) { if (!widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) widget->show(); } else { widget->hide(); - widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false); + if(!oldState) + widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false); } } } diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 2818d88..56349ad 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1113,15 +1113,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // The window decoration visibility has to be changed before doing actual window state // change since in that order the availableGeometry will return directly the right size and // we will avoid unnecessarty redraws - CEikStatusPane *statusPane = S60->statusPane(); - CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer(); - TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - if (statusPane) - statusPane->MakeVisible(visible); - if (buttonGroup) { - // Visibility - buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested)); - } + const bool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool statusPaneVisibility = visible; + const bool buttonGroupVisibility = (visible || (isFullscreen && cbaRequested)); + S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. @@ -1133,8 +1128,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint; if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) { + setAttribute(Qt::WA_OutsideWSRange, false); window->SetExtentToWholeScreen(); } else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) { + setAttribute(Qt::WA_OutsideWSRange, false); TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this)); window->SetExtent(maxExtent.iTl, maxExtent.Size()); } else { @@ -1143,7 +1140,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) // accurate because it did not consider the status pane. This means that when returning // normal mode after showing the status pane, the geometry would overlap so we should // move it if it never had an explicit position. - if (!wasMoved && statusPane && visible) { + if (!wasMoved && S60->statusPane() && visible) { TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl; normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY)); } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ca9556b..1ff3d7b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1314,7 +1314,7 @@ static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint comp_func_Clear_impl(dest, length, const_alpha); } -static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) +void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { comp_func_Clear_impl(dest, length, const_alpha); } @@ -1338,7 +1338,7 @@ static void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint colo } } -static void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) { ::memcpy(dest, src, length * sizeof(uint)); @@ -1356,7 +1356,7 @@ static void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint) { } -static void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint) +void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint) { } @@ -1381,7 +1381,7 @@ static void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint } } -static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1419,7 +1419,7 @@ static void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, } } -static void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1461,7 +1461,7 @@ static void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint co } } -static void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1498,7 +1498,7 @@ static void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, ui } } -static void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1540,7 +1540,7 @@ static void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint c } } -static void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1576,7 +1576,7 @@ static void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, u } } -static void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1613,7 +1613,7 @@ static void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint } } -static void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1653,7 +1653,7 @@ static void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, } } -static void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1695,7 +1695,7 @@ static void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, } } -static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) { PRELOAD_INIT2(dest, src) if (const_alpha == 255) { @@ -1715,11 +1715,6 @@ static void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, u } } -static const uint AMASK = 0xff000000; -static const uint RMASK = 0x00ff0000; -static const uint GMASK = 0x0000ff00; -static const uint BMASK = 0x000000ff; - struct QFullCoverage { inline void store(uint *dest, const uint src) const { @@ -1794,7 +1789,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *dest, const uin } } -static void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Plus_impl(dest, src, length, QFullCoverage()); @@ -1866,7 +1861,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *dest, const } } -static void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Multiply_impl(dest, src, length, QFullCoverage()); @@ -1934,7 +1929,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *dest, const u } } -static void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Screen_impl(dest, src, length, QFullCoverage()); @@ -2013,7 +2008,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *dest, const } } -static void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Overlay_impl(dest, src, length, QFullCoverage()); @@ -2086,7 +2081,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *dest, const u } } -static void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Darken_impl(dest, src, length, QFullCoverage()); @@ -2159,7 +2154,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *dest, const } } -static void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Lighten_impl(dest, src, length, QFullCoverage()); @@ -2242,7 +2237,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *dest, con } } -static void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_ColorDodge_impl(dest, src, length, QFullCoverage()); @@ -2325,7 +2320,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *dest, cons } } -static void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_ColorBurn_impl(dest, src, length, QFullCoverage()); @@ -2405,7 +2400,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *dest, cons } } -static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_HardLight_impl(dest, src, length, QFullCoverage()); @@ -2496,7 +2491,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *dest, cons } } -static void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_SoftLight_impl(dest, src, length, QFullCoverage()); @@ -2569,7 +2564,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *dest, con } } -static void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Difference_impl(dest, src, length, QFullCoverage()); @@ -2636,7 +2631,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *dest, cons } } -static void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha) +void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha) { if (const_alpha == 255) comp_func_Exclusion_impl(dest, src, length, QFullCoverage()); @@ -2659,10 +2654,10 @@ static void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, *dest++ |= color; } -static void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) @@ -2680,10 +2675,10 @@ static void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, *dest++ &= color; } -static void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2703,10 +2698,10 @@ static void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, *dest++ ^= color; } -static void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2728,10 +2723,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, } } -static void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2753,10 +2748,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, } } -static void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2778,10 +2773,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, } } -static void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2797,8 +2792,8 @@ static void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, qt_memfill(dest, ~color | 0xff000000, length); } -static void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, - int length, uint const_alpha) +void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, + int length, uint const_alpha) { Q_UNUSED(const_alpha); while (length--) @@ -2818,10 +2813,10 @@ static void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, } } -static void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -2842,10 +2837,10 @@ static void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, } } -static void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, - const uint *src, - int length, - uint const_alpha) +void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, + const uint *src, + int length, + uint const_alpha) { Q_UNUSED(const_alpha); while (length--) { @@ -7775,6 +7770,7 @@ void qInitDrawhelperAsm() #ifdef QT_HAVE_MMX if (features & MMX) { functionForModeAsm = qt_functionForMode_MMX; + functionForModeSolidAsm = qt_functionForModeSolid_MMX; qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx; #ifdef QT_HAVE_3DNOW @@ -7823,8 +7819,12 @@ void qInitDrawhelperAsm() int length, 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; extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, @@ -7919,17 +7919,8 @@ void qInitDrawhelperAsm() functionForModeSolid = functionForModeSolidAsm; } - if (functionForModeAsm) { - const int destinationMode = QPainter::CompositionMode_Destination; - functionForModeAsm[destinationMode] = functionForMode_C[destinationMode]; - - // use the default qdrawhelper implementation for the - // extended composition modes - for (int mode = 12; mode < numCompositionFunctions; ++mode) - functionForModeAsm[mode] = functionForMode_C[mode]; - + if (functionForModeAsm) functionForMode = functionForModeAsm; - } qt_build_pow_tables(); } diff --git a/src/gui/painting/qdrawhelper_iwmmxt.cpp b/src/gui/painting/qdrawhelper_iwmmxt.cpp index 80b2c04..d99045d 100644 --- a/src/gui/painting/qdrawhelper_iwmmxt.cpp +++ b/src/gui/painting/qdrawhelper_iwmmxt.cpp @@ -106,14 +106,35 @@ CompositionFunction qt_functionForMode_IWMMXT[] = { comp_func_DestinationOver<QIWMMXTIntrinsics>, comp_func_Clear<QIWMMXTIntrinsics>, comp_func_Source<QIWMMXTIntrinsics>, - 0, + comp_func_Destination, comp_func_SourceIn<QIWMMXTIntrinsics>, comp_func_DestinationIn<QIWMMXTIntrinsics>, comp_func_SourceOut<QIWMMXTIntrinsics>, comp_func_DestinationOut<QIWMMXTIntrinsics>, comp_func_SourceAtop<QIWMMXTIntrinsics>, comp_func_DestinationAtop<QIWMMXTIntrinsics>, - comp_func_XOR<QIWMMXTIntrinsics> + comp_func_XOR<QIWMMXTIntrinsics>, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination }; void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData) diff --git a/src/gui/painting/qdrawhelper_mmx.cpp b/src/gui/painting/qdrawhelper_mmx.cpp index d49c5a1..ba92554 100644 --- a/src/gui/painting/qdrawhelper_mmx.cpp +++ b/src/gui/painting/qdrawhelper_mmx.cpp @@ -77,7 +77,7 @@ CompositionFunction qt_functionForMode_MMX[numCompositionFunctions] = { comp_func_DestinationOver<QMMXIntrinsics>, comp_func_Clear<QMMXIntrinsics>, comp_func_Source<QMMXIntrinsics>, - 0, + comp_func_Destination, comp_func_SourceIn<QMMXIntrinsics>, comp_func_DestinationIn<QMMXIntrinsics>, comp_func_SourceOut<QMMXIntrinsics>, @@ -85,6 +85,27 @@ CompositionFunction qt_functionForMode_MMX[numCompositionFunctions] = { comp_func_SourceAtop<QMMXIntrinsics>, comp_func_DestinationAtop<QMMXIntrinsics>, comp_func_XOR<QMMXIntrinsics>, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination }; void qt_blend_color_argb_mmx(int count, const QSpan *spans, void *userData) diff --git a/src/gui/painting/qdrawhelper_mmx3dnow.cpp b/src/gui/painting/qdrawhelper_mmx3dnow.cpp index 8bffaa7..b1e81fc 100644 --- a/src/gui/painting/qdrawhelper_mmx3dnow.cpp +++ b/src/gui/painting/qdrawhelper_mmx3dnow.cpp @@ -85,14 +85,35 @@ CompositionFunction qt_functionForMode_MMX3DNOW[numCompositionFunctions] = { comp_func_DestinationOver<QMMX3DNOWIntrinsics>, comp_func_Clear<QMMX3DNOWIntrinsics>, comp_func_Source<QMMX3DNOWIntrinsics>, - 0, + comp_func_Destination, comp_func_SourceIn<QMMX3DNOWIntrinsics>, comp_func_DestinationIn<QMMX3DNOWIntrinsics>, comp_func_SourceOut<QMMX3DNOWIntrinsics>, comp_func_DestinationOut<QMMX3DNOWIntrinsics>, comp_func_SourceAtop<QMMX3DNOWIntrinsics>, comp_func_DestinationAtop<QMMX3DNOWIntrinsics>, - comp_func_XOR<QMMX3DNOWIntrinsics> + comp_func_XOR<QMMX3DNOWIntrinsics>, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination }; void qt_blend_color_argb_mmx3dnow(int count, const QSpan *spans, void *userData) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 97c78bb..1a87127 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -91,6 +91,11 @@ QT_BEGIN_NAMESPACE # define Q_STATIC_INLINE_FUNCTION static inline #endif +static const uint AMASK = 0xff000000; +static const uint RMASK = 0x00ff0000; +static const uint GMASK = 0x0000ff00; +static const uint BMASK = 0x000000ff; + /******************************************************************************* * QSpan * @@ -1945,6 +1950,41 @@ const uint qt_bayer_matrix[16][16] = { ((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff) +// prototypes of all the composition functions +void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha); +void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint); +void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha); +void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha); + QT_END_NAMESPACE #endif // QDRAWHELPER_P_H diff --git a/src/gui/painting/qdrawhelper_sse.cpp b/src/gui/painting/qdrawhelper_sse.cpp index 58a7fdd..8b17c29 100644 --- a/src/gui/painting/qdrawhelper_sse.cpp +++ b/src/gui/painting/qdrawhelper_sse.cpp @@ -77,14 +77,35 @@ CompositionFunction qt_functionForMode_SSE[numCompositionFunctions] = { comp_func_DestinationOver<QSSEIntrinsics>, comp_func_Clear<QSSEIntrinsics>, comp_func_Source<QSSEIntrinsics>, - 0, + comp_func_Destination, comp_func_SourceIn<QSSEIntrinsics>, comp_func_DestinationIn<QSSEIntrinsics>, comp_func_SourceOut<QSSEIntrinsics>, comp_func_DestinationOut<QSSEIntrinsics>, comp_func_SourceAtop<QSSEIntrinsics>, comp_func_DestinationAtop<QSSEIntrinsics>, - comp_func_XOR<QSSEIntrinsics> + comp_func_XOR<QSSEIntrinsics>, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination }; void qt_blend_color_argb_sse(int count, const QSpan *spans, void *userData) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 346e177..7ab9eda 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -110,13 +110,23 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); for (int y = 0; y < h; ++y) { 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) { + 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); + } + for (; x < w-3; x += 4) { __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { - const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]); + const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); __m128i result; INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half); - _mm_storeu_si128((__m128i *)&dst[x], result); + _mm_store_si128((__m128i *)&dst[x], result); } } for (; x<w; ++x) { @@ -135,7 +145,6 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha) { - Q_ASSERT(const_alpha >= 0); Q_ASSERT(const_alpha < 256); const quint32 *src = (const quint32 *) srcPixels; @@ -154,6 +163,105 @@ void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixe } } +inline int comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha) +{ +#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) + const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); +#undef MIX + return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha); +} + +inline int comp_func_Plus_one_pixel(uint d, const uint s) +{ +#define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) + const int result = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); +#undef MIX + return result; +} + +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) + dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); + + // 2) composition with SSE2 + for (; x < length - 3; x += 4) { + const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + + const __m128i result = _mm_adds_epu8(srcVector, dstVector); + _mm_store_si128((__m128i *)&dst[x], result); + } + + // 3) Epilogue: + for (; x < length; ++x) + dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); + } else { + const int one_minus_const_alpha = 255 - const_alpha; + const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); + const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); + + // 1) Prologue: align destination on 16 bytes + for (; x < prologLength; ++x) + 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); + const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); + // 2) composition with SSE2 + for (; x < length - 3; x += 4) { + const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + + __m128i result = _mm_adds_epu8(srcVector, dstVector); + INTERPOLATE_PIXEL_255_SSE2(result, result, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) + _mm_store_si128((__m128i *)&dst[x], result); + } + + // 3) Epilogue: + for (; x < length; ++x) + dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); + } +} + +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 + const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; + const int prologLength = qMin(length, offsetToAlignOn16Bytes); + for (; x < prologLength; ++x) + 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_sse3dnow.cpp b/src/gui/painting/qdrawhelper_sse3dnow.cpp index c58cf13..9ae0e07 100644 --- a/src/gui/painting/qdrawhelper_sse3dnow.cpp +++ b/src/gui/painting/qdrawhelper_sse3dnow.cpp @@ -85,14 +85,35 @@ CompositionFunction qt_functionForMode_SSE3DNOW[numCompositionFunctions] = { comp_func_DestinationOver<QSSE3DNOWIntrinsics>, comp_func_Clear<QSSE3DNOWIntrinsics>, comp_func_Source<QSSE3DNOWIntrinsics>, - 0, + comp_func_Destination, comp_func_SourceIn<QSSE3DNOWIntrinsics>, comp_func_DestinationIn<QSSE3DNOWIntrinsics>, comp_func_SourceOut<QSSE3DNOWIntrinsics>, comp_func_DestinationOut<QSSE3DNOWIntrinsics>, comp_func_SourceAtop<QSSE3DNOWIntrinsics>, comp_func_DestinationAtop<QSSE3DNOWIntrinsics>, - comp_func_XOR<QSSE3DNOWIntrinsics> + comp_func_XOR<QSSE3DNOWIntrinsics>, + comp_func_Plus, + comp_func_Multiply, + comp_func_Screen, + comp_func_Overlay, + comp_func_Darken, + comp_func_Lighten, + comp_func_ColorDodge, + comp_func_ColorBurn, + comp_func_HardLight, + comp_func_SoftLight, + comp_func_Difference, + comp_func_Exclusion, + rasterop_SourceOrDestination, + rasterop_SourceAndDestination, + rasterop_SourceXorDestination, + rasterop_NotSourceAndNotDestination, + rasterop_NotSourceOrNotDestination, + rasterop_NotSourceXorDestination, + rasterop_NotSource, + rasterop_NotSourceAndDestination, + rasterop_SourceAndNotDestination }; void qt_blend_color_argb_sse3dnow(int count, const QSpan *spans, void *userData) diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 3c96946..18355c2 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -141,12 +141,24 @@ QT_BEGIN_NAMESPACE // with shortcuts if fully opaque or fully transparent. #define BLEND_SOURCE_OVER_ARGB32_SSE2(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) { \ + uint s = src[x]; \ + if (s >= 0xff000000) \ + dst[x] = s; \ + else if (s != 0) \ + dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ + } \ +\ for (; x < length-3; x += 4) { \ const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ /* all opaque */ \ - _mm_storeu_si128((__m128i *)&dst[x], srcVector); \ + _mm_store_si128((__m128i *)&dst[x], srcVector); \ } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ /* not fully transparent */ \ /* extract the alpha channel on 2 x 16 bits */ \ @@ -157,13 +169,13 @@ QT_BEGIN_NAMESPACE alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); \ alphaChannel = _mm_sub_epi16(one, alphaChannel); \ \ - const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]); \ + const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ __m128i destMultipliedByOneMinusAlpha; \ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ \ /* result = s + d * (1-alpha) */\ const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_storeu_si128((__m128i *)&dst[x], result); \ + _mm_store_si128((__m128i *)&dst[x], result); \ } \ } \ for (; x < length; ++x) { \ @@ -189,6 +201,17 @@ QT_BEGIN_NAMESPACE #define BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, length, nullVector, half, one, colorMask, constAlphaVector) \ { \ int x = 0; \ +\ + const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\ + const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ + for (; x < prologLength; ++x) { \ + quint32 s = src[x]; \ + if (s != 0) { \ + s = BYTE_MUL(s, const_alpha); \ + dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); \ + } \ + } \ +\ for (; x < length-3; x += 4) { \ __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); \ if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { \ @@ -198,12 +221,12 @@ QT_BEGIN_NAMESPACE alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); \ alphaChannel = _mm_sub_epi16(one, alphaChannel); \ \ - const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]); \ + 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_storeu_si128((__m128i *)&dst[x], result); \ + _mm_store_si128((__m128i *)&dst[x], result); \ } \ } \ for (; x < length; ++x) { \ diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 910b2df..e521e01 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -696,11 +696,10 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount) linef = d->matrix.map(QLineF(lines[i])); } if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -730,11 +729,10 @@ 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 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -1690,8 +1688,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 = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); + xpoints[i].x = qFloor(clippedPoints[i].x + aliasedCoordinateDelta); + xpoints[i].y = qFloor(clippedPoints[i].y + aliasedCoordinateDelta); } uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); XPoint *pts = xpoints.data(); diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h index 8e635a8..ea5f353 100644 --- a/src/gui/painting/qrgb.h +++ b/src/gui/painting/qrgb.h @@ -64,7 +64,7 @@ Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb) // get blue part of RGB { return (rgb & 0xff); } Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb) // get alpha part of RGBA -{ return ((rgb >> 24) & 0xff); } +{ return rgb >> 24; } Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)// set RGB value { return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } 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/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/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 43fa4b9..dff525e 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -4283,6 +4283,13 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op } break; + case PE_FrameMenu: + if (rule.hasDrawable()) { + // Drawn by PE_PanelMenu + return; + } + break; + case PE_PanelMenuBar: if (rule.hasDrawable()) { // Drawn by PE_Widget 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/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index f691413..52a1fe7 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -94,7 +94,7 @@ bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *len } else { *length = tableByteLength; if (buffer) - qMemCopy(buffer, fontTable.TableContent(), tableByteLength); + memcpy(buffer, fontTable.TableContent(), tableByteLength); } fontTable.Close(); @@ -146,7 +146,7 @@ bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *len } else { *length = tableByteLength; if (buffer) - qMemCopy(buffer, table, tableByteLength); + memcpy(buffer, table, tableByteLength); } m_trueTypeExtension->ReleaseTrueTypeTable(table); @@ -374,7 +374,10 @@ glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph) QFixed QFontEngineS60::ascent() const { - return m_originalFont->FontMaxAscent(); + // Workaround for QTBUG-8013 + // Stroke based fonts may return an incorrect FontMaxAscent of 0. + const QFixed ascent = m_originalFont->FontMaxAscent(); + return (ascent > 0) ? ascent : QFixed::fromReal(m_originalFontSizeInPixels) - descent(); } QFixed QFontEngineS60::descent() const diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 91a6612..7396bcd 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -148,9 +148,7 @@ QStaticText::QStaticText() } /*! - Constructs a QStaticText object with the given \a text and bounded by the given \a size. - - If an invalid size is passed for \a size the text will be unbounded. + Constructs a QStaticText object with the given \a text. */ QStaticText::QStaticText(const QString &text) : data(new QStaticTextPrivate) @@ -465,16 +463,21 @@ namespace { m_chars.resize(m_chars.size() + ti.num_chars); glyph_t *glyphsDestination = m_glyphs.data() + currentItem.glyphOffset; - qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * currentItem.numGlyphs); + memcpy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * currentItem.numGlyphs); QFixedPoint *positionsDestination = m_positions.data() + currentItem.positionOffset; - qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * currentItem.numGlyphs); + memcpy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * currentItem.numGlyphs); QChar *charsDestination = m_chars.data() + currentItem.charOffset; - qMemCopy(charsDestination, ti.chars, sizeof(QChar) * currentItem.numChars); + memcpy(charsDestination, ti.chars, sizeof(QChar) * currentItem.numChars); m_items.append(currentItem); - } + } + + virtual void drawPolygon(const QPointF *, int , PolygonDrawMode ) + { + /* intentionally empty */ + } virtual bool begin(QPaintDevice *) { return true; } virtual bool end() { return true; } @@ -681,13 +684,13 @@ void QStaticTextPrivate::init() items = new QStaticTextItem[itemCount]; glyphPool = new glyph_t[glyphs.size()]; - qMemCopy(glyphPool, glyphs.constData(), glyphs.size() * sizeof(glyph_t)); + memcpy(glyphPool, glyphs.constData(), glyphs.size() * sizeof(glyph_t)); positionPool = new QFixedPoint[positions.size()]; - qMemCopy(positionPool, positions.constData(), positions.size() * sizeof(QFixedPoint)); + memcpy(positionPool, positions.constData(), positions.size() * sizeof(QFixedPoint)); charPool = new QChar[chars.size()]; - qMemCopy(charPool, chars.constData(), chars.size() * sizeof(QChar)); + memcpy(charPool, chars.constData(), chars.size() * sizeof(QChar)); for (int i=0; i<itemCount; ++i) { items[i] = deviceItems.at(i); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 7b3f985..213db7e 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1649,7 +1649,7 @@ void QTextDocumentPrivate::compressPieceTable() int newLen = 0; for (FragmentMap::Iterator it = fragments.begin(); !it.atEnd(); ++it) { - qMemCopy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar)); + memcpy(newTextPtr, text.constData() + it->stringPosition, it->size_array[0] * sizeof(QChar)); it->stringPosition = newLen; newTextPtr += it->size_array[0]; newLen += it->size_array[0]; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index d6535ea..674064e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1935,7 +1935,7 @@ 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) { - if (lbh.calculateNewWidth(line) + lbh.minimumRightBearing > line.width) + if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width) lbh.adjustRightBearing(); if (lbh.checkFullOtherwiseExtend(line)) { if (!breakany) { diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index f386871..5fb3384 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1148,7 +1148,7 @@ int QTextBlock::charFormatIndex() const direction from the blocks content. Returns either Qt::LeftToRight or Qt::RightToLeft. - \sa QTextBlock::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection + \sa QTextFormat::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection */ Qt::LayoutDirection QTextBlock::textDirection() const { diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index e3985ce..c291f25 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -935,12 +935,13 @@ void QTextTable::removeColumns(int pos, int num) for (int r = 0; r < d->nRows; ++r) { for (int c = pos; c < pos + num; ++c) { int cell = d->grid[r*d->nCols + c]; - if (touchedCells.contains(cell)) - continue; - touchedCells << cell; QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell); QTextCharFormat fmt = collection->charFormat(it->format); int span = fmt.tableCellColumnSpan(); + if (touchedCells.contains(cell) && span <= 1) + continue; + touchedCells << cell; + if (span > 1) { fmt.setTableCellColumnSpan(span - 1); p->setCharFormat(it.position(), 1, fmt); diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 34311a9..af8daa5 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -197,8 +197,6 @@ contains(QT_CONFIG, freetype) { # pull in the proper freetype2 include directory include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri) LIBS_PRIVATE += -lfreetype -} else { - DEFINES *= QT_NO_FREETYPE } contains(QT_CONFIG, fontconfig) { diff --git a/src/gui/util/qdesktopservices_x11.cpp b/src/gui/util/qdesktopservices_x11.cpp index fe7f9a6..75e7209 100644 --- a/src/gui/util/qdesktopservices_x11.cpp +++ b/src/gui/util/qdesktopservices_x11.cpp @@ -71,10 +71,12 @@ static bool openDocument(const QUrl &url) if (launch(url, QLatin1String("xdg-open"))) return true; - if (X11->desktopEnvironment == DE_GNOME && launch(url, QLatin1String("gnome-open"))) { + // Use the X11->desktopEnvironment value if X11 is non-NULL, + // otherwise just attempt to launch command regardless of the desktop environment + if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { return true; } else { - if (X11->desktopEnvironment == DE_KDE && launch(url, QLatin1String("kfmclient exec"))) + if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient exec"))) return true; } @@ -104,10 +106,12 @@ static bool launchWebBrowser(const QUrl &url) if (launch(url, QString::fromLocal8Bit(getenv("BROWSER")))) return true; - if (X11->desktopEnvironment == DE_GNOME && launch(url, QLatin1String("gnome-open"))) { + // Use the X11->desktopEnvironment value if X11 is non-NULL, + // otherwise just attempt to launch command regardless of the desktop environment + if ((!X11 || (X11 && X11->desktopEnvironment == DE_GNOME)) && launch(url, QLatin1String("gnome-open"))) { return true; } else { - if (X11->desktopEnvironment == DE_KDE && launch(url, QLatin1String("kfmclient openURL"))) + if ((!X11 || (X11 && X11->desktopEnvironment == DE_KDE)) && launch(url, QLatin1String("kfmclient openURL"))) return true; } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 1bffde1..981e934 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1663,8 +1663,11 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) } #endif d->control->processKeyEvent(event); - if (event->isAccepted()) + if (event->isAccepted()) { + if (layoutDirection() != d->control->layoutDirection()) + setLayoutDirection(d->control->layoutDirection()); d->control->setCursorBlinkPeriod(0); + } } /*! @@ -1946,7 +1949,8 @@ void QLineEdit::paintEvent(QPaintEvent *) if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){ flags |= QLineControl::DrawSelections; // Palette only used for selections/mask and may not be in sync - if(d->control->palette() != pal) + if (d->control->palette() != pal + || d->control->palette().currentColorGroup() != pal.currentColorGroup()) d->control->setPalette(pal); } diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index b8cef93..1bfc746 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -48,6 +48,7 @@ #include <Carbon/Carbon.h> #else #include <private/qcocoatoolbardelegate_mac_p.h> +#import <private/qcocoawindowdelegate_mac_p.h> #endif QT_BEGIN_NAMESPACE @@ -337,6 +338,17 @@ void QMainWindowLayout::updateHIToolBarStatus() #endif layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though +#if defined(QT_MAC_USE_COCOA) + QMacCocoaAutoReleasePool pool; + NSView *cView = [qt_mac_window_for(layoutState.mainWindow) contentView]; + if (useMacToolbar) { + [cView setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver: [QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] + selector: @selector(syncContentViewFrame:) + name: NSViewFrameDidChangeNotification + object: cView]; + } +#endif if (!useMacToolbar) { macWindowToolbarShow(layoutState.mainWindow, false); // Move everything out of the HIToolbar into the main toolbar. @@ -356,6 +368,14 @@ void QMainWindowLayout::updateHIToolBarStatus() } syncUnifiedToolbarVisibility(); } +#if defined(QT_MAC_USE_COCOA) + if (!useMacToolbar) { + [cView setPostsFrameChangedNotifications:NO]; + [[NSNotificationCenter defaultCenter] removeObserver: [QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] + name: NSViewFrameDidChangeNotification + object: cView]; + } +#endif layoutState.mainWindow->setUpdatesEnabled(true); } diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index d692307..bbc7e5d 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1219,6 +1219,12 @@ void QTabBar::setCurrentIndex(int index) if (oldIndex >= 0 && oldIndex < count()) d->layoutTab(oldIndex); d->layoutTab(index); +#ifndef QT_NO_ACCESSIBILITY + if (QAccessible::isActive()) { + QAccessible::updateAccessibility(this, index + 1, QAccessible::Focus); + QAccessible::updateAccessibility(this, index + 1, QAccessible::Selection); + } +#endif #ifdef QT3_SUPPORT emit selected(index); #endif |