Source

Target

Commits (15)
Showing with 235 additions and 468 deletions
...@@ -34,8 +34,3 @@ HEADERS += \ ...@@ -34,8 +34,3 @@ HEADERS += \
$$PWD/qqmlprofiler_p.h $$PWD/qqmlprofiler_p.h
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
!contains(DEFINES, QT_QML_NO_DEBUGGER): static {
DEFINES += QML_DEBUGGER_EMBED
include(../../plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pri)
}
...@@ -72,8 +72,8 @@ The following pages show how to develop Qt applications using ...@@ -72,8 +72,8 @@ The following pages show how to develop Qt applications using
\l{Qt Creator Manual}{Qt Creator} and Qt Quick. The pages demonstrate various \l{Qt Creator Manual}{Qt Creator} and Qt Quick. The pages demonstrate various
steps such as use cases and introductory material. For more information about Qt Quick Applications and related modules, visit the \l{QML Applications} page. steps such as use cases and introductory material. For more information about Qt Quick Applications and related modules, visit the \l{QML Applications} page.
\div {class="landingicons"} \div {class="multi-column"}
\div {class="icons1of3"} \div {class="doc-column"}
\b{Development Environment} \b{Development Environment}
\list \list
\li \l{Qt Creator: Creating Qt Quick Projects}{Creating Qt Quick Projects} \li \l{Qt Creator: Creating Qt Quick Projects}{Creating Qt Quick Projects}
...@@ -84,7 +84,7 @@ steps such as use cases and introductory material. For more information about Qt ...@@ -84,7 +84,7 @@ steps such as use cases and introductory material. For more information about Qt
\li \l{Qt Creator: Using QML Modules with Plugins}{Using QML Modules with Plugins} \li \l{Qt Creator: Using QML Modules with Plugins}{Using QML Modules with Plugins}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{Beginning with QML and Qt Quick} \b{Beginning with QML and Qt Quick}
\list \list
\li \l{First Steps with QML} \li \l{First Steps with QML}
...@@ -92,7 +92,7 @@ steps such as use cases and introductory material. For more information about Qt ...@@ -92,7 +92,7 @@ steps such as use cases and introductory material. For more information about Qt
\li \l{QML Advanced Tutorial}{SameGame} \li \l{QML Advanced Tutorial}{SameGame}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{Use Cases} \b{Use Cases}
\list \list
\li \l{qtquick-usecase-visual.html}{Visual types in QML} \li \l{qtquick-usecase-visual.html}{Visual types in QML}
...@@ -120,8 +120,8 @@ Examples are small applications which show how to implement various Qt Quick ...@@ -120,8 +120,8 @@ Examples are small applications which show how to implement various Qt Quick
features. The examples run on various platforms and are opened from within Qt features. The examples run on various platforms and are opened from within Qt
Creator. Creator.
\div {class="landingicons"} \div {class="multi-column"}
\div {class="icons1of3"} \div {class="doc-column"}
\b{QML Types and Controls} \b{QML Types and Controls}
\list \list
\li \l{Qt Quick Controls - Gallery}{Controls Gallery} \li \l{Qt Quick Controls - Gallery}{Controls Gallery}
...@@ -132,7 +132,7 @@ Creator. ...@@ -132,7 +132,7 @@ Creator.
\li \l{Qt Quick Examples - Toggle Switch}{Custom Toggle Switch} \li \l{Qt Quick Examples - Toggle Switch}{Custom Toggle Switch}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{Layouts and Views} \b{Layouts and Views}
\list \list
\li \l{Qt Quick Controls - Basic Layouts Example}{Basic Layouts} \li \l{Qt Quick Controls - Basic Layouts Example}{Basic Layouts}
...@@ -142,7 +142,7 @@ Creator. ...@@ -142,7 +142,7 @@ Creator.
\li \l{Qt Quick Examples - Right to Left}{Right-to-Left and Text Layout} \li \l{Qt Quick Examples - Right to Left}{Right-to-Left and Text Layout}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{Image and Graphics} \b{Image and Graphics}
\list \list
\li \l{Qt Quick Examples - Image Elements}{Image Elements} \li \l{Qt Quick Examples - Image Elements}{Image Elements}
...@@ -153,8 +153,8 @@ Creator. ...@@ -153,8 +153,8 @@ Creator.
\enddiv \enddiv
\enddiv \enddiv
\div {class="landingicons"} \div {class="multi-column"}
\div {class="icons1of3"} \div {class="doc-column"}
\b{Keyboard, Focus, and Touch} \b{Keyboard, Focus, and Touch}
\list \list
\li \l{Qt Quick Examples - Key Interaction}{Key Interaction} \li \l{Qt Quick Examples - Key Interaction}{Key Interaction}
...@@ -162,7 +162,7 @@ Creator. ...@@ -162,7 +162,7 @@ Creator.
\li \l{Qt Quick Controls - Touch Gallery}{Touch Gallery} \li \l{Qt Quick Controls - Touch Gallery}{Touch Gallery}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{System and Events} \b{System and Events}
\list \list
\li \l{Qt Quick Examples - Threading}{Threading} \li \l{Qt Quick Examples - Threading}{Threading}
...@@ -171,7 +171,7 @@ Creator. ...@@ -171,7 +171,7 @@ Creator.
\li \l{Qt Quick Examples - Drag and Drop}{Drag and Drop} \li \l{Qt Quick Examples - Drag and Drop}{Drag and Drop}
\endlist \endlist
\enddiv \enddiv
\div {class="icons1of3"} \div {class="doc-column"}
\b{Scene Graph} \b{Scene Graph}
\list \list
\li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML} \li \l{Scene Graph - OpenGL Under QML}{OpenGL Under QML}
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\qmlmodule QtQuick 2.3 \qmlmodule QtQuick 2.4
\title Qt Quick QML Types \title Qt Quick QML Types
\ingroup qmlmodules \ingroup qmlmodules
\brief Provides graphical QML types. \brief Provides graphical QML types.
...@@ -34,11 +34,11 @@ ...@@ -34,11 +34,11 @@
The \l{Qt Quick} module provides graphical primitive types. These types are only The \l{Qt Quick} module provides graphical primitive types. These types are only
available in a QML document if that document imports the \c QtQuick namespace. available in a QML document if that document imports the \c QtQuick namespace.
The current version of the \c QtQuick module is version 2.3, and thus it may be The current version of the \c QtQuick module is version 2.4, and thus it may be
imported via the following statement: imported via the following statement:
\qml \qml
import QtQuick 2.3 import QtQuick 2.4
\endqml \endqml
Visit the \l {Qt Quick} module documentation for more Visit the \l {Qt Quick} module documentation for more
......
...@@ -625,8 +625,25 @@ void QQuickAnimatedSprite::prepareNextFrame() ...@@ -625,8 +625,25 @@ void QQuickAnimatedSprite::prepareNextFrame()
qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width(); qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width();
qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height(); qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height();
qreal x1 = m_spriteEngine->spriteX() / m_sheetSize.width() + frameAt * w; qreal x1;
qreal y1 = m_spriteEngine->spriteY() / m_sheetSize.height(); qreal y1;
if (m_paused) {
int spriteY = m_spriteEngine->spriteY();
if (reverse) {
int rows = m_spriteEngine->maxFrames() * m_spriteEngine->spriteWidth() / m_sheetSize.width();
spriteY -= rows * m_spriteEngine->spriteHeight();
frameAt = (frameCount - 1) - frameAt;
}
int position = frameAt * m_spriteEngine->spriteWidth() + m_spriteEngine->spriteX();
int row = position / m_sheetSize.width();
x1 = (position - (row * m_sheetSize.width())) / m_sheetSize.width();
y1 = (row * m_spriteEngine->spriteHeight() + spriteY) / m_sheetSize.height();
} else {
x1 = m_spriteEngine->spriteX() / m_sheetSize.width() + frameAt * w;
y1 = m_spriteEngine->spriteY() / m_sheetSize.height();
}
//### hard-coded 0/1 work because we are the only //### hard-coded 0/1 work because we are the only
// images in the sprite sheet (without this we cannot assume // images in the sprite sheet (without this we cannot assume
......
This diff is collapsed.
...@@ -87,8 +87,6 @@ private Q_SLOTS: ...@@ -87,8 +87,6 @@ private Q_SLOTS:
void sciRequestFinished(); void sciRequestFinished();
private: private:
static QImage shallowCopy(const QImage &image, const QRect &rect);
Q_DISABLE_COPY(QQuickBorderImage) Q_DISABLE_COPY(QQuickBorderImage)
Q_DECLARE_PRIVATE(QQuickBorderImage) Q_DECLARE_PRIVATE(QQuickBorderImage)
}; };
......
...@@ -89,16 +89,6 @@ public: ...@@ -89,16 +89,6 @@ public:
QQuickBorderImage::TileMode verticalTileMode; QQuickBorderImage::TileMode verticalTileMode;
int redirectCount; int redirectCount;
struct BorderImageRegion
{
BorderImageRegion() : node(0), textureFactory(0) {}
QImage image;
QSGImageNode *node;
QScopedPointer<QQuickTextureFactory> textureFactory;
QRectF targetRect;
};
BorderImageRegion regions[9];
bool pixmapChanged : 1; bool pixmapChanged : 1;
}; };
......
...@@ -75,9 +75,6 @@ public: ...@@ -75,9 +75,6 @@ public:
QSize sourcesize; QSize sourcesize;
QSize oldSourceSize; QSize oldSourceSize;
qreal devicePixelRatio; qreal devicePixelRatio;
QRectF oldInnerSourceRect;
QRectF oldInnerTargetRect;
QSizeF oldSize;
bool async : 1; bool async : 1;
bool cache : 1; bool cache : 1;
bool mirror: 1; bool mirror: 1;
......
...@@ -79,6 +79,7 @@ QQuickTextPrivate::QQuickTextPrivate() ...@@ -79,6 +79,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false) , requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false)
, truncated(false), hAlignImplicit(true), rightToLeftText(false) , truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false) , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
, polishSize(false)
{ {
implicitAntialiasing = true; implicitAntialiasing = true;
} }
...@@ -356,6 +357,8 @@ void QQuickTextPrivate::updateLayout() ...@@ -356,6 +357,8 @@ void QQuickTextPrivate::updateLayout()
textHasChanged = true; textHasChanged = true;
updateLayout(); updateLayout();
} }
q->polish();
} }
void QQuickText::imageDownloadFinished() void QQuickText::imageDownloadFinished()
...@@ -2248,13 +2251,22 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data ...@@ -2248,13 +2251,22 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image()); node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image());
} }
} }
// The font caches have now been initialized on the render thread, so they have to be
// invalidated before we can use them from the main thread again.
invalidateFontCaches();
return node; return node;
} }
void QQuickText::updatePolish() void QQuickText::updatePolish()
{ {
Q_D(QQuickText); Q_D(QQuickText);
d->updateSize(); if (d->polishSize) {
d->updateSize();
d->polishSize = false;
}
invalidateFontCaches();
} }
/*! /*!
...@@ -2381,6 +2393,7 @@ void QQuickText::setFontSizeMode(FontSizeMode mode) ...@@ -2381,6 +2393,7 @@ void QQuickText::setFontSizeMode(FontSizeMode mode)
if (d->fontSizeMode() == mode) if (d->fontSizeMode() == mode)
return; return;
d->polishSize = true;
polish(); polish();
d->extra.value().fontSizeMode = mode; d->extra.value().fontSizeMode = mode;
...@@ -2409,8 +2422,10 @@ void QQuickText::setMinimumPixelSize(int size) ...@@ -2409,8 +2422,10 @@ void QQuickText::setMinimumPixelSize(int size)
if (d->minimumPixelSize() == size) if (d->minimumPixelSize() == size)
return; return;
if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
d->polishSize = true;
polish(); polish();
}
d->extra.value().minimumPixelSize = size; d->extra.value().minimumPixelSize = size;
emit minimumPixelSizeChanged(); emit minimumPixelSizeChanged();
} }
...@@ -2437,8 +2452,10 @@ void QQuickText::setMinimumPointSize(int size) ...@@ -2437,8 +2452,10 @@ void QQuickText::setMinimumPointSize(int size)
if (d->minimumPointSize() == size) if (d->minimumPointSize() == size)
return; return;
if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
d->polishSize = true;
polish(); polish();
}
d->extra.value().minimumPointSize = size; d->extra.value().minimumPointSize = size;
emit minimumPointSizeChanged(); emit minimumPointSizeChanged();
} }
...@@ -2699,4 +2716,26 @@ QString QQuickText::linkAt(qreal x, qreal y) const ...@@ -2699,4 +2716,26 @@ QString QQuickText::linkAt(qreal x, qreal y) const
return d->anchorAt(QPointF(x, y)); return d->anchorAt(QPointF(x, y));
} }
/*!
* \internal
*
* Invalidates font caches owned by the text objects owned by the element
* to work around the fact that text objects cannot be used from multiple threads.
*/
void QQuickText::invalidateFontCaches()
{
Q_D(QQuickText);
if (d->richText && d->extra->doc != 0) {
QTextBlock block;
for (block = d->extra->doc->firstBlock(); block.isValid(); block = block.next()) {
if (block.layout() != 0 && block.layout()->engine() != 0)
block.layout()->engine()->resetFontEngineCache();
}
} else {
if (d->layout.engine() != 0)
d->layout.engine()->resetFontEngineCache();
}
}
QT_END_NAMESPACE QT_END_NAMESPACE
...@@ -245,6 +245,7 @@ protected: ...@@ -245,6 +245,7 @@ protected:
void hoverEnterEvent(QHoverEvent *event); void hoverEnterEvent(QHoverEvent *event);
void hoverMoveEvent(QHoverEvent *event); void hoverMoveEvent(QHoverEvent *event);
void hoverLeaveEvent(QHoverEvent *event); void hoverLeaveEvent(QHoverEvent *event);
void invalidateFontCaches();
private Q_SLOTS: private Q_SLOTS:
void q_imagesLoaded(); void q_imagesLoaded();
......
...@@ -151,6 +151,7 @@ public: ...@@ -151,6 +151,7 @@ public:
bool textHasChanged:1; bool textHasChanged:1;
bool needToUpdateLayout:1; bool needToUpdateLayout:1;
bool formatModifiesFontSize:1; bool formatModifiesFontSize:1;
bool polishSize:1; // Workaround for problem with polish called after updateSize (QTBUG-42636)
static const QChar elideChar; static const QChar elideChar;
......
...@@ -1739,6 +1739,7 @@ void QQuickTextEdit::triggerPreprocess() ...@@ -1739,6 +1739,7 @@ void QQuickTextEdit::triggerPreprocess()
Q_D(QQuickTextEdit); Q_D(QQuickTextEdit);
if (d->updateType == QQuickTextEditPrivate::UpdateNone) if (d->updateType == QQuickTextEditPrivate::UpdateNone)
d->updateType = QQuickTextEditPrivate::UpdateOnlyPreprocess; d->updateType = QQuickTextEditPrivate::UpdateOnlyPreprocess;
polish();
update(); update();
} }
...@@ -1758,6 +1759,25 @@ static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topL ...@@ -1758,6 +1759,25 @@ static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topL
node->setMatrix(transformMatrix); node->setMatrix(transformMatrix);
} }
/*!
* \internal
*
* Invalidates font caches owned by the text objects owned by the element
* to work around the fact that text objects cannot be used from multiple threads.
*/
void QQuickTextEdit::invalidateFontCaches()
{
Q_D(QQuickTextEdit);
if (d->document == 0)
return;
QTextBlock block;
for (block = d->document->firstBlock(); block.isValid(); block = block.next()) {
if (block.layout() != 0 && block.layout()->engine() != 0)
block.layout()->engine()->resetFontEngineCache();
}
}
QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
{ {
Q_UNUSED(updatePaintNodeData); Q_UNUSED(updatePaintNodeData);
...@@ -1911,9 +1931,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * ...@@ -1911,9 +1931,16 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
rootNode->resetCursorNode(cursor); rootNode->resetCursorNode(cursor);
} }
invalidateFontCaches();
return rootNode; return rootNode;
} }
void QQuickTextEdit::updatePolish()
{
invalidateFontCaches();
}
/*! /*!
\qmlproperty bool QtQuick::TextEdit::canPaste \qmlproperty bool QtQuick::TextEdit::canPaste
...@@ -2079,6 +2106,7 @@ void QQuickTextEdit::q_contentsChange(int pos, int charsRemoved, int charsAdded) ...@@ -2079,6 +2106,7 @@ void QQuickTextEdit::q_contentsChange(int pos, int charsRemoved, int charsAdded)
markDirtyNodesForRange(pos, editRange, delta); markDirtyNodesForRange(pos, editRange, delta);
polish();
if (isComponentComplete()) { if (isComponentComplete()) {
d->updateType = QQuickTextEditPrivate::UpdatePaintNode; d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
update(); update();
...@@ -2106,6 +2134,7 @@ void QQuickTextEdit::updateSelection() ...@@ -2106,6 +2134,7 @@ void QQuickTextEdit::updateSelection()
// No need for node updates when we go from an empty selection to another empty selection // No need for node updates when we go from an empty selection to another empty selection
if (d->control->textCursor().hasSelection() || d->hadSelection) { if (d->control->textCursor().hasSelection() || d->hadSelection) {
markDirtyNodesForRange(qMin(d->lastSelectionStart, d->control->textCursor().selectionStart()), qMax(d->control->textCursor().selectionEnd(), d->lastSelectionEnd), 0); markDirtyNodesForRange(qMin(d->lastSelectionStart, d->control->textCursor().selectionStart()), qMax(d->control->textCursor().selectionEnd(), d->lastSelectionEnd), 0);
polish();
if (isComponentComplete()) { if (isComponentComplete()) {
d->updateType = QQuickTextEditPrivate::UpdatePaintNode; d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
update(); update();
...@@ -2246,6 +2275,7 @@ void QQuickTextEdit::updateWholeDocument() ...@@ -2246,6 +2275,7 @@ void QQuickTextEdit::updateWholeDocument()
node->setDirty(); node->setDirty();
} }
polish();
if (isComponentComplete()) { if (isComponentComplete()) {
d->updateType = QQuickTextEditPrivate::UpdatePaintNode; d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
update(); update();
...@@ -2260,6 +2290,7 @@ void QQuickTextEdit::invalidateBlock(const QTextBlock &block) ...@@ -2260,6 +2290,7 @@ void QQuickTextEdit::invalidateBlock(const QTextBlock &block)
void QQuickTextEdit::updateCursor() void QQuickTextEdit::updateCursor()
{ {
Q_D(QQuickTextEdit); Q_D(QQuickTextEdit);
polish();
if (isComponentComplete()) { if (isComponentComplete()) {
d->updateType = QQuickTextEditPrivate::UpdatePaintNode; d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
update(); update();
......
...@@ -330,6 +330,7 @@ private Q_SLOTS: ...@@ -330,6 +330,7 @@ private Q_SLOTS:
private: private:
void markDirtyNodesForRange(int start, int end, int charDelta); void markDirtyNodesForRange(int start, int end, int charDelta);
void updateTotalLines(); void updateTotalLines();
void invalidateFontCaches();
protected: protected:
virtual void geometryChanged(const QRectF &newGeometry, virtual void geometryChanged(const QRectF &newGeometry,
...@@ -354,6 +355,7 @@ protected: ...@@ -354,6 +355,7 @@ protected:
void inputMethodEvent(QInputMethodEvent *e); void inputMethodEvent(QInputMethodEvent *e);
#endif #endif
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
void updatePolish();
friend class QQuickTextUtil; friend class QQuickTextUtil;
friend class QQuickTextDocument; friend class QQuickTextDocument;
......
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
#include "qquickaccessibleattached_p.h" #include "qquickaccessibleattached_p.h"
#endif #endif
#include <QtGui/private/qtextengine_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
...@@ -362,6 +364,7 @@ void QQuickTextInput::setColor(const QColor &c) ...@@ -362,6 +364,7 @@ void QQuickTextInput::setColor(const QColor &c)
d->color = c; d->color = c;
d->textLayoutDirty = true; d->textLayoutDirty = true;
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
emit colorChanged(); emit colorChanged();
} }
...@@ -389,6 +392,7 @@ void QQuickTextInput::setSelectionColor(const QColor &color) ...@@ -389,6 +392,7 @@ void QQuickTextInput::setSelectionColor(const QColor &color)
if (d->hasSelectedText()) { if (d->hasSelectedText()) {
d->textLayoutDirty = true; d->textLayoutDirty = true;
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
} }
emit selectionColorChanged(); emit selectionColorChanged();
...@@ -414,6 +418,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color) ...@@ -414,6 +418,7 @@ void QQuickTextInput::setSelectedTextColor(const QColor &color)
if (d->hasSelectedText()) { if (d->hasSelectedText()) {
d->textLayoutDirty = true; d->textLayoutDirty = true;
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
} }
emit selectedTextColorChanged(); emit selectedTextColorChanged();
...@@ -723,6 +728,7 @@ void QQuickTextInput::setCursorVisible(bool on) ...@@ -723,6 +728,7 @@ void QQuickTextInput::setCursorVisible(bool on)
if (!d->cursorItem) { if (!d->cursorItem) {
d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0); d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
} }
emit cursorVisibleChanged(d->cursorVisible); emit cursorVisibleChanged(d->cursorVisible);
...@@ -1830,9 +1836,23 @@ void QQuickTextInput::triggerPreprocess() ...@@ -1830,9 +1836,23 @@ void QQuickTextInput::triggerPreprocess()
Q_D(QQuickTextInput); Q_D(QQuickTextInput);
if (d->updateType == QQuickTextInputPrivate::UpdateNone) if (d->updateType == QQuickTextInputPrivate::UpdateNone)
d->updateType = QQuickTextInputPrivate::UpdateOnlyPreprocess; d->updateType = QQuickTextInputPrivate::UpdateOnlyPreprocess;
polish();
update(); update();
} }
void QQuickTextInput::updatePolish()
{
invalidateFontCaches();
}
void QQuickTextInput::invalidateFontCaches()
{
Q_D(QQuickTextInput);
if (d->m_textLayout.engine() != 0)
d->m_textLayout.engine()->resetFontEngineCache();
}
QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{ {
Q_UNUSED(data); Q_UNUSED(data);
...@@ -1891,6 +1911,8 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData ...@@ -1891,6 +1911,8 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
d->textLayoutDirty = false; d->textLayoutDirty = false;
} }
invalidateFontCaches();
return node; return node;
} }
...@@ -2651,6 +2673,7 @@ void QQuickTextInput::updateCursorRectangle(bool scroll) ...@@ -2651,6 +2673,7 @@ void QQuickTextInput::updateCursorRectangle(bool scroll)
d->updateVerticalScroll(); d->updateVerticalScroll();
} }
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
emit cursorRectangleChanged(); emit cursorRectangleChanged();
if (d->cursorItem) { if (d->cursorItem) {
...@@ -2668,6 +2691,7 @@ void QQuickTextInput::selectionChanged() ...@@ -2668,6 +2691,7 @@ void QQuickTextInput::selectionChanged()
Q_D(QQuickTextInput); Q_D(QQuickTextInput);
d->textLayoutDirty = true; //TODO: Only update rect in selection d->textLayoutDirty = true; //TODO: Only update rect in selection
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
emit selectedTextChanged(); emit selectedTextChanged();
...@@ -2879,6 +2903,7 @@ void QQuickTextInputPrivate::updateLayout() ...@@ -2879,6 +2903,7 @@ void QQuickTextInputPrivate::updateLayout()
contentSize = QSizeF(width, height); contentSize = QSizeF(width, height);
updateType = UpdatePaintNode; updateType = UpdatePaintNode;
q->polish();
q->update(); q->update();
if (!requireImplicitWidth && !q->widthValid()) if (!requireImplicitWidth && !q->widthValid())
...@@ -4167,6 +4192,7 @@ void QQuickTextInputPrivate::setCursorBlinkPeriod(int msec) ...@@ -4167,6 +4192,7 @@ void QQuickTextInputPrivate::setCursorBlinkPeriod(int msec)
m_blinkTimer = 0; m_blinkTimer = 0;
if (m_blinkStatus == 1) { if (m_blinkStatus == 1) {
updateType = UpdatePaintNode; updateType = UpdatePaintNode;
q->polish();
q->update(); q->update();
} }
} }
...@@ -4179,6 +4205,7 @@ void QQuickTextInput::timerEvent(QTimerEvent *event) ...@@ -4179,6 +4205,7 @@ void QQuickTextInput::timerEvent(QTimerEvent *event)
if (event->timerId() == d->m_blinkTimer) { if (event->timerId() == d->m_blinkTimer) {
d->m_blinkStatus = !d->m_blinkStatus; d->m_blinkStatus = !d->m_blinkStatus;
d->updateType = QQuickTextInputPrivate::UpdatePaintNode; d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
polish();
update(); update();
} else if (event->timerId() == d->m_passwordEchoTimer.timerId()) { } else if (event->timerId() == d->m_passwordEchoTimer.timerId()) {
d->m_passwordEchoTimer.stop(); d->m_passwordEchoTimer.stop();
......
...@@ -314,6 +314,9 @@ Q_SIGNALS: ...@@ -314,6 +314,9 @@ Q_SIGNALS:
#endif #endif
void renderTypeChanged(); void renderTypeChanged();
private:
void invalidateFontCaches();
protected: protected:
virtual void geometryChanged(const QRectF &newGeometry, virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry); const QRectF &oldGeometry);
...@@ -332,6 +335,7 @@ protected: ...@@ -332,6 +335,7 @@ protected:
void focusInEvent(QFocusEvent *event); void focusInEvent(QFocusEvent *event);
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data); QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
void updatePolish();
public Q_SLOTS: public Q_SLOTS:
void selectAll(); void selectAll();
......
...@@ -1796,7 +1796,9 @@ void QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event) ...@@ -1796,7 +1796,9 @@ void QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event)
if (!delayedTouch) { if (!delayedTouch) {
delayedTouch = new QTouchEvent(event->type(), event->device(), event->modifiers(), event->touchPointStates(), event->touchPoints()); delayedTouch = new QTouchEvent(event->type(), event->device(), event->modifiers(), event->touchPointStates(), event->touchPoints());
delayedTouch->setTimestamp(event->timestamp()); delayedTouch->setTimestamp(event->timestamp());
if (windowManager) if (renderControl)
QQuickRenderControlPrivate::get(renderControl)->maybeUpdate();
else if (windowManager)
windowManager->maybeUpdate(q); windowManager->maybeUpdate(q);
return; return;
} else { } else {
......
...@@ -126,17 +126,6 @@ public: ...@@ -126,17 +126,6 @@ public:
class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGVisitableNode class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGVisitableNode
{ {
public: public:
enum AntialiasingFlag
{
AntialiasingNone = 0,
AntialiasingLeft = 1,
AntialiasingRight = 2,
AntialiasingTop = 4,
AntialiasingBottom = 8,
AntialiasingAll = AntialiasingLeft | AntialiasingRight | AntialiasingBottom | AntialiasingTop
};
Q_DECLARE_FLAGS(AntialiasingFlags, AntialiasingFlag)
virtual void setTargetRect(const QRectF &rect) = 0; virtual void setTargetRect(const QRectF &rect) = 0;
virtual void setInnerTargetRect(const QRectF &rect) = 0; virtual void setInnerTargetRect(const QRectF &rect) = 0;
virtual void setInnerSourceRect(const QRectF &rect) = 0; virtual void setInnerSourceRect(const QRectF &rect) = 0;
...@@ -151,7 +140,6 @@ public: ...@@ -151,7 +140,6 @@ public:
virtual void setFiltering(QSGTexture::Filtering filtering) = 0; virtual void setFiltering(QSGTexture::Filtering filtering) = 0;
virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0; virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0; virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
virtual void setAntialiasing(AntialiasingFlags flags) { Q_UNUSED(flags); }
virtual void update() = 0; virtual void update() = 0;
......
...@@ -140,11 +140,10 @@ void SmoothTextureMaterialShader::initialize() ...@@ -140,11 +140,10 @@ void SmoothTextureMaterialShader::initialize()
QSGDefaultImageNode::QSGDefaultImageNode() QSGDefaultImageNode::QSGDefaultImageNode()
: m_innerSourceRect(0, 0, 1, 1) : m_innerSourceRect(0, 0, 1, 1)
, m_subSourceRect(0, 0, 1, 1) , m_subSourceRect(0, 0, 1, 1)
, m_antialiasing(false)
, m_mirror(false) , m_mirror(false)
, m_dirtyGeometry(false) , m_dirtyGeometry(false)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
, m_antialiasing(AntialiasingNone)
{ {
setMaterial(&m_materialO); setMaterial(&m_materialO);
setOpaqueMaterial(&m_material); setOpaqueMaterial(&m_material);
...@@ -250,20 +249,10 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture) ...@@ -250,20 +249,10 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture)
void QSGDefaultImageNode::setAntialiasing(bool antialiasing) void QSGDefaultImageNode::setAntialiasing(bool antialiasing)
{ {
AntialiasingFlags antialiasingFlags = antialiasing if (antialiasing == m_antialiasing)
? AntialiasingAll
: AntialiasingNone;
setAntialiasing(antialiasingFlags);
}
void QSGDefaultImageNode::setAntialiasing(AntialiasingFlags antialiasingFlags)
{
if (antialiasingFlags == m_antialiasing)
return; return;
m_antialiasing = antialiasing;
m_antialiasing = antialiasingFlags; if (m_antialiasing) {
if (m_antialiasing != AntialiasingNone) {
setMaterial(&m_smoothMaterial); setMaterial(&m_smoothMaterial);
setOpaqueMaterial(0); setOpaqueMaterial(0);
setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); setGeometry(new QSGGeometry(smoothAttributeSet(), 0));
...@@ -375,14 +364,11 @@ void QSGDefaultImageNode::updateGeometry() ...@@ -375,14 +364,11 @@ void QSGDefaultImageNode::updateGeometry()
} }
// An image can be rendered as a single quad if: // An image can be rendered as a single quad if:
// - There is antialiasing on all or no edges
// - There are no margins, and either: // - There are no margins, and either:
// - the image isn't repeated // - the image isn't repeated
// - the source rectangle fills the entire texture so that texture wrapping can be used, // - the source rectangle fills the entire texture so that texture wrapping can be used,
// and NPOT is supported // and NPOT is supported
if (!hasMargins if (!hasMargins && (!hasTiles || (fullTexture && wrapSupported))) {
&& (m_antialiasing == AntialiasingAll || m_antialiasing == AntialiasingNone)
&& (!hasTiles || (fullTexture && wrapSupported))) {
QRectF sr; QRectF sr;
if (!fullTexture) { if (!fullTexture) {
sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(), sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(),
...@@ -561,35 +547,10 @@ void QSGDefaultImageNode::updateGeometry() ...@@ -561,35 +547,10 @@ void QSGDefaultImageNode::updateGeometry()
topDv = bottomDv *= 0.5f; topDv = bottomDv *= 0.5f;
} }
if (!m_antialiasing.testFlag(AntialiasingTop)) {
topDy = 0.0f;
topDv = 0.0f;
}
if (!m_antialiasing.testFlag(AntialiasingBottom)) {
bottomDy = 0.0f;
bottomDv = 0.0f;
}
if (!m_antialiasing.testFlag(AntialiasingLeft)) {
leftDx = 0.0f;
leftDu = 0.0f;
}
if (!m_antialiasing.testFlag(AntialiasingRight)) {
rightDx = 0.0f;
rightDu = 0.0f;
}
// This delta is how much the fuzziness can reach out from the image. // This delta is how much the fuzziness can reach out from the image.
float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height())
? m_targetRect.width() : m_targetRect.height()) * 0.5f; ? m_targetRect.width() : m_targetRect.height()) * 0.5f;
float deltaTop = m_antialiasing.testFlag(AntialiasingTop) ? delta : 0.0f;
float deltaBottom = m_antialiasing.testFlag(AntialiasingBottom) ? delta : 0.0f;
float deltaLeft = m_antialiasing.testFlag(AntialiasingLeft) ? delta : 0.0f;
float deltaRight = m_antialiasing.testFlag(AntialiasingRight) ? delta : 0.0f;
quint16 index = 0; quint16 index = 0;
ys = yData.data(); ys = yData.data();
for (int j = 0; j < vCells; ++j, ys += 2) { for (int j = 0; j < vCells; ++j, ys += 2) {
...@@ -639,28 +600,28 @@ void QSGDefaultImageNode::updateGeometry() ...@@ -639,28 +600,28 @@ void QSGDefaultImageNode::updateGeometry()
if (isTop) { if (isTop) {
vertices[topLeft].dy = vertices[topRight].dy = topDy; vertices[topLeft].dy = vertices[topRight].dy = topDy;
vertices[topLeft].dv = vertices[topRight].dv = topDv; vertices[topLeft].dv = vertices[topRight].dv = topDv;
vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -deltaTop; vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta;
appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight); appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight);
} }
if (isBottom) { if (isBottom) {
vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy; vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy;
vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv; vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv;
vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = deltaBottom; vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta;
appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1); appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1);
} }
if (isLeft) { if (isLeft) {
vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx; vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx;
vertices[topLeft].du = vertices[bottomLeft].du = leftDu; vertices[topLeft].du = vertices[bottomLeft].du = leftDu;
vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -deltaLeft; vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta;
appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft); appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft);
} }
if (isRight) { if (isRight) {
vertices[topRight].dx = vertices[bottomRight].dx = -rightDx; vertices[topRight].dx = vertices[bottomRight].dx = -rightDx;
vertices[topRight].du = vertices[bottomRight].du = -rightDu; vertices[topRight].du = vertices[bottomRight].du = -rightDu;
vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = deltaRight; vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta;
appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1); appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1);
} }
} }
......
...@@ -62,7 +62,6 @@ public: ...@@ -62,7 +62,6 @@ public:
virtual void setSubSourceRect(const QRectF &rect); virtual void setSubSourceRect(const QRectF &rect);
virtual void setTexture(QSGTexture *t); virtual void setTexture(QSGTexture *t);
virtual void setAntialiasing(bool antialiasing); virtual void setAntialiasing(bool antialiasing);
virtual void setAntialiasing(AntialiasingFlags antialiasing);
virtual void setMirror(bool mirror); virtual void setMirror(bool mirror);
virtual void update(); virtual void update();
...@@ -85,11 +84,11 @@ private: ...@@ -85,11 +84,11 @@ private:
QSGTextureMaterial m_materialO; QSGTextureMaterial m_materialO;
QSGSmoothTextureMaterial m_smoothMaterial; QSGSmoothTextureMaterial m_smoothMaterial;
uint m_antialiasing : 1;
uint m_mirror : 1; uint m_mirror : 1;
uint m_dirtyGeometry : 1; uint m_dirtyGeometry : 1;
QSGGeometry m_geometry; QSGGeometry m_geometry;
AntialiasingFlags m_antialiasing;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <QtGui/QScreen> #include <QtGui/QScreen>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/QOffscreenSurface>
#include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qquickwindow_p.h> #include <QtQuick/private/qquickwindow_p.h>
...@@ -210,15 +211,29 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) ...@@ -210,15 +211,29 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
hide(window); hide(window);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
if (m_gl) bool current = false;
m_gl->makeCurrent(window); QScopedPointer<QOffscreenSurface> offscreenSurface;
if (m_gl) {
QSurface *surface = window;
// There may be no platform window if the window got closed.
if (!window->handle()) {
offscreenSurface.reset(new QOffscreenSurface);
offscreenSurface->setFormat(m_gl->format());
offscreenSurface->create();
surface = offscreenSurface.data();
}
current = m_gl->makeCurrent(surface);
}
if (Q_UNLIKELY(!current))
qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
d->cleanupNodesOnShutdown(); d->cleanupNodesOnShutdown();
if (m_windows.size() == 0) { if (m_windows.size() == 0) {
d->context->invalidate(); d->context->invalidate();
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete m_gl; delete m_gl;
m_gl = 0; m_gl = 0;
} else if (m_gl) { } else if (m_gl && current) {
m_gl->doneCurrent(); m_gl->doneCurrent();
} }
} }
......