summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-10-23 14:01:35 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-10-23 14:45:03 +0200
commit790aef362fd195adf97d8c780a7cbbbade27d51f (patch)
tree8be464687ab21806cfe9f7ada27098b563aa41b2 /src/gui
parent9720efbd1035c2e939b0581163e6d804c713dd96 (diff)
parent07475c662eb73c833da2d461b8ef2702ca1e2cfb (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: .qmake.conf configure src/corelib/global/qglobal.h src/tools/qdoc/node.cpp src/tools/qdoc/qdocdatabase.cpp tests/auto/corelib/io/qsettings/tst_qsettings.cpp tools/configure/configureapp.cpp Change-Id: I66028ae5e441a06b73ee85ba72a03a3af3e8593f
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/image/qicon.cpp51
-rw-r--r--src/gui/image/qicon.h2
-rw-r--r--src/gui/image/qpixmap_win.cpp28
-rw-r--r--src/gui/image/qpixmapcache.cpp3
-rw-r--r--src/gui/kernel/qguiapplication.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.cpp3
-rw-r--r--src/gui/kernel/qplatformwindow.h2
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp13
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h2
-rw-r--r--src/gui/kernel/qshortcutmap.cpp4
-rw-r--r--src/gui/kernel/qsimpledrag.cpp3
-rw-r--r--src/gui/kernel/qsimpledrag_p.h4
-rw-r--r--src/gui/kernel/qwindow.cpp60
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp2
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp257
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h4
-rw-r--r--src/gui/painting/qcolor.cpp4
-rw-r--r--src/gui/painting/qdrawhelper.cpp15
-rw-r--r--src/gui/painting/qpdf.cpp6
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp29
-rw-r--r--src/gui/text/qtextimagehandler.cpp16
-rw-r--r--src/gui/util/qdesktopservices.cpp4
23 files changed, 327 insertions, 189 deletions
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 436e2e0b34..e34347b801 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -4,7 +4,7 @@ project = QtGui
description = Qt GUI Reference Documentation
version = $QT_VERSION
-examplesinstallpath = gui
+examplesinstallpath = qtbase/gui
qhp.projects = QtGui
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 7ae081adfb..cebe5ce5f9 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -45,6 +45,7 @@
#include "qcache.h"
#include "qdebug.h"
#include "qpalette.h"
+#include "qmath.h"
#include "private/qhexstring_p.h"
#include "private/qguiapplication_p.h"
@@ -1029,19 +1030,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
d->engine = new QPixmapIconEngine;
}
}
+
d->engine->addFile(fileName, size, mode, state);
- // Check if a "@2x" file exists and add it.
- static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
- if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) {
- QString at2xfileName = fileName;
- int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex == -1) /* no dot */
- dotIndex = fileName.size(); /* append */
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName))
- d->engine->addFile(at2xfileName, size, mode, state);
- }
+ // Check if a "@Nx" file exists and add it.
+ QString atNxFileName = qt_findAtNxFile(fileName, qApp->devicePixelRatio());
+ if (atNxFileName != fileName)
+ d->engine->addFile(atNxFileName, size, mode, state);
}
/*!
@@ -1395,5 +1390,39 @@ QDebug operator<<(QDebug dbg, const QIcon &i)
\internal
*/
+/*!
+ \internal
+ \since 5.6
+ Attempts to find a suitable @Nx file for the given \a targetDevicePixelRatio
+ Returns the the \a baseFileName if no such file was found.
+
+ Given base foo.png and a target dpr of 2.5, this function will look for
+ foo@3x.png, then foo@2x, then fall back to foo.png if not found.
+*/
+QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio)
+{
+ if (targetDevicePixelRatio <= 1.0)
+ return baseFileName;
+
+ static bool disableNxImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING");
+ if (disableNxImageLoading)
+ return baseFileName;
+
+ QString atNx = QLatin1String("@%1x");
+ int dotIndex = baseFileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex == -1) /* no dot */
+ dotIndex = baseFileName.size(); /* append */
+
+ // Check for @Nx, ..., @3x, @2x file versions,
+ for (int n = qCeil(targetDevicePixelRatio); n > 1; --n) {
+ QString atNxfileName = baseFileName;
+ atNxfileName.insert(dotIndex, atNx.arg(n));
+ if (QFile::exists(atNxfileName))
+ return atNxfileName;
+ }
+
+ return baseFileName;
+}
+
QT_END_NAMESPACE
#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 329ae3deb3..6808bc2828 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -140,6 +140,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QIcon &);
#endif
+Q_GUI_EXPORT QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio);
+
QT_END_NAMESPACE
#endif // QICON_H
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 12e19440dc..a7a9b375ff 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -345,9 +345,22 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
return image;
}
+static inline bool hasAlpha(const QImage &image)
+{
+ const int w = image.width();
+ const int h = image.height();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *scanLine = reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(scanLine[x]) != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
{
- bool foundAlpha = false;
HDC screenDevice = GetDC(0);
HDC hdc = CreateCompatibleDC(screenDevice);
ReleaseDC(0, screenDevice);
@@ -356,6 +369,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
if (!result) {
qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ DeleteDC(hdc);
return QPixmap();
}
@@ -371,17 +385,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
- for (int y = 0 ; y < h && !foundAlpha ; y++) {
- const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
- for (int x = 0; x < w ; x++) {
- if (qAlpha(scanLine[x]) != 0) {
- foundAlpha = true;
- break;
- }
- }
- }
- if (!foundAlpha) {
- //If no alpha was found, we use the mask to set alpha values
+ if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 2df813367d..6265a0c16d 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -652,7 +652,8 @@ void QPixmapCache::remove(const Key &key)
void QPixmapCache::clear()
{
QT_TRY {
- pm_cache()->clear();
+ if (pm_cache.exists())
+ pm_cache->clear();
} QT_CATCH(const std::bad_alloc &) {
// if we ran out of memory during pm_cache(), it's no leak,
// so just ignore it.
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index b717585b54..35e880fc5b 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -902,7 +902,7 @@ QWindowList QGuiApplication::topLevelWindows()
if (!list.at(i)->parent() && list.at(i)->type() != Qt::Desktop) {
// Top windows of embedded QAxServers do not have QWindow parents,
// but they are not true top level windows, so do not include them.
- const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded(0);
+ const bool embedded = list.at(i)->handle() && list.at(i)->handle()->isEmbedded();
if (!embedded)
topLevelWindows.prepend(list.at(i));
}
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 457a420148..14633d8b30 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -208,8 +208,7 @@ QPlatformServices *QPlatformIntegration::services() const
behavior for desktop platforms.
\value ForeignWindows The platform allows creating QWindows which represent
- native windows created by other processes or anyway created by using native
- libraries.
+ native windows created by other processes or by using native libraries.
\value NonFullScreenWindows The platform supports top-level windows which do not
fill the screen. The default implementation returns \c true. Returning false for
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 9c2817906f..850e2b4bfe 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -95,7 +95,7 @@ public:
virtual bool isExposed() const;
virtual bool isActive() const;
- virtual bool isEmbedded(const QPlatformWindow *parentWindow) const;
+ virtual bool isEmbedded(const QPlatformWindow *parentWindow = 0) const;
virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const;
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 5736c41e25..d77b6dc262 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -35,12 +35,16 @@
#include <QtGui/QPainter>
#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPalette>
+#include <QtGui/QBitmap>
QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
: QWindow(screen),
- m_backingStore(0)
+ m_backingStore(0),
+ m_useCompositing(true)
{
QSurfaceFormat format;
format.setAlphaBufferSize(8);
@@ -68,7 +72,10 @@ void QShapedPixmapWindow::render()
{
QPainter p(device);
- p.setCompositionMode(QPainter::CompositionMode_Source);
+ if (m_useCompositing)
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ else
+ p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
@@ -79,6 +86,8 @@ void QShapedPixmapWindow::render()
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
+ if (!m_useCompositing)
+ setMask(m_pixmap.mask());
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index 7536c09165..3d7974fa82 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -60,6 +60,7 @@ public:
void render();
+ void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@@ -72,6 +73,7 @@ private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
+ bool m_useCompositing;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 3b2e6ffd29..9c8218b7b5 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -84,7 +84,7 @@ struct QShortcutEntry
QShortcutMap::ContextMatcher contextMatcher;
};
-#if 0 //ndef QT_NO_DEBUG_STREAM
+#ifdef Dump_QShortcutMap
/*! \internal
QDebug operator<< for easy debug output of the shortcut entries.
*/
@@ -99,7 +99,7 @@ static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)
<< "), owner(" << se->owner << ')';
return dbg;
}
-#endif // QT_NO_DEBUGSTREAM
+#endif // Dump_QShortcutMap
/* \internal
Private data for QShortcutMap
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index d2efeaca28..706786385b 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -88,7 +88,7 @@ static QWindow* topLevelAt(const QPoint &pos)
QBasicDrag::QBasicDrag() :
m_restoreCursor(false), m_eventLoop(0),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0)
+ m_drag(0), m_drag_icon_window(0), m_useCompositing(true)
{
}
@@ -234,6 +234,7 @@ void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos)
// when QDrag is used without a pixmap - QDrag::setPixmap()
m_drag_icon_window = new QShapedPixmapWindow(screen);
+ m_drag_icon_window->setUseCompositing(m_useCompositing);
m_drag_icon_window->setPixmap(m_drag->pixmap());
m_drag_icon_window->setHotspot(m_drag->hotSpot());
m_drag_icon_window->updateGeometry(pos);
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 34679a7540..d5dacd8fd2 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -88,6 +88,9 @@ protected:
bool canDrop() const { return m_can_drop; }
void setCanDrop(bool c) { m_can_drop = c; }
+ bool useCompositing() const { return m_useCompositing; }
+ void setUseCompositing(bool on) { m_useCompositing = on; }
+
Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
@@ -105,6 +108,7 @@ private:
bool m_can_drop;
QDrag *m_drag;
QShapedPixmapWindow *m_drag_icon_window;
+ bool m_useCompositing;
};
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index d4edc0fca1..e262f3f8a4 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -389,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
void QWindowPrivate::create(bool recursive)
{
Q_Q(QWindow);
+ if (platformWindow)
+ return;
+
+ platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
+ Q_ASSERT(platformWindow);
+
if (!platformWindow) {
- platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- QObjectList childObjects = q->children();
- for (int i = 0; i < childObjects.size(); i ++) {
- QObject *object = childObjects.at(i);
- if (object->isWindowType()) {
- QWindow *window = static_cast<QWindow *>(object);
- if (recursive)
- window->d_func()->create(true);
- if (window->d_func()->platformWindow)
- window->d_func()->platformWindow->setParent(platformWindow);
- }
- }
+ qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
+ return;
+ }
- if (platformWindow) {
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
- QGuiApplication::sendEvent(q, &e);
+ QObjectList childObjects = q->children();
+ for (int i = 0; i < childObjects.size(); i ++) {
+ QObject *object = childObjects.at(i);
+ if (object->isWindowType()) {
+ QWindow *window = static_cast<QWindow *>(object);
+ if (recursive)
+ window->d_func()->create(true);
+ if (window->d_func()->platformWindow)
+ window->d_func()->platformWindow->setParent(platformWindow);
}
}
+
+ QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
+ QGuiApplication::sendEvent(q, &e);
}
void QWindowPrivate::clearFocusObject()
@@ -588,8 +594,7 @@ QWindow *QWindow::parent() const
Setting \a parent to be 0 will make the window become a top level window.
If \a parent is a window created by fromWinId(), then the current window
- will be embedded inside \a parent, if the platform supports it. Window
- embedding is currently supported only by the X11 platform plugin.
+ will be embedded inside \a parent, if the platform supports it.
*/
void QWindow::setParent(QWindow *parent)
{
@@ -2292,10 +2297,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapToGlobal(pos);
}
- return pos + d_func()->globalPosition();
+ return pos + d->globalPosition();
}
@@ -2312,10 +2317,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
- && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) {
+ && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) {
return d->platformWindow->mapFromGlobal(pos);
}
- return pos - d_func()->globalPosition();
+ return pos - d->globalPosition();
}
@@ -2377,9 +2382,16 @@ QWindow *QWindowPrivate::topLevelWindow() const
Given the handle \a id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods like
setParent() and setTransientParent().
- This can be used, on platforms which support it, to embed a window inside a
- container or to make a window stick on top of a window created by another
- process.
+
+ This can be used, on platforms which support it, to embed a QWindow inside a
+ native window, or to embed a native window inside a QWindow.
+
+ If foreign windows are not supported, this function returns 0.
+
+ \note The resulting QWindow should not be used to manipulate the underlying
+ native window (besides re-parenting), or to observe state changes of the
+ native window. Any support for these kind of operations is incidental, highly
+ platform dependent and untested.
\sa setParent()
\sa setTransientParent()
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index a9a4adaddc..4836dde343 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -2076,7 +2076,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->device->ensureActiveTarget();
- if (d->device->context() != QOpenGLContext::currentContext()) {
+ if (d->device->context() != QOpenGLContext::currentContext() || !d->device->context()) {
qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");
return false;
}
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index 0f9fa6400d..1c6a7937e5 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -39,6 +39,10 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
QT_BEGIN_NAMESPACE
static const char vertex_shader150[] =
@@ -88,6 +92,18 @@ static const char fragment_shader[] =
" gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
"}";
+static const char fragment_shader_external_oes[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "varying highp vec2 uv;"
+ "uniform samplerExternalOES textureSampler;\n"
+ "uniform bool swizzle;"
+ "uniform highp float opacity;"
+ "void main() {"
+ " highp vec4 tmpFragColor = texture2D(textureSampler, uv);"
+ " tmpFragColor.a *= opacity;"
+ " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
+ "}";
+
static const GLfloat vertex_buffer_data[] = {
-1,-1, 0,
-1, 1, 0,
@@ -109,14 +125,17 @@ static const GLfloat texture_buffer_data[] = {
class TextureBinder
{
public:
- TextureBinder(GLuint textureId)
+ TextureBinder(GLenum target, GLuint textureId) : m_target(target)
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, textureId);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId);
}
~TextureBinder()
{
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0);
}
+
+private:
+ GLenum m_target;
};
class QOpenGLTextureBlitterPrivate
@@ -128,74 +147,106 @@ public:
IdentityFlipped
};
- QOpenGLTextureBlitterPrivate()
- : program(0)
- , vertexCoordAttribPos(0)
- , vertexTransformUniformPos(0)
- , textureCoordAttribPos(0)
- , textureTransformUniformPos(0)
- , swizzle(false)
- , swizzleOld(false)
- , opacity(1.0f)
- , opacityOld(0.0f)
- , textureMatrixUniformState(User)
- , vao(new QOpenGLVertexArrayObject())
+ enum ProgramIndex {
+ TEXTURE_2D,
+ TEXTURE_EXTERNAL_OES
+ };
+
+ QOpenGLTextureBlitterPrivate() :
+ swizzle(false),
+ opacity(1.0f),
+ vao(new QOpenGLVertexArrayObject),
+ currentTarget(TEXTURE_2D)
{ }
+ bool buildProgram(ProgramIndex idx, const char *vs, const char *fs);
+
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);
void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);
- void prepareProgram(const QMatrix4x4 &vertexTransform)
- {
- vertexBuffer.bind();
- program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- program->enableAttributeArray(vertexCoordAttribPos);
- vertexBuffer.release();
-
- program->setUniformValue(vertexTransformUniformPos, vertexTransform);
-
- textureBuffer.bind();
- program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- program->enableAttributeArray(textureCoordAttribPos);
- textureBuffer.release();
-
- if (swizzle != swizzleOld) {
- program->setUniformValue(swizzleUniformPos, swizzle);
- swizzleOld = swizzle;
- }
-
- if (opacity != opacityOld) {
- program->setUniformValue(opacityUniformPos, opacity);
- opacityOld = opacity;
- }
- }
+ void prepareProgram(const QMatrix4x4 &vertexTransform);
QOpenGLBuffer vertexBuffer;
QOpenGLBuffer textureBuffer;
- QScopedPointer<QOpenGLShaderProgram> program;
- GLuint vertexCoordAttribPos;
- GLuint vertexTransformUniformPos;
- GLuint textureCoordAttribPos;
- GLuint textureTransformUniformPos;
- GLuint swizzleUniformPos;
- GLuint opacityUniformPos;
+ struct Program {
+ Program() :
+ vertexCoordAttribPos(0),
+ vertexTransformUniformPos(0),
+ textureCoordAttribPos(0),
+ textureTransformUniformPos(0),
+ swizzleUniformPos(0),
+ opacityUniformPos(0),
+ swizzle(false),
+ opacity(0.0f),
+ textureMatrixUniformState(User)
+ { }
+ QScopedPointer<QOpenGLShaderProgram> glProgram;
+ GLuint vertexCoordAttribPos;
+ GLuint vertexTransformUniformPos;
+ GLuint textureCoordAttribPos;
+ GLuint textureTransformUniformPos;
+ GLuint swizzleUniformPos;
+ GLuint opacityUniformPos;
+ bool swizzle;
+ float opacity;
+ TextureMatrixUniform textureMatrixUniformState;
+ } programs[2];
bool swizzle;
- bool swizzleOld;
float opacity;
- float opacityOld;
- TextureMatrixUniform textureMatrixUniformState;
QScopedPointer<QOpenGLVertexArrayObject> vao;
+ GLenum currentTarget;
};
+static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
+ default:
+ qWarning("Unsupported texture target 0x%x", target);
+ return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
+ }
+}
+
+void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform)
+{
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+
+ vertexBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ program->glProgram->enableAttributeArray(program->vertexCoordAttribPos);
+ vertexBuffer.release();
+
+ program->glProgram->setUniformValue(program->vertexTransformUniformPos, vertexTransform);
+
+ textureBuffer.bind();
+ program->glProgram->setAttributeBuffer(program->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ program->glProgram->enableAttributeArray(program->textureCoordAttribPos);
+ textureBuffer.release();
+
+ if (swizzle != program->swizzle) {
+ program->glProgram->setUniformValue(program->swizzleUniformPos, swizzle);
+ program->swizzle = swizzle;
+ }
+
+ if (opacity != program->opacity) {
+ program->glProgram->setUniformValue(program->opacityUniformPos, opacity);
+ program->opacity = opacity;
+ }
+}
+
void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
const QMatrix3x3 &textureTransform)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
- program->setUniformValue(textureTransformUniformPos, textureTransform);
- textureMatrixUniformState = User;
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, textureTransform);
+ program->textureMatrixUniformState = User;
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
@@ -204,25 +255,54 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
const QMatrix4x4 &vertexTransform,
QOpenGLTextureBlitter::Origin origin)
{
- TextureBinder binder(texture);
+ TextureBinder binder(currentTarget, texture);
prepareProgram(vertexTransform);
+ Program *program = &programs[targetToProgramIndex(currentTarget)];
if (origin == QOpenGLTextureBlitter::OriginTopLeft) {
- if (textureMatrixUniformState != IdentityFlipped) {
+ if (program->textureMatrixUniformState != IdentityFlipped) {
QMatrix3x3 flipped;
flipped(1,1) = -1;
flipped(1,2) = 1;
- program->setUniformValue(textureTransformUniformPos, flipped);
- textureMatrixUniformState = IdentityFlipped;
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, flipped);
+ program->textureMatrixUniformState = IdentityFlipped;
}
- } else if (textureMatrixUniformState != Identity) {
- program->setUniformValue(textureTransformUniformPos, QMatrix3x3());
- textureMatrixUniformState = Identity;
+ } else if (program->textureMatrixUniformState != Identity) {
+ program->glProgram->setUniformValue(program->textureTransformUniformPos, QMatrix3x3());
+ program->textureMatrixUniformState = Identity;
}
QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
}
+bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs, const char *fs)
+{
+ Program *p = &programs[idx];
+
+ p->glProgram.reset(new QOpenGLShaderProgram);
+
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs);
+ p->glProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs);
+ p->glProgram->link();
+ if (!p->glProgram->isLinked()) {
+ qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << p->glProgram->log();
+ return false;
+ }
+
+ p->glProgram->bind();
+
+ p->vertexCoordAttribPos = p->glProgram->attributeLocation("vertexCoord");
+ p->vertexTransformUniformPos = p->glProgram->uniformLocation("vertexTransform");
+ p->textureCoordAttribPos = p->glProgram->attributeLocation("textureCoord");
+ p->textureTransformUniformPos = p->glProgram->uniformLocation("textureTransform");
+ p->swizzleUniformPos = p->glProgram->uniformLocation("swizzle");
+ p->opacityUniformPos = p->glProgram->uniformLocation("opacity");
+
+ p->glProgram->setUniformValue(p->swizzleUniformPos, false);
+
+ return true;
+}
+
QOpenGLTextureBlitter::QOpenGLTextureBlitter()
: d_ptr(new QOpenGLTextureBlitterPrivate)
{
@@ -241,28 +321,21 @@ bool QOpenGLTextureBlitter::create()
Q_D(QOpenGLTextureBlitter);
- if (d->program)
+ if (d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram)
return true;
- d->program.reset(new QOpenGLShaderProgram());
-
QSurfaceFormat format = currentContext->format();
-
if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150);
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150))
+ return false;
} else {
- d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
- d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
- }
- d->program->link();
- if (!d->program->isLinked()) {
- qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log();
- return false;
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader))
+ return false;
+ if (supportsExternalOESTarget())
+ if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes))
+ return false;
}
- d->program->bind();
-
// Create and bind the VAO, if supported.
QOpenGLVertexArrayObject::Binder vaoBinder(d->vao.data());
@@ -276,22 +349,13 @@ bool QOpenGLTextureBlitter::create()
d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data));
d->textureBuffer.release();
- d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord");
- d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform");
- d->textureCoordAttribPos = d->program->attributeLocation("textureCoord");
- d->textureTransformUniformPos = d->program->uniformLocation("textureTransform");
- d->swizzleUniformPos = d->program->uniformLocation("swizzle");
- d->opacityUniformPos = d->program->uniformLocation("opacity");
-
- d->program->setUniformValue(d->swizzleUniformPos,false);
-
return true;
}
bool QOpenGLTextureBlitter::isCreated() const
{
Q_D(const QOpenGLTextureBlitter);
- return d->program;
+ return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
}
void QOpenGLTextureBlitter::destroy()
@@ -299,36 +363,45 @@ void QOpenGLTextureBlitter::destroy()
if (!isCreated())
return;
Q_D(QOpenGLTextureBlitter);
- d->program.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram.reset();
+ d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES].glProgram.reset();
d->vertexBuffer.destroy();
d->textureBuffer.destroy();
d->vao.reset();
}
-void QOpenGLTextureBlitter::bind()
+bool QOpenGLTextureBlitter::supportsExternalOESTarget() const
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
+}
+
+void QOpenGLTextureBlitter::bind(GLenum target)
{
Q_D(QOpenGLTextureBlitter);
if (d->vao->isCreated())
d->vao->bind();
- d->program->bind();
+ d->currentTarget = target;
+ QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)];
+ p->glProgram->bind();
d->vertexBuffer.bind();
- d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
- d->program->enableAttributeArray(d->vertexCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ p->glProgram->enableAttributeArray(p->vertexCoordAttribPos);
d->vertexBuffer.release();
d->textureBuffer.bind();
- d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
- d->program->enableAttributeArray(d->textureCoordAttribPos);
+ p->glProgram->setAttributeBuffer(p->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ p->glProgram->enableAttributeArray(p->textureCoordAttribPos);
d->textureBuffer.release();
}
void QOpenGLTextureBlitter::release()
{
Q_D(QOpenGLTextureBlitter);
- d->program->release();
+ d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release();
if (d->vao->isCreated())
d->vao->release();
}
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
index 8f7eae1c32..ebf3a4bfbb 100644
--- a/src/gui/opengl/qopengltextureblitter_p.h
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -68,7 +68,9 @@ public:
bool isCreated() const;
void destroy();
- void bind();
+ bool supportsExternalOESTarget() const;
+
+ void bind(GLenum target = GL_TEXTURE_2D);
void release();
void setSwizzleRB(bool swizzle);
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 1012ed7c6d..3f30c061dc 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2075,7 +2075,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a)
|| s < 0 || s > 255
|| l < 0 || l > 255
|| a < 0 || a > 255) {
- qWarning("QColor::fromHsv: HSV parameters out of range");
+ qWarning("QColor::fromHsl: HSL parameters out of range");
return QColor();
}
@@ -2107,7 +2107,7 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
|| (s < qreal(0.0) || s > qreal(1.0))
|| (l < qreal(0.0) || l > qreal(1.0))
|| (a < qreal(0.0) || a > qreal(1.0))) {
- qWarning("QColor::fromHsvF: HSV parameters out of range");
+ qWarning("QColor::fromHslF: HSL parameters out of range");
return QColor();
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 64a363868a..6cfc4b9307 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -503,14 +503,16 @@ static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const
template<bool RGBA, bool maskAlpha>
static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
+ if (count <= 0)
+ return;
+
const __m128i amask = _mm_set1_epi32(0xff000000);
int i = 0;
- if (((uintptr_t)buffer & 0xf) && count > 0) {
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
uint s = *src++;
if (RGBA)
s = RGBA2ARGB(s);
*buffer++ = QRgba64::fromArgb32(s);
- i++;
}
for (; i < count-3; i += 4) {
__m128i vs = _mm_loadu_si128((const __m128i*)src);
@@ -641,15 +643,18 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui
template<QtPixelOrder PixelOrder>
static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
+ if (count <= 0)
+ return;
+
const __m128i rmask = _mm_set1_epi32(0x3ff00000);
const __m128i gmask = _mm_set1_epi32(0x000ffc00);
const __m128i bmask = _mm_set1_epi32(0x000003ff);
const __m128i afactor = _mm_set1_epi16(0x5555);
int i = 0;
- if (((uintptr_t)buffer & 0xf) && count > 0) {
+
+ for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
*buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++);
- i++;
- }
+
for (; i < count-3; i += 4) {
__m128i vs = _mm_loadu_si128((const __m128i*)src);
src += 4;
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 0f81f09f60..47483b2869 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -377,8 +377,8 @@ QByteArray QPdf::generateDashes(const QPen &pen)
s << dw;
}
s << ']';
- //qDebug() << "dasharray: pen has" << dasharray;
- //qDebug() << " => " << result;
+ s << pen.dashOffset() * w;
+ s << " d\n";
return result;
}
@@ -1209,7 +1209,7 @@ void QPdfEngine::setPen()
}
*d->currentPage << pdfJoinStyle << "j ";
- *d->currentPage << QPdf::generateDashes(d->pen) << " 0 d\n";
+ *d->currentPage << QPdf::generateDashes(d->pen);
}
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c86fdebea5..dd02e24676 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -48,6 +48,16 @@
#include <qpa/qplatformgraphicsbuffer.h>
#include <qpa/qplatformgraphicsbufferhelper.h>
+#ifndef GL_TEXTURE_BASE_LEVEL
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#endif
+#ifndef GL_TEXTURE_MAX_LEVEL
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#endif
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -311,12 +321,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -435,18 +444,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
image = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
-
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
}
-#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -459,15 +466,13 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
-#ifndef QT_OPENGL_ES_2
- if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- } else
-#endif
- {
+ } else {
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
if (rect.width() >= imageRect.width() / 2) {
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 54d7fe1738..686a00e42a 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
+extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio);
static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio)
{
// We might use the fileName for loading if url loading fails
@@ -63,19 +64,8 @@ static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePi
if (targetDevicePixelRatio <= 1.0)
return fileName;
- // try to find a 2x version
-
- const int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
- if (dotIndex != -1) {
- QString at2xfileName = fileName;
- at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName)) {
- fileName = at2xfileName;
- *url = QUrl(fileName);
- }
- }
-
- return fileName;
+ // try to find a Nx version
+ return qt_findAtNxFile(fileName, targetDevicePixelRatio);
}
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 4c92e5d000..354dfeb78c 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -231,13 +231,13 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c
QOpenUrlHandlerRegistry *registry = handlerRegistry();
QMutexLocker locker(&registry->mutex);
if (!receiver) {
- registry->handlers.remove(scheme);
+ registry->handlers.remove(scheme.toLower());
return;
}
QOpenUrlHandlerRegistry::Handler h;
h.receiver = receiver;
h.name = method;
- registry->handlers.insert(scheme, h);
+ registry->handlers.insert(scheme.toLower(), h);
QObject::connect(receiver, SIGNAL(destroyed(QObject*)),
registry, SLOT(handlerDestroyed(QObject*)));
}