summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorFabien Freling <fabien.freling@nokia.com>2010-10-08 16:37:25 (GMT)
committerFabien Freling <fabien.freling@nokia.com>2010-10-08 16:37:59 (GMT)
commit1966b88611bb45d18d586847eeb3597d6e022eb7 (patch)
tree0bba3169a8bc44761686fd967f1cb25e4beca97a /src/gui/painting
parent392ecc76cdbcef37ee492400a1b783106a37ad36 (diff)
downloadQt-1966b88611bb45d18d586847eeb3597d6e022eb7.zip
Qt-1966b88611bb45d18d586847eeb3597d6e022eb7.tar.gz
Qt-1966b88611bb45d18d586847eeb3597d6e022eb7.tar.bz2
Experimental support of the unified toolbar with
the raster engine on Mac OS X. Task-number: QTBUG-12615 Reviewed-by: Samuel Rødal
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/painting.pri6
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac.cpp233
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac_p.h95
-rw-r--r--src/gui/painting/qwindowsurface.cpp4
-rw-r--r--src/gui/painting/qwindowsurface_p.h2
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp41
-rw-r--r--src/gui/painting/qwindowsurface_raster_p.h2
7 files changed, 377 insertions, 6 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 793d380..10c6f40 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -247,6 +247,12 @@ symbian {
QMAKE_CXXFLAGS.ARMCC *= -O3
}
+mac {
+ HEADERS += painting/qunifiedtoolbarsurface_mac_p.h
+ SOURCES += painting/qunifiedtoolbarsurface_mac.cpp
+}
+
+
NEON_SOURCES += painting/qdrawhelper_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
new file mode 100644
index 0000000..722355e
--- /dev/null
+++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 "qunifiedtoolbarsurface_mac_p.h"
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qbackingstore_p.h>
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget)
+ : QRasterWindowSurface(widget, false), d_ptr(new QUnifiedToolbarSurfacePrivate)
+{
+ d_ptr->image = 0;
+ d_ptr->inSetGeometry = false;
+ setStaticContentsSupport(true);
+
+ setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height.
+}
+
+QUnifiedToolbarSurface::~QUnifiedToolbarSurface()
+{
+ if (d_ptr->image)
+ delete d_ptr->image;
+}
+
+QPaintDevice *QUnifiedToolbarSurface::paintDevice()
+{
+ return &d_ptr->image->image;
+}
+
+void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &offset)
+{
+ if (object != 0) {
+ if (object->isWidgetType()) {
+ QWidget *widget = qobject_cast<QWidget *>(object);
+ widget->d_func()->unifiedSurface = this;
+ widget->d_func()->isInUnifiedToolbar = true;
+ widget->d_func()->toolbar_offset = offset;
+ }
+
+ for (int i = 0; i < object->children().size(); ++i) {
+ recursiveRedirect(object->children().at(i), offset);
+ }
+ }
+}
+
+void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset)
+{
+ setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME
+ recursiveRedirect(toolbar, offset);
+// toolbar->d_func()->toolbar_offset = offset;
+}
+
+void QUnifiedToolbarSurface::setGeometry(const QRect &rect)
+{
+ QWindowSurface::setGeometry(rect);
+ Q_D(QUnifiedToolbarSurface);
+ d->inSetGeometry = true;
+ if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height())
+ prepareBuffer(QImage::Format_ARGB32_Premultiplied, window());
+ d->inSetGeometry = false;
+}
+
+void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn)
+{
+ QPainter p(&d_ptr->image->image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = rgn.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
+}
+
+void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
+{
+ Q_D(QUnifiedToolbarSurface);
+
+ if (!d->image || rgn.rectCount() == 0) {
+ return;
+ }
+
+ Q_UNUSED(offset);
+
+ // Get a context for the widget.
+ CGContextRef context;
+ if (!(widget->d_func()->hasOwnContext)) {
+ widget->d_func()->ut_rg = rgn;
+ widget->d_func()->ut_pt = offset;
+ qt_mac_display(widget);
+ return;
+ } else {
+ context = widget->d_func()->cgContext;
+ widget->render(widget->d_func()->unifiedSurface->paintDevice(), widget->d_func()->toolbar_offset, QRegion(), QWidget::DrawChildren);
+ }
+
+ CGContextSaveGState(context);
+
+ int areaX = widget->geometry().x() + widget->d_func()->toolbar_offset.x();
+ int areaY = widget->geometry().y() + widget->d_func()->toolbar_offset.y();
+ int areaWidth = widget->geometry().width();
+ int areaHeight = widget->geometry().height();
+ const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight);
+
+ // Clip to region.
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect &rect = rects.at(i);
+ // CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
+ CGContextAddRect(context, CGRectMake(0, 0, 1000, 1000)); //FIXME: Set correct size.
+ }
+ CGContextAddRect(context, area);
+ CGContextClip(context);
+
+
+ CGImageRef image = CGBitmapContextCreateImage(d->image->cg);
+ CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
+
+ const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight);
+ qt_mac_drawCGImage(context, &drawingArea, subImage);
+
+ CGImageRelease(subImage);
+ CGImageRelease(image);
+
+ CGContextFlush(context);
+
+ // Restore context.
+ CGContextRestoreGState(context);
+ widget->d_func()->hasOwnContext = false;
+}
+
+void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget)
+{
+ Q_D(QUnifiedToolbarSurface);
+
+ int width = geometry().width();
+ int height = geometry().height();
+ if (d->image) {
+ width = qMax(d->image->width(), width);
+ height = qMax(d->image->height(), height);
+ }
+
+ if (width == 0 || height == 0) {
+ delete d->image;
+ d->image = 0;
+ return;
+ }
+
+ QNativeImage *oldImage = d->image;
+
+ d->image = new QNativeImage(width, height, format, false, widget);
+
+ if (oldImage && d->inSetGeometry && hasStaticContents()) {
+ // Make sure we use the const version of bits() (no detach).
+ const uchar *src = const_cast<const QImage &>(oldImage->image).bits();
+ uchar *dst = d->image->image.bits();
+
+ const int srcBytesPerLine = oldImage->image.bytesPerLine();
+ const int dstBytesPerLine = d->image->image.bytesPerLine();
+ const int bytesPerPixel = oldImage->image.depth() >> 3;
+
+ QRegion staticRegion(staticContents());
+ // Make sure we're inside the boundaries of the old image.
+ staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height());
+ const QVector<QRect> &rects = staticRegion.rects();
+ const QRect *srcRect = rects.constData();
+
+ // Copy the static content of the old image into the new one.
+ int numRectsLeft = rects.size();
+ do {
+ const int bytesOffset = srcRect->x() * bytesPerPixel;
+ const int dy = srcRect->y();
+
+ // Adjust src and dst to point to the right offset.
+ const uchar *s = src + dy * srcBytesPerLine + bytesOffset;
+ uchar *d = dst + dy * dstBytesPerLine + bytesOffset;
+ const int numBytes = srcRect->width() * bytesPerPixel;
+
+ int numScanLinesLeft = srcRect->height();
+ do {
+ ::memcpy(d, s, numBytes);
+ d += dstBytesPerLine;
+ s += srcBytesPerLine;
+ } while (--numScanLinesLeft);
+
+ ++srcRect;
+ } while (--numRectsLeft);
+ }
+
+ delete oldImage;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
new file mode 100644
index 0000000..d7805e8
--- /dev/null
+++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QUNIFIEDTOOLBARSURFACE_MAC_P_H
+#define QUNIFIEDTOOLBARSURFACE_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qwindowsurface_raster_p.h>
+#include <QWidget>
+#include <private/qwidget_p.h>
+#include <private/qnativeimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNativeImage;
+
+
+class QUnifiedToolbarSurfacePrivate
+{
+public:
+ QNativeImage *image;
+ uint inSetGeometry : 1;
+};
+
+class Q_GUI_EXPORT QUnifiedToolbarSurface : public QRasterWindowSurface
+{
+public:
+ QUnifiedToolbarSurface(QWidget *widget);
+ ~QUnifiedToolbarSurface();
+
+ void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
+ void setGeometry(const QRect &rect);
+ void beginPaint(const QRegion &rgn);
+ void insertToolbar(QWidget *toolbar, const QPoint &offset);
+
+private:
+ QPaintDevice *paintDevice();
+ void prepareBuffer(QImage::Format format, QWidget *widget);
+ void recursiveRedirect(QObject *widget, const QPoint &offset);
+
+ Q_DECLARE_PRIVATE(QUnifiedToolbarSurface)
+ QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QUNIFIEDTOOLBARSURFACE_MAC_P_H
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
index 02a8b80..8cf3977 100644
--- a/src/gui/painting/qwindowsurface.cpp
+++ b/src/gui/painting/qwindowsurface.cpp
@@ -114,11 +114,11 @@ public:
/*!
Constructs an empty surface for the given top-level \a window.
*/
-QWindowSurface::QWindowSurface(QWidget *window)
+QWindowSurface::QWindowSurface(QWidget *window, bool setDefaultSurface)
: d_ptr(new QWindowSurfacePrivate(window))
{
if (!QApplicationPrivate::runtime_graphics_system) {
- if(window)
+ if(setDefaultSurface && window)
window->setWindowSurface(this);
}
}
diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
index 6171ae8..ab84527 100644
--- a/src/gui/painting/qwindowsurface_p.h
+++ b/src/gui/painting/qwindowsurface_p.h
@@ -67,7 +67,7 @@ class QWindowSurfacePrivate;
class Q_GUI_EXPORT QWindowSurface
{
public:
- QWindowSurface(QWidget *window);
+ QWindowSurface(QWidget *window, bool setDefaultSurface = true);
virtual ~QWindowSurface();
QWidget *window() const;
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 6a2cb1e..99f8597 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -64,6 +64,9 @@
#ifdef Q_WS_MAC
#include <private/qt_cocoa_helpers_mac_p.h>
+#include <QMainWindow>
+#include <private/qmainwindowlayout_p.h>
+#include <QToolBar>
#endif
QT_BEGIN_NAMESPACE
@@ -82,8 +85,8 @@ public:
uint inSetGeometry : 1;
};
-QRasterWindowSurface::QRasterWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new QRasterWindowSurfacePrivate)
+QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurface)
+ : QWindowSurface(window, setDefaultSurface), d_ptr(new QRasterWindowSurfacePrivate)
{
#ifdef Q_WS_X11
d_ptr->gc = XCreateGC(X11->display, window->handle(), 0, 0);
@@ -248,6 +251,23 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
#ifdef Q_WS_MAC
+ // Unified toolbar hack.
+ QMainWindow* mWindow = qobject_cast<QMainWindow*>(widget->window());
+ if (mWindow) {
+ QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout());
+ QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList;
+
+ for (int i = 0; i < toolbarList.size(); ++i) {
+ QToolBar* toolbar = toolbarList.at(i);
+ if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) {
+ QWidget* tbWidget = (QWidget*) toolbar;
+ if (tbWidget->d_func()->unifiedSurface) {
+ tbWidget->d_func()->unifiedSurface->flush(tbWidget, rgn, offset);
+ }
+ }
+ }
+ }
+
Q_UNUSED(offset);
// Get a context for the widget.
#ifndef QT_MAC_USE_COCOA
@@ -318,6 +338,23 @@ void QRasterWindowSurface::setGeometry(const QRect &rect)
prepareBuffer(QNativeImage::systemFormat(), window());
}
d->inSetGeometry = false;
+#ifdef Q_WS_MAC
+ QMainWindow* mWindow = qobject_cast<QMainWindow*>(window());
+ if (mWindow) {
+ QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout());
+ QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList;
+
+ for (int i = 0; i < toolbarList.size(); ++i) {
+ QToolBar* toolbar = toolbarList.at(i);
+ if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) {
+ QWidget* tbWidget = (QWidget*) toolbar;
+ if (tbWidget->d_func()->unifiedSurface) {
+ tbWidget->d_func()->unifiedSurface->setGeometry(rect);
+ }
+ }
+ }
+ }
+#endif // Q_WS_MAC
}
// from qwindowsurface.cpp
diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h
index 2b932a9..a7c3b9f 100644
--- a/src/gui/painting/qwindowsurface_raster_p.h
+++ b/src/gui/painting/qwindowsurface_raster_p.h
@@ -97,7 +97,7 @@ class QNativeImage;
class Q_GUI_EXPORT QRasterWindowSurface : public QWindowSurface
{
public:
- QRasterWindowSurface(QWidget *widget);
+ QRasterWindowSurface(QWidget *widget, bool setDefaultSurface = true);
~QRasterWindowSurface();
QPaintDevice *paintDevice();