summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Boddie <dboddie@trolltech.com>2009-08-26 15:50:44 (GMT)
committerDavid Boddie <dboddie@trolltech.com>2009-08-26 15:50:44 (GMT)
commit1be8c6dc12b0158955bf88af450982d6688754d9 (patch)
tree1b80419c0b8ccd5bab30bc64cf64472b9f6b82c5 /src
parent2b7aaf18660fb6639a97b0421563696648384948 (diff)
parent9385eebd22e005ff6027594ea643a8f46ed2e3e3 (diff)
downloadQt-1be8c6dc12b0158955bf88af450982d6688754d9.zip
Qt-1be8c6dc12b0158955bf88af450982d6688754d9.tar.gz
Qt-1be8c6dc12b0158955bf88af450982d6688754d9.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into 4.6
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp327
-rw-r--r--src/corelib/kernel/qabstractitemmodel.h13
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h7
-rw-r--r--src/gui/effects/qgraphicseffect.cpp4
-rw-r--r--src/gui/painting/qpaintengineex_p.h3
-rw-r--r--src/gui/painting/qpainter.cpp39
-rw-r--r--src/gui/painting/qpainter.h3
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h48
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp34
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h5
-rw-r--r--src/opengl/qglpixmapfilter.cpp1
-rw-r--r--src/openvg/qpaintengine_vg.cpp63
-rw-r--r--src/openvg/qpaintengine_vg_p.h3
13 files changed, 479 insertions, 71 deletions
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 3b7059b..fb0afcc 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -599,6 +599,118 @@ void QAbstractItemModelPrivate::rowsInserted(const QModelIndex &parent,
}
}
+void QAbstractItemModelPrivate::itemsAboutToBeMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation)
+{
+ Q_Q(QAbstractItemModel);
+ QVector<QPersistentModelIndexData *> persistent_moved_explicitly;
+ QVector<QPersistentModelIndexData *> persistent_moved_in_source;
+ QVector<QPersistentModelIndexData *> persistent_moved_in_destination;
+
+ QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it;
+ const QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator begin = persistent.indexes.constBegin();
+ const QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator end = persistent.indexes.constEnd();
+
+ const bool sameParent = (srcParent == destinationParent);
+ const bool movingUp = (srcFirst > destinationChild);
+
+ for ( it = begin; it != end; ++it) {
+ QPersistentModelIndexData *data = *it;
+ const QModelIndex &index = data->index;
+ const QModelIndex &parent = index.parent();
+ const bool isSourceIndex = (parent == srcParent);
+ const bool isDestinationIndex = (parent == destinationParent);
+
+ int childPosition;
+ if (orientation == Qt::Vertical)
+ childPosition = index.row();
+ else
+ childPosition = index.column();
+
+ if (!index.isValid() || !(isSourceIndex || isDestinationIndex ) )
+ continue;
+
+ if (!sameParent && isDestinationIndex) {
+ if (childPosition >= destinationChild)
+ persistent_moved_in_destination.append(data);
+ continue;
+ }
+
+ if (sameParent && movingUp && childPosition < destinationChild)
+ continue;
+
+ if (sameParent && !movingUp && childPosition < srcFirst )
+ continue;
+
+ if (!sameParent && childPosition < srcFirst)
+ continue;
+
+ if (sameParent && (childPosition > srcLast) && (childPosition >= destinationChild ))
+ continue;
+
+ if ((childPosition <= srcLast) && (childPosition >= srcFirst)) {
+ persistent_moved_explicitly.append(data);
+ } else {
+ persistent_moved_in_source.append(data);
+ }
+ }
+ persistent.moved.push(persistent_moved_explicitly);
+ persistent.moved.push(persistent_moved_in_source);
+ persistent.moved.push(persistent_moved_in_destination);
+}
+
+/*!
+ \internal
+
+ Moves persistent indexes \a indexes by amount \a change. The change will be either a change in row value or a change in
+ column value depending on the value of \a orientation. The indexes may also be moved to a different parent if \a parent
+ differs from the existing parent for the index.
+*/
+void QAbstractItemModelPrivate::movePersistentIndexes(QVector<QPersistentModelIndexData *> indexes, int change, const QModelIndex &parent, Qt::Orientation orientation)
+{
+ QVector<QPersistentModelIndexData *>::const_iterator it;
+ const QVector<QPersistentModelIndexData *>::const_iterator begin = indexes.constBegin();
+ const QVector<QPersistentModelIndexData *>::const_iterator end = indexes.constEnd();
+
+ for (it = begin; it != end; ++it)
+ {
+ QPersistentModelIndexData *data = *it;
+
+ int row = data->index.row();
+ int column = data->index.column();
+
+ if (Qt::Vertical == orientation)
+ row += change;
+ else
+ column += change;
+
+ persistent.indexes.erase(persistent.indexes.find(data->index));
+ data->index = q_func()->index(row, column, parent);
+ if (data->index.isValid()) {
+ persistent.insertMultiAtEnd(data->index, data);
+ } else {
+ qWarning() << "QAbstractItemModel::endMoveRows: Invalid index (" << row << "," << column << ") in model" << q_func();
+ }
+ }
+}
+
+void QAbstractItemModelPrivate::itemsMoved(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation)
+{
+ QVector<QPersistentModelIndexData *> moved_in_destination = persistent.moved.pop();
+ QVector<QPersistentModelIndexData *> moved_in_source = persistent.moved.pop();
+ QVector<QPersistentModelIndexData *> moved_explicitly = persistent.moved.pop();
+
+ const bool sameParent = (sourceParent == destinationParent);
+ const bool movingUp = (sourceFirst > destinationChild);
+
+ const int explicit_change = (!sameParent || movingUp) ? destinationChild - sourceFirst : destinationChild - sourceLast - 1 ;
+ const int source_change = (!sameParent || !movingUp) ? -1*(sourceLast - sourceFirst + 1) : sourceLast - sourceFirst + 1 ;
+ const int destination_change = sourceLast - sourceFirst + 1;
+
+ movePersistentIndexes(moved_explicitly, explicit_change, destinationParent, orientation);
+ movePersistentIndexes(moved_in_source, source_change, sourceParent, orientation);
+ movePersistentIndexes(moved_in_destination, destination_change, destinationParent, orientation);
+}
+
void QAbstractItemModelPrivate::rowsAboutToBeRemoved(const QModelIndex &parent,
int first, int last)
{
@@ -1370,6 +1482,36 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
+ \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+
+ This signal is emitted after rows have been moved within the
+ model. The items between \a sourceStart and \a sourceEnd
+ inclusive, under the given \a sourceParent item have been moved to \a destinationParent
+ starting at the row \a destinationRow.
+
+ \bold{Note:} Components connected to this signal use it to adapt to changes
+ in the model's dimensions. It can only be emitted by the QAbstractItemModel
+ implementation, and cannot be explicitly emitted in subclass code.
+
+ \sa beginMoveRows()
+*/
+
+/*!
+ \fn void QAbstractItemModel::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+
+ This signal is emitted just before rows are moved within the
+ model. The items that will be moved are those between \a sourceStart and \a sourceEnd
+ inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
+ starting at the row \a destinationRow.
+
+ \bold{Note:} Components connected to this signal use it to adapt to changes
+ in the model's dimensions. It can only be emitted by the QAbstractItemModel
+ implementation, and cannot be explicitly emitted in subclass code.
+
+ \sa beginMoveRows()
+*/
+
+/*!
\fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int start, int end)
This signal is emitted after columns have been inserted into the model. The
@@ -2284,6 +2426,116 @@ void QAbstractItemModel::endRemoveRows()
}
/*!
+ Returns whether a move operation is valid.
+
+ A move operation is not allowed if it moves a continuous range of rows to a destination within
+ itself, or if it attempts to move a row to one of its own descendants.
+
+ \internal
+*/
+bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int start, int end, const QModelIndex &destinationParent, int destinationStart, Qt::Orientation orientation)
+{
+ Q_Q(QAbstractItemModel);
+ // Don't move the range within itself.
+ if ( ( destinationParent == srcParent )
+ && ( destinationStart >= start )
+ && ( destinationStart <= end + 1) )
+ return false;
+
+ QModelIndex destinationAncestor = destinationParent;
+ int pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
+ forever {
+ if (destinationAncestor == srcParent) {
+ if (pos >= start && pos <= end)
+ return false;
+ break;
+ }
+
+ if (!destinationAncestor.isValid())
+ break;
+
+ pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
+ destinationAncestor = destinationAncestor.parent();
+ }
+
+ return true;
+}
+
+/*!
+ Begins a row move operation.
+
+ When reimplementing a subclass, this method simplifies moving entities
+ in your model. This method is responsible for moving persistent indexes
+ in the model, which you would otherwise be required to do yourself.
+
+ Using beginMoveRows and endMoveRows is an alternative to emitting
+ layoutAboutToBeChanged and layoutChanged directly along with changePersistentIndexes.
+ layoutAboutToBeChanged is emitted by this method for compatibility reasons.
+
+ The \a sourceParent index corresponds to the parent from which the
+ rows are moved; \a sourceFirst and \a sourceLast are the row numbers of the
+ rows to be moved. The \a destinationParent index corresponds to the parent into which
+ the rows are moved. The \a destinationRow is the row to which the rows will be moved.
+ That is, the index at row \a sourceFirst in \a sourceParent will become row \a destinationRow
+ in \a destinationParent. Its siblings will be moved correspondingly.
+
+ Note that \a sourceParent and \a destinationParent may be the same, in which case you must
+ ensure that the \a destinationRow is not within the range of \a sourceFirst and \a sourceLast.
+ You must also ensure that you do not attempt to move a row to one of its own chilren or ancestors.
+ This method returns false if either condition is true, in which case you should abort your move operation.
+
+ \sa endMoveRows()
+
+ \since 4.6
+*/
+bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
+{
+ Q_ASSERT(sourceFirst >= 0);
+ Q_ASSERT(sourceLast >= sourceFirst);
+ Q_ASSERT(destinationChild >= 0);
+ Q_D(QAbstractItemModel);
+
+ if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical)) {
+ return false;
+ }
+
+ d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
+ int destinationLast = destinationChild + (sourceLast - sourceFirst);
+ d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
+
+ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical);
+ emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
+ emit layoutAboutToBeChanged();
+ return true;
+}
+
+/*!
+ Ends a row move operation.
+
+ When implementing a subclass, you must call this
+ function \e after moving data within the model's underlying data
+ store.
+
+ layoutChanged is emitted by this method for compatibility reasons.
+
+ \sa beginMoveRows()
+
+ \since 4.6
+*/
+void QAbstractItemModel::endMoveRows()
+{
+ Q_D(QAbstractItemModel);
+
+ QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
+ QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
+
+ d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Vertical);
+
+ emit rowsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
+ emit layoutChanged();
+}
+
+/*!
Begins a column insertion operation.
When reimplementing insertColumns() in a subclass, you must call this
@@ -2406,6 +2658,81 @@ void QAbstractItemModel::endRemoveColumns()
}
/*!
+ Begins a column move operation.
+
+ When reimplementing a subclass, this method simplifies moving entities
+ in your model. This method is responsible for moving persistent indexes
+ in the model, which you would otherwise be required to do yourself.
+
+ Using beginMoveColumns and endMoveColumns is an alternative to emitting
+ layoutAboutToBeChanged and layoutChanged directly along with changePersistentIndexes.
+ layoutAboutToBeChanged is emitted by this method for compatibility reasons.
+
+ The \a sourceParent index corresponds to the parent from which the
+ columns are moved; \a sourceFirst and \a sourceLast are the column numbers of the
+ columns to be moved. The \a destinationParent index corresponds to the parent into which
+ the columns are moved. The \a destinationColumn is the column to which the columns will be moved.
+ That is, the index at column \a sourceFirst in \a sourceParent will become column \a destinationColumn
+ in \a destinationParent. Its siblings will be moved correspondingly.
+
+ Note that \a sourceParent and \a destinationParent may be the same, in which case you must
+ ensure that the \a destinationColumn is not within the range of \a sourceFirst and \a sourceLast.
+ You must also ensure that you do not attempt to move a row to one of its own chilren or ancestors.
+ This method returns false if either condition is true, in which case you should abort your move operation.
+
+ \sa endMoveColumns()
+
+ \since 4.6
+*/
+bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
+{
+ Q_ASSERT(sourceFirst >= 0);
+ Q_ASSERT(sourceLast >= sourceFirst);
+ Q_ASSERT(destinationChild >= 0);
+ Q_D(QAbstractItemModel);
+
+ if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal)) {
+ return false;
+ }
+
+ d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
+ int destinationLast = destinationChild + (sourceLast - sourceFirst);
+ d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
+
+ d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
+
+ emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
+ emit layoutAboutToBeChanged();
+ return true;
+}
+
+/*!
+ Ends a column move operation.
+
+ When implementing a subclass, you must call this
+ function \e after moving data within the model's underlying data
+ store.
+
+ layoutChanged is emitted by this method for compatibility reasons.
+
+ \sa beginMoveColumns()
+
+ \since 4.6
+*/
+void QAbstractItemModel::endMoveColumns()
+{
+ Q_D(QAbstractItemModel);
+
+ QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
+ QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
+
+ d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Horizontal);
+
+ emit columnsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
+ emit layoutChanged();
+}
+
+/*!
Resets the model to its original state in any attached views.
The view to which the model is attached to will be reset as well.
diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h
index 00f6cb2..b47e4cb 100644
--- a/src/corelib/kernel/qabstractitemmodel.h
+++ b/src/corelib/kernel/qabstractitemmodel.h
@@ -252,6 +252,13 @@ private: // can only be emitted by QAbstractItemModel
void modelAboutToBeReset();
void modelReset();
+ void rowsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow );
+ void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row );
+
+ void columnsAboutToBeMoved( const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn );
+ void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column );
+
+
public Q_SLOTS:
virtual bool submit();
virtual void revert();
@@ -272,12 +279,18 @@ protected:
void beginRemoveRows(const QModelIndex &parent, int first, int last);
void endRemoveRows();
+ bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationRow);
+ void endMoveRows();
+
void beginInsertColumns(const QModelIndex &parent, int first, int last);
void endInsertColumns();
void beginRemoveColumns(const QModelIndex &parent, int first, int last);
void endRemoveColumns();
+ bool beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationColumn);
+ void endMoveColumns();
+
void reset();
void changePersistentIndex(const QModelIndex &from, const QModelIndex &to);
diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h
index e81e627..aae3cba 100644
--- a/src/corelib/kernel/qabstractitemmodel_p.h
+++ b/src/corelib/kernel/qabstractitemmodel_p.h
@@ -80,6 +80,7 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
public:
QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {}
void removePersistentIndexData(QPersistentModelIndexData *data);
+ void movePersistentIndexes(QVector<QPersistentModelIndexData *> indexes, int change, const QModelIndex &parent, Qt::Orientation orientation);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void rowsInserted(const QModelIndex &parent, int first, int last);
void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
@@ -91,6 +92,10 @@ public:
static QAbstractItemModel *staticEmptyModel();
static bool variantLessThan(const QVariant &v1, const QVariant &v2);
+ void itemsAboutToBeMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation);
+ void itemsMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
+ bool allowMove(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation);
+
inline QModelIndex createIndex(int row, int column, void *data = 0) const {
return q_func()->createIndex(row, column, data);
}
@@ -132,6 +137,8 @@ public:
Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l) {}
QModelIndex parent;
int first, last;
+
+ bool isValid() { return first >= 0 && last >= 0; }
};
QStack<Change> changes;
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index 0289914..f620878 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -61,13 +61,13 @@
Qt provides the following standard effects:
\list
- \o QGraphicsGrayScaleEffect - renders the item in shades of gray
+ \o QGraphicsGrayscaleEffect - renders the item in shades of gray
\o QGraphicsColorizeEffect - renders the item in shades of any given color
\o QGraphicsPixelizeEffect - pixelizes the item with any pixel size
\o QGraphicsBlurEffect - blurs the item by a given radius
\o QGraphicsDropShadowEffect - renders a dropshadow behind the item
\o QGraphicsOpacityEffect - renders the item with an opacity
- \o QGrahicsShaderEffect - renders the item with a pixel shader fragment
+ \o QGraphicsShaderEffect - renders the item with a pixel shader fragment
\endlist
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index cf3aad7..1ba2153 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -204,6 +204,9 @@ public:
virtual void sync() {}
+ virtual void beginNativePainting() {}
+ virtual void endNativePainting() {}
+
virtual QPixmapFilter *createPixmapFilter(int /*type*/) const { return 0; }
protected:
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e1a6e80..cba4ad9 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1889,6 +1889,45 @@ QPaintEngine *QPainter::paintEngine() const
return d->engine;
}
+/*!
+ Flushes the painting pipeline and prepares for the user issuing
+ native painting commands. Must be followed by a call to
+ endNativePainting().
+
+ \sa endNativePainting()
+*/
+void QPainter::beginNativePainting()
+{
+ Q_D(QPainter);
+ if (!d->engine) {
+ qWarning("QPainter::beginNativePainting: Painter not active");
+ return;
+ }
+
+ if (d->extended)
+ d->extended->beginNativePainting();
+}
+
+/*!
+ Restores the painter after manually issuing native painting commands.
+ Lets the painter restore any native state that it relies on before
+ calling any other painter commands.
+
+ \sa beginNativePainting()
+*/
+void QPainter::endNativePainting()
+{
+ Q_D(const QPainter);
+ if (!d->engine) {
+ qWarning("QPainter::beginNativePainting: Painter not active");
+ return;
+ }
+
+ if (d->extended)
+ d->extended->endNativePainting();
+ else
+ d->engine->syncState();
+}
/*!
Returns the font metrics for the painter if the painter is
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 14d1cf8..1bb97c6 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -423,6 +423,9 @@ public:
static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = 0);
static void restoreRedirected(const QPaintDevice *device);
+ void beginNativePainting();
+ void endNativePainting();
+
#ifdef QT3_SUPPORT
inline QT3_SUPPORT void setBackgroundColor(const QColor &color) { setBackground(color); }
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index a8e2e72..cd3cf57 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -73,8 +73,8 @@ static const char* const qglslMainVertexShader = "\
}";
static const char* const qglslMainWithTexCoordsVertexShader = "\
- attribute mediump vec2 textureCoordArray; \
- varying mediump vec2 textureCoords; \
+ attribute highp vec2 textureCoordArray; \
+ varying highp vec2 textureCoords; \
uniform highp float depth;\
void setPosition();\
void main(void) \
@@ -105,9 +105,9 @@ static const char* const qglslPositionWithPatternBrushVertexShader = "\
attribute highp vec4 vertexCoordsArray; \
uniform highp mat4 pmvMatrix; \
uniform mediump vec2 halfViewportSize; \
- uniform mediump vec2 invertedTextureSize; \
- uniform mediump mat3 brushTransform; \
- varying mediump vec2 patternTexCoords; \
+ uniform highp vec2 invertedTextureSize; \
+ uniform highp mat3 brushTransform; \
+ varying highp vec2 patternTexCoords; \
void setPosition(void) { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
@@ -124,9 +124,9 @@ static const char* const qglslAffinePositionWithPatternBrushVertexShader
= qglslPositionWithPatternBrushVertexShader;
static const char* const qglslPatternBrushSrcFragmentShader = "\
- uniform sampler2D brushTexture;\
+ uniform lowp sampler2D brushTexture;\
uniform lowp vec4 patternColor; \
- varying mediump vec2 patternTexCoords;\
+ varying highp vec2 patternTexCoords;\
lowp vec4 srcPixel() { \
return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \
}\n";
@@ -139,7 +139,7 @@ static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\
uniform mediump vec2 halfViewportSize; \
uniform highp vec3 linearData; \
uniform highp mat3 brushTransform; \
- varying mediump float index ; \
+ varying mediump float index; \
void setPosition() { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
@@ -155,7 +155,7 @@ static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader
= qglslPositionWithLinearGradientBrushVertexShader;
static const char* const qglslLinearGradientBrushSrcFragmentShader = "\
- uniform sampler2D brushTexture; \
+ uniform lowp sampler2D brushTexture; \
varying mediump float index; \
lowp vec4 srcPixel() { \
mediump vec2 val = vec2(index, 0.5); \
@@ -187,7 +187,7 @@ static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader
static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\
#define INVERSE_2PI 0.1591549430918953358 \n\
- uniform sampler2D brushTexture; \n\
+ uniform lowp sampler2D brushTexture; \n\
uniform mediump float angle; \
varying highp vec2 A; \
lowp vec4 srcPixel() { \
@@ -226,7 +226,7 @@ static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader
= qglslPositionWithRadialGradientBrushVertexShader;
static const char* const qglslRadialGradientBrushSrcFragmentShader = "\
- uniform sampler2D brushTexture; \
+ uniform lowp sampler2D brushTexture; \
uniform highp float fmp2_m_radius2; \
uniform highp float inverse_2_fmp2_m_radius2; \
varying highp float b; \
@@ -243,9 +243,9 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\
attribute highp vec4 vertexCoordsArray; \
uniform highp mat4 pmvMatrix; \
uniform mediump vec2 halfViewportSize; \
- uniform mediump vec2 invertedTextureSize; \
- uniform mediump mat3 brushTransform; \
- varying mediump vec2 brushTextureCoords; \
+ uniform highp vec2 invertedTextureSize; \
+ uniform highp mat3 brushTransform; \
+ varying highp vec2 brushTextureCoords; \
void setPosition(void) { \
gl_Position = pmvMatrix * vertexCoordsArray;\
gl_Position.xy = gl_Position.xy / gl_Position.w; \
@@ -262,16 +262,16 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader
= qglslPositionWithTextureBrushVertexShader;
static const char* const qglslTextureBrushSrcFragmentShader = "\
- varying mediump vec2 brushTextureCoords; \
- uniform sampler2D brushTexture; \
+ varying highp vec2 brushTextureCoords; \
+ uniform lowp sampler2D brushTexture; \
lowp vec4 srcPixel() { \
return texture2D(brushTexture, brushTextureCoords); \
}";
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\
- varying mediump vec2 brushTextureCoords; \
+ varying highp vec2 brushTextureCoords; \
uniform lowp vec4 patternColor; \
- uniform sampler2D brushTexture; \
+ uniform lowp sampler2D brushTexture; \
lowp vec4 srcPixel() { \
return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \
}";
@@ -284,15 +284,15 @@ static const char* const qglslSolidBrushSrcFragmentShader = "\
}";
static const char* const qglslImageSrcFragmentShader = "\
- varying mediump vec2 textureCoords; \
- uniform sampler2D imageTexture; \
+ varying highp vec2 textureCoords; \
+ uniform lowp sampler2D imageTexture; \
lowp vec4 srcPixel() { \
return texture2D(imageTexture, textureCoords); \
}";
static const char* const qglslCustomSrcFragmentShader = "\
varying highp vec2 textureCoords; \
- uniform sampler2D imageTexture; \
+ uniform lowp sampler2D imageTexture; \
lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \
lowp vec4 srcPixel() { \
return customShader(imageTexture, textureCoords); \
@@ -301,14 +301,14 @@ static const char* const qglslCustomSrcFragmentShader = "\
static const char* const qglslImageSrcWithPatternFragmentShader = "\
varying highp vec2 textureCoords; \
uniform lowp vec4 patternColor; \
- uniform sampler2D imageTexture; \
+ uniform lowp sampler2D imageTexture; \
lowp vec4 srcPixel() { \
return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \
}\n";
static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\
varying highp vec2 textureCoords; \
- uniform sampler2D imageTexture; \
+ uniform lowp sampler2D imageTexture; \
lowp vec4 srcPixel() { \
lowp vec4 sample = texture2D(imageTexture, textureCoords); \
sample.rgb = sample.rgb * sample.a; \
@@ -383,7 +383,7 @@ static const char* const qglslMainFragmentShader = "\
static const char* const qglslMaskFragmentShader = "\
varying highp vec2 textureCoords;\
- uniform sampler2D maskTexture;\
+ uniform lowp sampler2D maskTexture;\
lowp vec4 applyMask(lowp vec4 src) \
{\
lowp vec4 mask = texture2D(maskTexture, textureCoords); \
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 136a078..2f565cf 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -376,6 +376,7 @@ void QGL2PaintEngineExPrivate::useSimpleShader()
void QGL2PaintEngineExPrivate::updateBrushTexture()
{
+ Q_Q(QGL2PaintEngineEx);
// qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()");
Qt::BrushStyle style = currentBrush->style();
@@ -385,7 +386,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, true);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true);
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
// Gradiant brush: All the gradiants use the same texture
@@ -400,11 +401,11 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
glBindTexture(GL_TEXTURE_2D, texId);
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true);
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
else if (g->spread() == QGradient::ReflectSpread)
- updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT_IBM, true);
+ updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT_IBM, q->state()->renderHints & QPainter::SmoothPixmapTransform);
else
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, true);
+ updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style == Qt::TexturePattern) {
const QPixmap& texPixmap = currentBrush->texture();
@@ -412,7 +413,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
// TODO: Support y-inverted pixmaps as brushes
ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, true);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true);
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
brushTextureDirty = false;
}
@@ -675,7 +676,7 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
-void QGL2PaintEngineEx::sync()
+void QGL2PaintEngineEx::beginNativePainting()
{
Q_D(QGL2PaintEngineEx);
ensureActive();
@@ -709,15 +710,25 @@ void QGL2PaintEngineEx::sync()
#endif
d->lastTexture = GLuint(-1);
+ d->resetGLState();
+
+ d->needsSync = true;
+}
+void QGL2PaintEngineExPrivate::resetGLState()
+{
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
-
glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
glDepthFunc(GL_LESS);
glDepthMask(true);
glClearDepth(1);
+}
+void QGL2PaintEngineEx::endNativePainting()
+{
+ Q_D(QGL2PaintEngineEx);
d->needsSync = true;
}
@@ -1074,6 +1085,7 @@ void QGL2PaintEngineEx::renderHintsChanged()
Q_D(QGL2PaintEngineEx);
d->lastTexture = GLuint(-1);
+ d->brushTextureDirty = true;
// qDebug("QGL2PaintEngineEx::renderHintsChanged() not implemented!");
}
@@ -1101,7 +1113,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && !pixmap.hasAlphaChannel();
- d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT,
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
}
@@ -1118,7 +1130,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
GLuint id = texture->id;
- d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT,
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
}
@@ -1133,7 +1145,7 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, textureId);
- d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT,
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->drawTexture(dest, src, size, false);
}
@@ -1356,6 +1368,8 @@ bool QGL2PaintEngineEx::end()
d->drawable.doneCurrent();
d->ctx->d_ptr->active_engine = 0;
+ d->resetGLState();
+
return false;
}
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 7b734e3..66e7a51 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -133,7 +133,9 @@ public:
inline const QOpenGL2PaintEngineState *state() const {
return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
}
- virtual void sync();
+
+ void beginNativePainting();
+ void endNativePainting();
const QGLContext* context();
@@ -168,6 +170,7 @@ public:
void setBrush(const QBrush* brush);
void transferMode(EngineMode newMode);
+ void resetGLState();
// fill, drawOutline, drawTexture & drawCachedGlyphs are the rendering entry points:
void fill(const QVectorPath &path);
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index df7811e..83fddd1 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -338,7 +338,6 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const
QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- engine->syncState();
painter->save();
// ensure GL_LINEAR filtering is used
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index d2c7b8b..09eb646 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -3072,43 +3072,42 @@ void QVGPaintEngine::setState(QPainterState *s)
}
}
-// Called from QPaintEngine::syncState() to force a state flush.
-// This should be called before and after raw VG operations.
-void QVGPaintEngine::updateState(const QPaintEngineState &state)
+void QVGPaintEngine::beginNativePainting()
{
- Q_UNUSED(state);
Q_D(QVGPaintEngine);
- if (!(d->rawVG)) {
- // About to enter raw VG mode: flush pending changes and make
- // sure that all matrices are set to the current transformation.
- QVGPainterState *s = this->state();
- d->ensurePen(s->pen);
- d->ensureBrush(s->brush);
- d->ensurePathTransform();
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, d->imageTransform);
+ // About to enter raw VG mode: flush pending changes and make
+ // sure that all matrices are set to the current transformation.
+ QVGPainterState *s = this->state();
+ d->ensurePen(s->pen);
+ d->ensureBrush(s->brush);
+ d->ensurePathTransform();
+ d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, d->imageTransform);
#if !defined(QVG_NO_DRAW_GLYPHS)
- d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform);
+ d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform);
#endif
- d->rawVG = true;
- } else {
- // Exiting raw VG mode: force all state values to be
- // explicitly set on the VG engine to undo any changes
- // that were made by the raw VG function calls.
- QPaintEngine::DirtyFlags dirty = d->dirty;
- d->clearModes();
- d->forcePenChange = true;
- d->forceBrushChange = true;
- d->penType = (VGPaintType)0;
- d->brushType = (VGPaintType)0;
- d->clearColor = QColor();
- d->fillPaint = d->brushPaint;
- restoreState(QPaintEngine::AllDirty);
- d->dirty = dirty;
- d->rawVG = false;
- vgSetPaint(d->penPaint, VG_STROKE_PATH);
- vgSetPaint(d->brushPaint, VG_FILL_PATH);
- }
+ d->rawVG = true;
+}
+
+void QVGPaintEngine::endNativePainting()
+{
+ Q_D(QVGPaintEngine);
+ // Exiting raw VG mode: force all state values to be
+ // explicitly set on the VG engine to undo any changes
+ // that were made by the raw VG function calls.
+ QPaintEngine::DirtyFlags dirty = d->dirty;
+ d->clearModes();
+ d->forcePenChange = true;
+ d->forceBrushChange = true;
+ d->penType = (VGPaintType)0;
+ d->brushType = (VGPaintType)0;
+ d->clearColor = QColor();
+ d->fillPaint = d->brushPaint;
+ restoreState(QPaintEngine::AllDirty);
+ d->dirty = dirty;
+ d->rawVG = false;
+ vgSetPaint(d->penPaint, VG_STROKE_PATH);
+ vgSetPaint(d->brushPaint, VG_FILL_PATH);
}
QPixmapFilter *QVGPaintEngine::createPixmapFilter(int type) const
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
index 469ec9e..f0a7838 100644
--- a/src/openvg/qpaintengine_vg_p.h
+++ b/src/openvg/qpaintengine_vg_p.h
@@ -140,7 +140,8 @@ public:
QVGPainterState *state() { return static_cast<QVGPainterState *>(QPaintEngineEx::state()); }
const QVGPainterState *state() const { return static_cast<const QVGPainterState *>(QPaintEngineEx::state()); }
- void updateState(const QPaintEngineState &state);
+ void beginNativePainting();
+ void endNativePainting();
QPixmapFilter *createPixmapFilter(int type) const;