summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/CMakeLists.txt5
-rw-r--r--src/platformsupport/accessibility/CMakeLists.txt8
-rw-r--r--src/platformsupport/accessibility/qaccessiblebridgeutils.cpp2
-rw-r--r--src/platformsupport/clipboard/CMakeLists.txt9
-rw-r--r--src/platformsupport/devicediscovery/CMakeLists.txt13
-rw-r--r--src/platformsupport/edid/CMakeLists.txt7
-rw-r--r--src/platformsupport/eglconvenience/.prev_CMakeLists.txt16
-rw-r--r--src/platformsupport/eglconvenience/CMakeLists.txt30
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp6
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer_p.h2
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp12
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h2
-rw-r--r--src/platformsupport/eventdispatchers/.prev_CMakeLists.txt14
-rw-r--r--src/platformsupport/eventdispatchers/CMakeLists.txt14
-rw-r--r--src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp2
-rw-r--r--src/platformsupport/fbconvenience/CMakeLists.txt8
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp2
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler.cpp4
-rw-r--r--src/platformsupport/fontdatabases/.prev_CMakeLists.txt53
-rw-r--r--src/platformsupport/fontdatabases/CMakeLists.txt53
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp96
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp4
-rw-r--r--src/platformsupport/fontdatabases/fontdatabases.pro7
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp159
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h19
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm11
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp465
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase_p.h96
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp806
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp20
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h37
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp869
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h133
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp60
-rw-r--r--src/platformsupport/fontdatabases/windows/windows.pri10
-rw-r--r--src/platformsupport/glxconvenience/.prev_CMakeLists.txt8
-rw-r--r--src/platformsupport/glxconvenience/CMakeLists.txt8
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp4
-rw-r--r--src/platformsupport/graphics/CMakeLists.txt8
-rw-r--r--src/platformsupport/input/.prev_CMakeLists.txt32
-rw-r--r--src/platformsupport/input/CMakeLists.txt32
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp3
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h8
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp15
-rw-r--r--src/platformsupport/input/integrityhid/qintegrityhidmanager.h2
-rw-r--r--src/platformsupport/input/libinput/qlibinputtouch.cpp58
-rw-r--r--src/platformsupport/input/libinput/qlibinputtouch_p.h7
-rw-r--r--src/platformsupport/input/xkbcommon/CMakeLists.txt10
-rw-r--r--src/platformsupport/kmsconvenience/.prev_CMakeLists.txt10
-rw-r--r--src/platformsupport/kmsconvenience/CMakeLists.txt10
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp121
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice_p.h17
-rw-r--r--src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt13
-rw-r--r--src/platformsupport/linuxaccessibility/CMakeLists.txt13
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp6
-rw-r--r--src/platformsupport/linuxofono/CMakeLists.txt20
-rw-r--r--src/platformsupport/linuxofono/linuxofono.pro15
-rw-r--r--src/platformsupport/linuxofono/qofonoservice_linux.cpp384
-rw-r--r--src/platformsupport/linuxofono/qofonoservice_linux_p.h207
-rw-r--r--src/platformsupport/platformcompositor/CMakeLists.txt10
-rw-r--r--src/platformsupport/platformcompositor/platformcompositor.pro4
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor_p.h2
-rw-r--r--src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.cpp455
-rw-r--r--src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.h87
-rw-r--r--src/platformsupport/platformsupport.pro6
-rw-r--r--src/platformsupport/services/CMakeLists.txt10
-rw-r--r--src/platformsupport/themes/CMakeLists.txt14
-rw-r--r--src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp6
-rw-r--r--src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h4
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp2
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes_p.h4
-rw-r--r--src/platformsupport/vkconvenience/.prev_CMakeLists.txt16
-rw-r--r--src/platformsupport/vkconvenience/CMakeLists.txt16
-rw-r--r--src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp16
-rw-r--r--src/platformsupport/vkconvenience/qvkconvenience.cpp4
-rw-r--r--src/platformsupport/vkconvenience/vkconvenience.pro2
-rw-r--r--src/platformsupport/windowsuiautomation/CMakeLists.txt8
78 files changed, 3400 insertions, 1333 deletions
diff --git a/src/platformsupport/CMakeLists.txt b/src/platformsupport/CMakeLists.txt
index 158ad419a3..fc980f3707 100644
--- a/src/platformsupport/CMakeLists.txt
+++ b/src/platformsupport/CMakeLists.txt
@@ -5,6 +5,11 @@ add_subdirectory(eventdispatchers)
add_subdirectory(devicediscovery)
add_subdirectory(fbconvenience)
add_subdirectory(themes)
+# special case begin
+if (QT_FEATURE_dbus)
+ add_subdirectory(linuxofono)
+endif()
+# special case end
if(APPLE OR QT_FEATURE_freetype OR WIN32)
add_subdirectory(fontdatabases)
endif()
diff --git a/src/platformsupport/accessibility/CMakeLists.txt b/src/platformsupport/accessibility/CMakeLists.txt
index 288b1a33e5..4757b123af 100644
--- a/src/platformsupport/accessibility/CMakeLists.txt
+++ b/src/platformsupport/accessibility/CMakeLists.txt
@@ -4,21 +4,17 @@
## AccessibilitySupport Module:
#####################################################################
-add_qt_module(AccessibilitySupport
+qt_add_module(AccessibilitySupport
STATIC
INTERNAL_MODULE
SOURCES
qaccessiblebridgeutils.cpp qaccessiblebridgeutils_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
)
#### Keys ignored in scope 1:.:.:accessibility.pro:<TRUE>:
# MODULE = "accessibility_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp b/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp
index f280e65c29..a15b93e31e 100644
--- a/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp
+++ b/src/platformsupport/accessibility/qaccessiblebridgeutils.cpp
@@ -93,7 +93,7 @@ bool performEffectiveAction(QAccessibleInterface *iface, const QString &actionNa
if (!success)
return false;
stepSize = (max - min) / 10; // this is pretty arbitrary, we just need to provide something
- const int typ = currentVariant.type();
+ const int typ = currentVariant.userType();
if (typ != QMetaType::Float && typ != QMetaType::Double) {
// currentValue is an integer. Round it up to ensure stepping in case it was below 1
stepSize = qCeil(stepSize);
diff --git a/src/platformsupport/clipboard/CMakeLists.txt b/src/platformsupport/clipboard/CMakeLists.txt
index 804f3d53c7..52022903aa 100644
--- a/src/platformsupport/clipboard/CMakeLists.txt
+++ b/src/platformsupport/clipboard/CMakeLists.txt
@@ -4,29 +4,26 @@
## ClipboardSupport Module:
#####################################################################
-add_qt_module(ClipboardSupport
+qt_add_module(ClipboardSupport
STATIC
INTERNAL_MODULE
SOURCES
qmacmime.mm qmacmime_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::CorePrivate
PUBLIC_LIBRARIES
${FWImageIO}
- Qt::Core
+ Qt::CorePrivate
Qt::Gui
)
#### Keys ignored in scope 1:.:.:clipboard.pro:<TRUE>:
# MODULE = "clipboard_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(ClipboardSupport CONDITION APPLE_OSX
+qt_extend_target(ClipboardSupport CONDITION APPLE_OSX
LIBRARIES
${FWAppKit}
)
diff --git a/src/platformsupport/devicediscovery/CMakeLists.txt b/src/platformsupport/devicediscovery/CMakeLists.txt
index 6253a024c0..8ecabb4a1b 100644
--- a/src/platformsupport/devicediscovery/CMakeLists.txt
+++ b/src/platformsupport/devicediscovery/CMakeLists.txt
@@ -4,40 +4,37 @@
## DeviceDiscoverySupport Module:
#####################################################################
-add_qt_module(DeviceDiscoverySupport
+qt_add_module(DeviceDiscoverySupport
STATIC
INTERNAL_MODULE
SOURCES
qdevicediscovery_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::CorePrivate
PUBLIC_LIBRARIES
- Qt::Core
+ Qt::CorePrivate
)
#### Keys ignored in scope 1:.:.:devicediscovery.pro:<TRUE>:
# MODULE = "devicediscovery_support"
# QT_FOR_CONFIG = "gui-private"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_libudev
+qt_extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_libudev
SOURCES
qdevicediscovery_udev.cpp qdevicediscovery_udev_p.h
LIBRARIES
PkgConfig::Libudev
)
-extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_evdev AND NOT QT_FEATURE_libudev
+qt_extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_evdev AND NOT QT_FEATURE_libudev
SOURCES
qdevicediscovery_static.cpp qdevicediscovery_static_p.h
)
-extend_target(DeviceDiscoverySupport CONDITION NOT QT_FEATURE_evdev AND NOT QT_FEATURE_libudev
+qt_extend_target(DeviceDiscoverySupport CONDITION NOT QT_FEATURE_evdev AND NOT QT_FEATURE_libudev
SOURCES
qdevicediscovery_dummy.cpp qdevicediscovery_dummy_p.h
)
diff --git a/src/platformsupport/edid/CMakeLists.txt b/src/platformsupport/edid/CMakeLists.txt
index 2691d27d95..aaea30448e 100644
--- a/src/platformsupport/edid/CMakeLists.txt
+++ b/src/platformsupport/edid/CMakeLists.txt
@@ -4,21 +4,18 @@
## EdidSupport Module:
#####################################################################
-add_qt_module(EdidSupport
+qt_add_module(EdidSupport
STATIC
INTERNAL_MODULE
SOURCES
qedidparser.cpp qedidparser_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::CorePrivate
PUBLIC_LIBRARIES
- Qt::Core
+ Qt::CorePrivate
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:edid.pro:<TRUE>:
# MODULE = "edid_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/eglconvenience/.prev_CMakeLists.txt b/src/platformsupport/eglconvenience/.prev_CMakeLists.txt
index ea6b9ea902..f8efacd7cb 100644
--- a/src/platformsupport/eglconvenience/.prev_CMakeLists.txt
+++ b/src/platformsupport/eglconvenience/.prev_CMakeLists.txt
@@ -4,7 +4,7 @@
## EglSupport Module:
#####################################################################
-add_qt_module(EglSupport
+qt_add_module(EglSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -13,42 +13,38 @@ add_qt_module(EglSupport
qt_egl_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:eglconvenience.pro:<TRUE>:
# MODULE = "egl_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(EglSupport CONDITION QT_FEATURE_opengl
+qt_extend_target(EglSupport CONDITION QT_FEATURE_opengl
SOURCES
qeglpbuffer.cpp qeglpbuffer_p.h
qeglplatformcontext.cpp qeglplatformcontext_p.h
)
-extend_target(EglSupport CONDITION QT_FEATURE_egl_x11
+qt_extend_target(EglSupport CONDITION QT_FEATURE_egl_x11
SOURCES
qxlibeglintegration.cpp qxlibeglintegration_p.h
LIBRARIES
X11::XCB
)
-extend_target(EglSupport CONDITION NOT QT_FEATURE_egl_x11
+qt_extend_target(EglSupport CONDITION NOT QT_FEATURE_egl_x11
DEFINES
QT_EGL_NO_X11
)
-extend_target(EglSupport CONDITION QT_FEATURE_dlopen
+qt_extend_target(EglSupport CONDITION QT_FEATURE_dlopen
PUBLIC_LIBRARIES
${CMAKE_DL_LIBS}
)
diff --git a/src/platformsupport/eglconvenience/CMakeLists.txt b/src/platformsupport/eglconvenience/CMakeLists.txt
index d6d41d1ead..b18a1470ec 100644
--- a/src/platformsupport/eglconvenience/CMakeLists.txt
+++ b/src/platformsupport/eglconvenience/CMakeLists.txt
@@ -1,10 +1,12 @@
-qt_find_package(EGL) # special case
+# Generated from eglconvenience.pro.
#####################################################################
## EglSupport Module:
#####################################################################
-add_qt_module(EglSupport
+qt_find_package(EGL) # special case
+
+qt_add_module(EglSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -13,33 +15,39 @@ add_qt_module(EglSupport
qt_egl_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- QT_EGL_NO_X11
- LIBRARIES
- ${CMAKE_DL_LIBS}
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
EGL::EGL # special case
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:eglconvenience.pro:<TRUE>:
# MODULE = "egl_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(EglSupport CONDITION QT_FEATURE_opengl
+qt_extend_target(EglSupport CONDITION QT_FEATURE_opengl
SOURCES
qeglpbuffer.cpp qeglpbuffer_p.h
qeglplatformcontext.cpp qeglplatformcontext_p.h
)
-extend_target(EglSupport CONDITION QT_FEATURE_xlib
+qt_extend_target(EglSupport CONDITION QT_FEATURE_egl_x11
SOURCES
qxlibeglintegration.cpp qxlibeglintegration_p.h
+ LIBRARIES
+ X11::XCB
+)
+
+qt_extend_target(EglSupport CONDITION NOT QT_FEATURE_egl_x11
+ DEFINES
+ QT_EGL_NO_X11
+)
+
+qt_extend_target(EglSupport CONDITION QT_FEATURE_dlopen
+ PUBLIC_LIBRARIES
+ ${CMAKE_DL_LIBS}
)
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index 5ee4773b70..5303d37cee 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -281,11 +281,11 @@ EGLConfig QEglConfigChooser::chooseConfig()
}
configureAttributes.append(EGL_NONE);
- EGLConfig cfg = 0;
+ EGLConfig cfg = nullptr;
do {
// Get the number of matching configurations for this set of properties.
EGLint matching = 0;
- if (!eglChooseConfig(display(), configureAttributes.constData(), 0, 0, &matching) || !matching)
+ if (!eglChooseConfig(display(), configureAttributes.constData(), nullptr, 0, &matching) || !matching)
continue;
// Fetch all of the matching configurations and find the
@@ -450,7 +450,7 @@ static struct AttrInfo attrs[] = {
{EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA"},
{EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL"},
{EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL"},
- {-1, 0}};
+ {-1, nullptr}};
void q_printEglConfig(EGLDisplay display, EGLConfig config)
{
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
index 8ad2eb7248..a137d0d328 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h
+++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
@@ -60,7 +60,7 @@ class QEGLPbuffer : public QPlatformOffscreenSurface
{
public:
QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface,
- QEGLPlatformContext::Flags flags = nullptr);
+ QEGLPlatformContext::Flags flags = { });
~QEGLPbuffer();
QSurfaceFormat format() const override { return m_format; }
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 94def16748..63cf771f32 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -137,7 +137,7 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig, format);
// m_format now has the renderableType() resolved (it cannot be Default anymore)
// but does not yet contain version, profile, options.
- m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0;
+ m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : nullptr;
QVector<EGLint> contextAttrs;
contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
@@ -194,8 +194,8 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
eglBindAPI(m_api);
m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData());
if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) {
- m_shareContext = 0;
- m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, 0, contextAttrs.constData());
+ m_shareContext = nullptr;
+ m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, nullptr, contextAttrs.constData());
}
if (m_eglContext == EGL_NO_CONTEXT) {
@@ -218,7 +218,7 @@ void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLCon
qWarning("QEGLPlatformContext: Requires a QEGLNativeContext");
return;
}
- QEGLNativeContext handle = nativeHandle.value<QEGLNativeContext>();
+ QEGLNativeContext handle = qvariant_cast<QEGLNativeContext>(nativeHandle);
EGLContext context = handle.context();
if (!context) {
qWarning("QEGLPlatformContext: No EGLContext given");
@@ -262,7 +262,7 @@ void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLCon
}
m_eglContext = context;
- m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0;
+ m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : nullptr;
updateFormatFromGL();
}
@@ -326,7 +326,7 @@ void QEGLPlatformContext::updateFormatFromGL()
EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext);
if (!ok) {
EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT);
- tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData());
+ tempContext = eglCreateContext(m_eglDisplay, config, nullptr, m_contextAttrs.constData());
if (tempContext != EGL_NO_CONTEXT)
ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext);
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
index ed77c57df5..f0388cd29c 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -69,7 +69,7 @@ public:
QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config = nullptr, const QVariant &nativeHandle = QVariant(),
- Flags flags = nullptr);
+ Flags flags = { });
~QEGLPlatformContext();
void initialize() override;
diff --git a/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt b/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt
index 22b89d3317..2e25d6cfd6 100644
--- a/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt
+++ b/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt
@@ -4,41 +4,37 @@
## EventDispatcherSupport Module:
#####################################################################
-add_qt_module(EventDispatcherSupport
+qt_add_module(EventDispatcherSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:eventdispatchers.pro:<TRUE>:
# MODULE = "eventdispatcher_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(EventDispatcherSupport CONDITION UNIX
+qt_extend_target(EventDispatcherSupport CONDITION UNIX
SOURCES
qgenericunixeventdispatcher.cpp qgenericunixeventdispatcher_p.h
qunixeventdispatcher.cpp
qunixeventdispatcher_qpa_p.h
)
-extend_target(EventDispatcherSupport CONDITION WIN32
+qt_extend_target(EventDispatcherSupport CONDITION WIN32
SOURCES
qwindowsguieventdispatcher.cpp qwindowsguieventdispatcher_p.h
)
-extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
+qt_extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
SOURCES
qeventdispatcher_glib.cpp qeventdispatcher_glib_p.h
LIBRARIES
diff --git a/src/platformsupport/eventdispatchers/CMakeLists.txt b/src/platformsupport/eventdispatchers/CMakeLists.txt
index fae7bff862..72b873423b 100644
--- a/src/platformsupport/eventdispatchers/CMakeLists.txt
+++ b/src/platformsupport/eventdispatchers/CMakeLists.txt
@@ -6,41 +6,37 @@ qt_find_package(GLIB2) # special case
## EventDispatcherSupport Module:
#####################################################################
-add_qt_module(EventDispatcherSupport
+qt_add_module(EventDispatcherSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:eventdispatchers.pro:<TRUE>:
# MODULE = "eventdispatcher_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(EventDispatcherSupport CONDITION UNIX
+qt_extend_target(EventDispatcherSupport CONDITION UNIX
SOURCES
qgenericunixeventdispatcher.cpp qgenericunixeventdispatcher_p.h
qunixeventdispatcher.cpp
qunixeventdispatcher_qpa_p.h
)
-extend_target(EventDispatcherSupport CONDITION WIN32
+qt_extend_target(EventDispatcherSupport CONDITION WIN32
SOURCES
qwindowsguieventdispatcher.cpp qwindowsguieventdispatcher_p.h
)
-extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
+qt_extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
SOURCES
qeventdispatcher_glib.cpp qeventdispatcher_glib_p.h
LIBRARIES
diff --git a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
index a37547f513..20cfb5155e 100644
--- a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
+++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
*/
QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
- QEventDispatcherWin32(parent), m_flags(0)
+ QEventDispatcherWin32(parent)
{
setObjectName(QStringLiteral("QWindowsGuiEventDispatcher"));
createInternalHwnd(); // QTBUG-40881: Do not delay registering timers, etc. for QtMfc.
diff --git a/src/platformsupport/fbconvenience/CMakeLists.txt b/src/platformsupport/fbconvenience/CMakeLists.txt
index 61d61e4321..804b2c15ec 100644
--- a/src/platformsupport/fbconvenience/CMakeLists.txt
+++ b/src/platformsupport/fbconvenience/CMakeLists.txt
@@ -4,7 +4,7 @@
## FbSupport Module:
#####################################################################
-add_qt_module(FbSupport
+qt_add_module(FbSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -15,16 +15,12 @@ add_qt_module(FbSupport
qfbwindow.cpp qfbwindow_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:fbconvenience.pro:<TRUE>:
# MODULE = "fb_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index c42fd879f8..76984dfe5c 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -255,7 +255,7 @@ QFbWindow *QFbScreen::windowForId(WId wid) const
QFbScreen::Flags QFbScreen::flags() const
{
- return 0;
+ return { };
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp
index 7bb9e28ac2..8aab0bada4 100644
--- a/src/platformsupport/fbconvenience/qfbvthandler.cpp
+++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp
@@ -70,6 +70,10 @@ QT_BEGIN_NAMESPACE
#ifdef VTH_ENABLED
static void setTTYCursor(bool enable)
{
+ static bool ignore = qEnvironmentVariableIntValue("QT_QPA_PRESERVE_CONSOLE_STATE");
+ if (ignore)
+ return;
+
const char * const devs[] = { "/dev/tty0", "/dev/tty", "/dev/console", 0 };
int fd = -1;
for (const char * const *dev = devs; *dev; ++dev) {
diff --git a/src/platformsupport/fontdatabases/.prev_CMakeLists.txt b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt
index bd193fbe78..56cf076bd9 100644
--- a/src/platformsupport/fontdatabases/.prev_CMakeLists.txt
+++ b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt
@@ -4,29 +4,25 @@
## FontDatabaseSupport Module:
#####################################################################
-add_qt_module(FontDatabaseSupport
+qt_add_module(FontDatabaseSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:fontdatabases.pro:<TRUE>:
# MODULE = "fontdatabase_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(FontDatabaseSupport CONDITION APPLE
+qt_extend_target(FontDatabaseSupport CONDITION APPLE
SOURCES
mac/qcoretextfontdatabase.mm mac/qcoretextfontdatabase_p.h
mac/qfontengine_coretext.mm mac/qfontengine_coretext_p.h
@@ -37,17 +33,17 @@ extend_target(FontDatabaseSupport CONDITION APPLE
${FWFoundation}
)
-extend_target(FontDatabaseSupport CONDITION APPLE_OSX
+qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX
LIBRARIES
${FWAppKit}
)
-extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
+qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
LIBRARIES
${FWUIKit}
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
SOURCES
freetype/qfontengine_ft.cpp freetype/qfontengine_ft_p.h
freetype/qfreetypefontdatabase.cpp freetype/qfreetypefontdatabase_p.h
@@ -55,12 +51,12 @@ extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
WrapFreetype::WrapFreetype
)
-extend_target(FontDatabaseSupport CONDITION UNIX
+qt_extend_target(FontDatabaseSupport CONDITION UNIX
SOURCES
genericunix/qgenericunixfontdatabase_p.h
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig AND UNIX
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
SOURCES
fontconfig/qfontconfigdatabase.cpp fontconfig/qfontconfigdatabase_p.h
fontconfig/qfontenginemultifontconfig.cpp fontconfig/qfontenginemultifontconfig_p.h
@@ -68,64 +64,73 @@ extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig AND UNIX
Fontconfig::Fontconfig
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase.cpp windows/qwindowsfontdatabase_p.h
+ windows/qwindowsfontdatabasebase.cpp windows/qwindowsfontdatabasebase_p.h
windows/qwindowsfontengine.cpp windows/qwindowsfontengine_p.h
windows/qwindowsnativeimage.cpp windows/qwindowsnativeimage_p.h
LIBRARIES
- Qt::GuiPrivate
advapi32
gdi32
ole32
user32
PUBLIC_LIBRARIES
- Qt::Gui
+ Qt::GuiPrivate
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase_ft.cpp windows/qwindowsfontdatabase_ft_p.h
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontenginedirectwrite.cpp windows/qwindowsfontenginedirectwrite_p.h
LIBRARIES
d2d1
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite3 AND WIN32 AND NOT WINRT
+ SOURCES
+ windows/qwindowsdirectwritefontdatabase.cpp windows/qwindowsdirectwritefontdatabase_p.h
+ DEFINES
+ QT_USE_DIRECTWRITE2
+ QT_USE_DIRECTWRITE3
+ LIBRARIES
+ dwrite_3
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
DEFINES
QT_USE_DIRECTWRITE2
LIBRARIES
dwrite_2
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
LIBRARIES
dwrite
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
DEFINES
QT_NO_DIRECTWRITE
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
LIBRARIES
uuid
)
-extend_target(FontDatabaseSupport CONDITION WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WINRT
SOURCES
winrt/qwinrtfontdatabase.cpp winrt/qwinrtfontdatabase_p.h
DEFINES
__WRL_NO_DEFAULT_LIB__
LIBRARIES
- Qt::GuiPrivate
dwrite_1
ws2_32
PUBLIC_LIBRARIES
- Qt::Gui
+ Qt::GuiPrivate
)
diff --git a/src/platformsupport/fontdatabases/CMakeLists.txt b/src/platformsupport/fontdatabases/CMakeLists.txt
index 38b0dfb40f..1150ac6bef 100644
--- a/src/platformsupport/fontdatabases/CMakeLists.txt
+++ b/src/platformsupport/fontdatabases/CMakeLists.txt
@@ -7,29 +7,25 @@ qt_find_package(Fontconfig) # special case
## FontDatabaseSupport Module:
#####################################################################
-add_qt_module(FontDatabaseSupport
+qt_add_module(FontDatabaseSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:fontdatabases.pro:<TRUE>:
# MODULE = "fontdatabase_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(FontDatabaseSupport CONDITION APPLE
+qt_extend_target(FontDatabaseSupport CONDITION APPLE
SOURCES
mac/qcoretextfontdatabase.mm mac/qcoretextfontdatabase_p.h
mac/qfontengine_coretext.mm mac/qfontengine_coretext_p.h
@@ -40,17 +36,17 @@ extend_target(FontDatabaseSupport CONDITION APPLE
${FWFoundation}
)
-extend_target(FontDatabaseSupport CONDITION APPLE_OSX
+qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX
LIBRARIES
${FWAppKit}
)
-extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
+qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
LIBRARIES
${FWUIKit}
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
SOURCES
freetype/qfontengine_ft.cpp freetype/qfontengine_ft_p.h
freetype/qfreetypefontdatabase.cpp freetype/qfreetypefontdatabase_p.h
@@ -58,12 +54,12 @@ extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype
WrapFreetype::WrapFreetype
)
-extend_target(FontDatabaseSupport CONDITION UNIX
+qt_extend_target(FontDatabaseSupport CONDITION UNIX
SOURCES
genericunix/qgenericunixfontdatabase_p.h
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig AND UNIX
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
SOURCES
fontconfig/qfontconfigdatabase.cpp fontconfig/qfontconfigdatabase_p.h
fontconfig/qfontenginemultifontconfig.cpp fontconfig/qfontenginemultifontconfig_p.h
@@ -71,64 +67,73 @@ extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig AND UNIX
Fontconfig::Fontconfig
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase.cpp windows/qwindowsfontdatabase_p.h
+ windows/qwindowsfontdatabasebase.cpp windows/qwindowsfontdatabasebase_p.h
windows/qwindowsfontengine.cpp windows/qwindowsfontengine_p.h
windows/qwindowsnativeimage.cpp windows/qwindowsnativeimage_p.h
LIBRARIES
- Qt::GuiPrivate
advapi32
gdi32
ole32
user32
PUBLIC_LIBRARIES
- Qt::Gui
+ Qt::GuiPrivate
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontdatabase_ft.cpp windows/qwindowsfontdatabase_ft_p.h
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT WINRT
SOURCES
windows/qwindowsfontenginedirectwrite.cpp windows/qwindowsfontenginedirectwrite_p.h
LIBRARIES
d2d1
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite3 AND WIN32 AND NOT WINRT
+ SOURCES
+ windows/qwindowsdirectwritefontdatabase.cpp windows/qwindowsdirectwritefontdatabase_p.h
+ DEFINES
+ QT_USE_DIRECTWRITE2
+ QT_USE_DIRECTWRITE3
+ LIBRARIES
+ dwrite_3
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND QT_FEATURE_directwrite2 AND WIN32 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
DEFINES
QT_USE_DIRECTWRITE2
LIBRARIES
dwrite_2
)
-extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_direct2d AND QT_FEATURE_directwrite AND WIN32 AND NOT QT_FEATURE_directwrite2 AND NOT QT_FEATURE_directwrite3 AND NOT WINRT
LIBRARIES
dwrite
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
DEFINES
QT_NO_DIRECTWRITE
)
-extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
LIBRARIES
uuid
)
-extend_target(FontDatabaseSupport CONDITION WINRT
+qt_extend_target(FontDatabaseSupport CONDITION WINRT
SOURCES
winrt/qwinrtfontdatabase.cpp winrt/qwinrtfontdatabase_p.h
DEFINES
__WRL_NO_DEFAULT_LIB__
LIBRARIES
- Qt::GuiPrivate
dwrite_1
ws2_32
PUBLIC_LIBRARIES
- Qt::Gui
+ Qt::GuiPrivate
)
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 7abf295782..af49ad6407 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -56,6 +56,8 @@
#include <QtGui/qguiapplication.h>
+#include <QtCore/private/qduplicatetracker_p.h>
+
#include <fontconfig/fontconfig.h>
#if FC_VERSION >= 20402
#include <fontconfig/fcfreetype.h>
@@ -260,7 +262,18 @@ static const char specialLanguages[][6] = {
"", // MasaramGondi
"", // Nushu
"", // Soyombo
- "" // ZanabazarSquare
+ "", // ZanabazarSquare
+ "", // Dogra
+ "", // GunjalaGondi
+ "", // HanifiRohingya
+ "", // Makasar
+ "", // Medefaidrin
+ "", // OldSogdian
+ "", // Sogdian
+ "", // Elymaic
+ "", // Nandinagari
+ "", // NyiakengPuachueHmong
+ "" // Wancho
};
Q_STATIC_ASSERT(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount);
@@ -349,7 +362,7 @@ Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritin
static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
{
- const char *stylehint = 0;
+ const char *stylehint = nullptr;
switch (style) {
case QFont::SansSerif:
stylehint = "sans-serif";
@@ -383,7 +396,7 @@ static void populateFromPattern(FcPattern *pattern)
{
QString familyName;
QString familyNameLang;
- FcChar8 *value = 0;
+ FcChar8 *value = nullptr;
int weight_value;
int slant_value;
int spacing_value;
@@ -406,7 +419,7 @@ static void populateFromPattern(FcPattern *pattern)
slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL;
- file_value = 0;
+ file_value = nullptr;
indexValue = 0;
scalable = FcTrue;
@@ -420,20 +433,20 @@ static void populateFromPattern(FcPattern *pattern)
if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
spacing_value = FC_PROPORTIONAL;
if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
+ file_value = nullptr;
if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
indexValue = 0;
if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
scalable = FcTrue;
if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
+ foundry_value = nullptr;
if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
+ style_value = nullptr;
if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
antialias = true;
QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
+ FcLangSet *langset = nullptr;
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
if (res == FcResultMatch) {
bool hasLang = false;
@@ -450,7 +463,7 @@ static void populateFromPattern(FcPattern *pattern)
if (*capabilityForWritingSystem[j] && requiresOpenType(j)) {
if (cap == nullptr)
capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
- if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)
+ if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == nullptr)
continue;
}
#endif
@@ -535,14 +548,14 @@ void QFontconfigDatabase::populateFontDatabase()
#if FC_VERSION >= 20297
FC_CAPABILITY,
#endif
- (const char *)0
+ (const char *)nullptr
};
const char **p = properties;
while (*p) {
FcObjectSetAdd(os, *p);
++p;
}
- fonts = FcFontList(0, pattern, os);
+ fonts = FcFontList(nullptr, pattern, os);
FcObjectSetDestroy(os);
FcPatternDestroy(pattern);
}
@@ -561,7 +574,7 @@ void QFontconfigDatabase::populateFontDatabase()
{ "Serif", "serif", false },
{ "Sans Serif", "sans-serif", false },
{ "Monospace", "monospace", true },
- { 0, 0, false }
+ { nullptr, nullptr, false }
};
const FcDefaultFont *f = defaults;
// aliases only make sense for 'common', not for any of the specials
@@ -570,9 +583,9 @@ void QFontconfigDatabase::populateFontDatabase()
while (f->qtname) {
QString familyQtName = QString::fromLatin1(f->qtname);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,0);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,0);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,0);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
++f;
}
@@ -588,7 +601,7 @@ void QFontconfigDatabase::populateFontDatabase()
void QFontconfigDatabase::invalidate()
{
// Clear app fonts.
- FcConfigAppFontClear(0);
+ FcConfigAppFontClear(nullptr);
}
QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
@@ -680,7 +693,7 @@ QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bo
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
if (!usrPtr)
- return 0;
+ return nullptr;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
@@ -695,7 +708,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
if (!engine->init(fid, engine->antialias, engine->defaultFormat) || engine->invalid()) {
delete engine;
- engine = 0;
+ engine = nullptr;
}
return engine;
@@ -704,8 +717,8 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
QFontEngineFT *engine = static_cast<QFontEngineFT*>(QFreeTypeFontDatabase::fontEngine(fontData, pixelSize, hintingPreference));
- if (engine == 0)
- return 0;
+ if (engine == nullptr)
+ return nullptr;
setupFontEngine(engine, engine->fontDef);
@@ -746,7 +759,7 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
// while a Japanese font should be used for that if LANG=ja)
FcPattern *dummy = FcPatternCreate();
FcDefaultSubstitute(dummy);
- FcChar8 *lang = 0;
+ FcChar8 *lang = nullptr;
FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
if (res == FcResultMatch)
FcPatternAddString(pattern, FC_LANG, lang);
@@ -759,27 +772,26 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
}
- FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
FcResult result = FcResultMatch;
- FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
+ FcFontSet *fontSet = FcFontSort(nullptr,pattern,FcFalse,nullptr,&result);
FcPatternDestroy(pattern);
if (fontSet) {
- QSet<QString> duplicates;
+ QDuplicateTracker<QString> duplicates;
duplicates.reserve(fontSet->nfont + 1);
- duplicates.insert(family.toCaseFolded());
+ (void)duplicates.hasSeen(family.toCaseFolded());
for (int i = 0; i < fontSet->nfont; i++) {
- FcChar8 *value = 0;
+ FcChar8 *value = nullptr;
if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
const QString familyName = QString::fromUtf8((const char *)value);
const QString familyNameCF = familyName.toCaseFolded();
- if (!duplicates.contains(familyNameCF)) {
+ if (!duplicates.hasSeen(familyNameCF)) {
fallbackFamilies << familyName;
- duplicates.insert(familyNameCF);
}
}
FcFontSetDestroy(fontSet);
@@ -800,7 +812,7 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
FT_Library lib = qt_getFreetype();
- FcPattern *pattern = 0;
+ FcPattern *pattern = nullptr;
FT_Face face;
if (!FT_New_Memory_Face(lib, (const FT_Byte *)data.constData(), data.size(), id, &face)) {
@@ -819,16 +831,16 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
{
QStringList families;
- FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
+ FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication);
if (!set) {
- FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
- set = FcConfigGetFonts(0, FcSetApplication); // try again
+ FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent");
+ set = FcConfigGetFonts(nullptr, FcSetApplication); // try again
if (!set)
return families;
}
int id = 0;
- FcBlanks *blanks = FcConfigGetBlanks(0);
+ FcBlanks *blanks = FcConfigGetBlanks(nullptr);
int count = 0;
FcPattern *pattern;
@@ -838,7 +850,7 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
if (!pattern)
return families;
- FcChar8 *fam = 0;
+ FcChar8 *fam = nullptr;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
@@ -866,10 +878,10 @@ QString QFontconfigDatabase::resolveFontFamilyAlias(const QString &family) const
const QByteArray cs = family.toUtf8();
FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
}
- FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
- FcChar8 *familyAfterSubstitution = 0;
+ FcChar8 *familyAfterSubstitution = nullptr;
FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
FcPatternDestroy(pattern);
@@ -884,7 +896,7 @@ QFont QFontconfigDatabase::defaultFont() const
// or https://bugs.freedesktop.org/show_bug.cgi?id=35482 is fixed
FcPattern *dummy = FcPatternCreate();
FcDefaultSubstitute(dummy);
- FcChar8 *lang = 0;
+ FcChar8 *lang = nullptr;
FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
FcPattern *pattern = FcPatternCreate();
@@ -893,10 +905,10 @@ QFont QFontconfigDatabase::defaultFont() const
// certain FC_LANG based custom rules may happen in FcConfigSubstitute()
FcPatternAddString(pattern, FC_LANG, lang);
}
- FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
- FcChar8 *familyAfterSubstitution = 0;
+ FcChar8 *familyAfterSubstitution = nullptr;
FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
FcPatternDestroy(pattern);
@@ -953,10 +965,10 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
FcResult result;
- FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
- FcPattern *match = FcFontMatch(0, pattern, &result);
+ FcPattern *match = FcFontMatch(nullptr, pattern, &result);
if (match) {
engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf));
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
index 2fbcb6216e..cbf0793d75 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
@@ -60,7 +60,7 @@ bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint u
{
bool charSetHasChar = true;
FcPattern *matchPattern = getMatchPatternForFallback(at - 1);
- if (matchPattern != 0) {
+ if (matchPattern != nullptr) {
FcCharSet *charSet;
FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet);
charSetHasChar = FcCharSetHasChar(charSet, ucs4);
@@ -85,7 +85,7 @@ FcPattern * QFontEngineMultiFontConfig::getMatchPatternForFallback(int fallBackI
value.u.s = reinterpret_cast<const FcChar8 *>(cs.data());
FcPatternAdd(requestPattern, FC_FAMILY, value, true);
FcResult result;
- ret = FcFontMatch(0, requestPattern, &result);
+ ret = FcFontMatch(nullptr, requestPattern, &result);
cachedMatchPatterns.insert(fallBackIndex, ret);
FcPatternDestroy(requestPattern);
return ret;
diff --git a/src/platformsupport/fontdatabases/fontdatabases.pro b/src/platformsupport/fontdatabases/fontdatabases.pro
index f2bac9ab94..c3985ed398 100644
--- a/src/platformsupport/fontdatabases/fontdatabases.pro
+++ b/src/platformsupport/fontdatabases/fontdatabases.pro
@@ -17,9 +17,10 @@ qtConfig(freetype) {
unix {
include($$PWD/genericunix/genericunix.pri)
- qtConfig(fontconfig) {
- include($$PWD/fontconfig/fontconfig.pri)
- }
+}
+
+qtConfig(fontconfig) {
+ include($$PWD/fontconfig/fontconfig.pri)
}
win32:!winrt {
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 8c6cc8fbc1..ca78063f08 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -121,7 +121,7 @@ class QtFreetypeData
{
public:
QtFreetypeData()
- : library(0)
+ : library(nullptr)
{ }
~QtFreetypeData();
@@ -135,7 +135,7 @@ QtFreetypeData::~QtFreetypeData()
iter.value()->cleanup();
faces.clear();
FT_Done_FreeType(library);
- library = 0;
+ library = nullptr;
}
Q_GLOBAL_STATIC(QThreadStorage<QtFreetypeData *>, theFreetypeData)
@@ -215,7 +215,7 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
const QByteArray &fontData)
{
if (face_id.filename.isEmpty() && fontData.isEmpty())
- return 0;
+ return nullptr;
QtFreetypeData *freetypeData = qt_getFreetypeData();
@@ -238,7 +238,7 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
} else if (!QFileInfo(fileName).isNativePath()) {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
- return 0;
+ return nullptr;
}
newFreetype->fontData = file.readAll();
}
@@ -247,10 +247,10 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
}
if (!newFreetype->fontData.isEmpty()) {
if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
- return 0;
+ return nullptr;
}
} else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
- return 0;
+ return nullptr;
}
newFreetype->face = face;
@@ -261,8 +261,8 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
newFreetype->matrix.yy = 0x10000;
newFreetype->matrix.xy = 0;
newFreetype->matrix.yx = 0;
- newFreetype->unicode_map = 0;
- newFreetype->symbol_map = 0;
+ newFreetype->unicode_map = nullptr;
+ newFreetype->symbol_map = nullptr;
memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));
@@ -307,7 +307,7 @@ void QFreetypeFace::cleanup()
{
hbFace.reset();
FT_Done_Face(face);
- face = 0;
+ face = nullptr;
}
void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
@@ -324,7 +324,7 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
if (freetypeData->faces.isEmpty()) {
FT_Done_FreeType(freetypeData->library);
- freetypeData->library = 0;
+ freetypeData->library = nullptr;
}
}
@@ -659,7 +659,7 @@ QFontEngineFT *QFontEngineFT::create(const QByteArray &fontData, qreal pixelSize
QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
if (!fe->initFromData(fontData)) {
delete fe;
- return 0;
+ return nullptr;
}
fe->updateFamilyNameAndStyle();
@@ -682,7 +682,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
embolden = false;
obliquen = false;
antialias = true;
- freetype = 0;
+ freetype = nullptr;
default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
default_hint_style = ftInitialDefaultHintStyle;
subpixelType = Subpixel_None;
@@ -729,7 +729,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
face_id = faceId;
- symbol = freetype->symbol_map != 0;
+ symbol = freetype->symbol_map != nullptr;
PS_FontInfoRec psrec;
// don't assume that type1 fonts are symbol fonts by default
if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {
@@ -744,12 +744,12 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);
if (fake_oblique)
obliquen = true;
- FT_Set_Transform(face, &matrix, 0);
+ FT_Set_Transform(face, &matrix, nullptr);
freetype->matrix = matrix;
// fake bold
if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) {
if (const TT_OS2 *os2 = reinterpret_cast<const TT_OS2 *>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {
- if (os2->usWeightClass < 750)
+ if (os2->usWeightClass < 700)
embolden = true;
}
}
@@ -953,7 +953,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
format = defaultFormat != Format_None ? defaultFormat : Format_Mono;
Q_ASSERT(format != Format_None);
- Glyph *g = set ? set->getGlyph(glyph, subPixelPosition) : 0;
+ Glyph *g = set ? set->getGlyph(glyph, subPixelPosition) : nullptr;
if (g && g->format == format && (fetchMetricsOnly || g->data))
return g;
@@ -1051,10 +1051,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
// If any of the metrics are too large to fit, don't cache them
if (areMetricsTooLarge(info))
- return 0;
+ return nullptr;
g = new Glyph;
- g->data = 0;
+ g->data = nullptr;
g->linearAdvance = info.linearAdvance;
g->width = info.width;
g->height = info.height;
@@ -1176,12 +1176,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB);
} else {
qWarning("QFontEngine: Glyph rendered in unknown pixel_mode=%d", slot->bitmap.pixel_mode);
- return 0;
+ return nullptr;
}
if (!g) {
g = new Glyph;
- g->data = 0;
+ g->data = nullptr;
}
g->linearAdvance = info.linearAdvance;
@@ -1354,54 +1354,69 @@ static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix)
return m;
}
-QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
+QFontEngineFT::QGlyphSet *QFontEngineFT::TransformedGlyphSets::findSet(const QTransform &matrix, const QFontDef &fontDef)
{
- if (matrix.type() > QTransform::TxShear || !cacheEnabled)
- return 0;
-
- // FT_Set_Transform only supports scalable fonts
- if (!FT_IS_SCALABLE(freetype->face))
- return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : nullptr;
-
FT_Matrix m = QTransformToFTMatrix(matrix);
- QGlyphSet *gs = 0;
-
- for (int i = 0; i < transformedGlyphSets.count(); ++i) {
- const QGlyphSet &g = transformedGlyphSets.at(i);
- if (g.transformationMatrix.xx == m.xx
- && g.transformationMatrix.xy == m.xy
- && g.transformationMatrix.yx == m.yx
- && g.transformationMatrix.yy == m.yy) {
+ int i = 0;
+ for (; i < nSets; ++i) {
+ QGlyphSet *g = sets[i];
+ if (!g)
+ break;
+ if (g->transformationMatrix.xx == m.xx
+ && g->transformationMatrix.xy == m.xy
+ && g->transformationMatrix.yx == m.yx
+ && g->transformationMatrix.yy == m.yy) {
// found a match, move it to the front
- transformedGlyphSets.move(i, 0);
- gs = &transformedGlyphSets[0];
- break;
+ moveToFront(i);
+ return g;
}
}
- if (!gs) {
- // don't cache more than 10 transformations
- if (transformedGlyphSets.count() >= 10) {
- transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0);
- } else {
- transformedGlyphSets.prepend(QGlyphSet());
- }
- gs = &transformedGlyphSets[0];
- gs->clear();
- gs->transformationMatrix = m;
- gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.determinant()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
- }
- Q_ASSERT(gs != 0);
+ // don't cache more than nSets transformations
+ if (i == nSets)
+ // reuse the last set
+ --i;
+ moveToFront(nSets - 1);
+ if (!sets[0])
+ sets[0] = new QGlyphSet;
+ QGlyphSet *gs = sets[0];
+ gs->clear();
+ gs->transformationMatrix = m;
+ gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.determinant()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
+ Q_ASSERT(gs != nullptr);
return gs;
}
+void QFontEngineFT::TransformedGlyphSets::moveToFront(int i)
+{
+ QGlyphSet *g = sets[i];
+ while (i > 0) {
+ sets[i] = sets[i - 1];
+ --i;
+ }
+ sets[0] = g;
+}
+
+
+QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
+{
+ if (matrix.type() > QTransform::TxShear || !cacheEnabled)
+ return 0;
+
+ // FT_Set_Transform only supports scalable fonts
+ if (!FT_IS_SCALABLE(freetype->face))
+ return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : nullptr;
+
+ return transformedGlyphSets.findSet(matrix, fontDef);
+}
+
void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
{
FT_Face face = lockFace(Unscaled);
- FT_Set_Transform(face, 0, 0);
+ FT_Set_Transform(face, nullptr, nullptr);
FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
int left = face->glyph->metrics.horiBearingX;
@@ -1424,7 +1439,7 @@ void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_me
else
QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
- FT_Set_Transform(face, &freetype->matrix, 0);
+ FT_Set_Transform(face, &freetype->matrix, nullptr);
unlockFace();
}
@@ -1622,10 +1637,10 @@ glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, con
void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
{
- FT_Face face = 0;
+ FT_Face face = nullptr;
bool design = shouldUseDesignMetrics(flags);
for (int i = 0; i < glyphs->numGlyphs; i++) {
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs->glyphs[i]) : 0;
+ Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs->glyphs[i]) : nullptr;
// Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
if (g && g->format == acceptableFormat) {
@@ -1633,7 +1648,7 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
} else {
if (!face)
face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
+ g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs->glyphs[i], 0, Format_None, true);
if (g)
glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
else
@@ -1657,7 +1672,7 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
{
- FT_Face face = 0;
+ FT_Face face = nullptr;
glyph_metrics_t overall;
// initialize with line height, we get the same behaviour on all platforms
@@ -1672,11 +1687,11 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
QFixed ymax = 0;
QFixed xmax = 0;
for (int i = 0; i < glyphs.numGlyphs; i++) {
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : 0;
+ Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : nullptr;
if (!g) {
if (!face)
face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs.glyphs[i], 0, Format_None, true);
+ g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs.glyphs[i], 0, Format_None, true);
}
if (g) {
QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
@@ -1716,12 +1731,12 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
{
- FT_Face face = 0;
+ FT_Face face = nullptr;
glyph_metrics_t overall;
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : 0;
+ Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : nullptr;
if (!g) {
face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, 0, Format_None, true);
+ g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, 0, Format_None, true);
}
if (g) {
overall.x = g->x;
@@ -1854,10 +1869,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
bool disableOutlineDrawing)
{
QGlyphSet *glyphSet = loadGlyphSet(t);
- if (glyphSet != 0 && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox)
- return 0;
+ if (glyphSet != nullptr && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox)
+ return nullptr;
- Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
+ Glyph *glyph = glyphSet != nullptr ? glyphSet->getGlyph(g, subPixelPosition) : nullptr;
if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) {
QScopedValueRollback<HintStyle> saved_default_hint_style(default_hint_style);
if (t.type() >= QTransform::TxScale && !is2dRotation(t))
@@ -1865,7 +1880,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
lockFace();
FT_Matrix m = this->matrix;
- FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
+ FT_Matrix ftMatrix = glyphSet != nullptr ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
FT_Matrix_Multiply(&ftMatrix, &m);
freetype->matrix = m;
glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing);
@@ -1978,7 +1993,7 @@ FT_Face QFontEngineFT::lockFace(Scaling scale) const
freetype->matrix.xy != matrix.xy ||
freetype->matrix.yx != matrix.yx) {
freetype->matrix = matrix;
- FT_Set_Transform(face, &freetype->matrix, 0);
+ FT_Set_Transform(face, &freetype->matrix, nullptr);
}
return face;
@@ -2017,7 +2032,7 @@ void QFontEngineFT::QGlyphSet::clear()
for (int i = 0; i < 256; ++i) {
if (fast_glyph_data[i]) {
delete fast_glyph_data[i];
- fast_glyph_data[i] = 0;
+ fast_glyph_data[i] = nullptr;
}
}
fast_glyph_count = 0;
@@ -2031,7 +2046,7 @@ void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPix
if (useFastGlyphData(index, subPixelPosition)) {
if (fast_glyph_data[index]) {
delete fast_glyph_data[index];
- fast_glyph_data[index] = 0;
+ fast_glyph_data[index] = nullptr;
if (fast_glyph_count > 0)
--fast_glyph_count;
}
@@ -2056,7 +2071,7 @@ int QFontEngineFT::getPointInOutline(glyph_t glyph, int flags, quint32 point, QF
lockFace();
bool hsubpixel = true;
int vfactor = 1;
- int load_flags = loadFlags(0, Format_A8, flags, hsubpixel, vfactor);
+ int load_flags = loadFlags(nullptr, Format_A8, flags, hsubpixel, vfactor);
int result = freetype->getPointInOutline(glyph, load_flags, point, xpos, ypos, nPoints);
unlockFace();
return result;
@@ -2091,7 +2106,7 @@ QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
QFontEngineFT *fe = new QFontEngineFT(fontDef);
if (!fe->initFromFontEngine(this)) {
delete fe;
- return 0;
+ return nullptr;
} else {
return fe;
}
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
index 2e3aef6979..8019588bf5 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
@@ -63,6 +63,8 @@
#include <qmutex.h>
+#include <string.h>
+
QT_BEGIN_NAMESPACE
class QFontEngineFTRawFont;
@@ -170,6 +172,7 @@ public:
inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
private:
+ Q_DISABLE_COPY(QGlyphSet);
mutable QHash<GlyphAndSubPixelPosition, Glyph *> glyph_data; // maps from glyph index to glyph data
mutable QSet<glyph_t> missing_glyphs;
mutable Glyph *fast_glyph_data[256]; // for fast lookup of glyphs < 256
@@ -310,7 +313,18 @@ private:
GlyphFormat defaultFormat;
FT_Matrix matrix;
- QList<QGlyphSet> transformedGlyphSets;
+ struct TransformedGlyphSets {
+ enum { nSets = 10 };
+ QGlyphSet *sets[nSets];
+
+ QGlyphSet *findSet(const QTransform &matrix, const QFontDef &fontDef);
+ TransformedGlyphSets() { std::fill(&sets[0], &sets[nSets], nullptr); }
+ ~TransformedGlyphSets() { qDeleteAll(&sets[0], &sets[nSets]); }
+ private:
+ void moveToFront(int i);
+ Q_DISABLE_COPY(TransformedGlyphSets);
+ };
+ TransformedGlyphSets transformedGlyphSets;
mutable QGlyphSet defaultGlyphSet;
QFontEngine::FaceId face_id;
@@ -326,6 +340,9 @@ private:
QFixed scalableBitmapScaleFactor;
};
+Q_DECLARE_TYPEINFO(QFontEngineFT::QGlyphSet, Q_MOVABLE_TYPE);
+
+
inline uint qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g)
{
return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index daa3dc94ea..894919a1c8 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -374,17 +374,6 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine
QCFType<CTFontDescriptorRef> descriptor = QCFType<CTFontDescriptorRef>::constructFromGet(
static_cast<CTFontDescriptorRef>(usrPtr));
- // CoreText will sometimes invalidate information in font descriptors that refer
- // to system fonts in certain function calls or application states. While the descriptor
- // looks the same from the outside, some internal plumbing is different, causing the results
- // of creating CTFonts from those descriptors unreliable. The work-around for this
- // is to copy the attributes of those descriptors each time we make a new CTFont
- // from them instead of referring to the original, as that may trigger the CoreText bug.
- if (m_systemFontDescriptors.contains(descriptor)) {
- QCFType<CFDictionaryRef> attributes = CTFontDescriptorCopyAttributes(descriptor);
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- }
-
// Since we do not pass in the destination DPI to CoreText when making
// the font, we need to pass in a point size which is scaled to include
// the DPI. The default DPI for the screen is 72, thus the scale factor
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 072dd1a28a..30c80ebd86 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -471,7 +471,7 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt
const qreal firstY = positions[0].y.toReal();
for (int i = 0; i < glyphs.size(); ++i) {
cgPositions[i].x = positions[i].x.toReal() - firstX;
- cgPositions[i].y = positions[i].y.toReal() - firstY;
+ cgPositions[i].y = firstY - positions[i].y.toReal();
cgGlyphs[i] = glyphs[i];
}
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp
new file mode 100644
index 0000000000..5a1ff935b8
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirectwritefontdatabase_p.h"
+#include "qwindowsfontenginedirectwrite_p.h"
+
+#include <QtCore/qstringbuilder.h>
+#include <QtCore/qvarlengtharray.h>
+
+#include <dwrite_3.h>
+#include <d2d1.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_USE_DIRECTWRITE3
+
+QWindowsDirectWriteFontDatabase::QWindowsDirectWriteFontDatabase()
+{
+ qCDebug(lcQpaFonts) << "Creating DirectWrite database";
+}
+
+QWindowsDirectWriteFontDatabase::~QWindowsDirectWriteFontDatabase()
+{
+ for (auto it = m_populatedFonts.begin(); it != m_populatedFonts.end(); ++it)
+ it.value()->Release();
+}
+
+QString QWindowsDirectWriteFontDatabase::localeString(IDWriteLocalizedStrings *names,
+ wchar_t localeName[])
+{
+ uint index;
+ BOOL exists;
+ if (SUCCEEDED(names->FindLocaleName(localeName, &index, &exists)) && exists) {
+ uint length;
+ if (SUCCEEDED(names->GetStringLength(index, &length)) && length > 0) {
+ QVarLengthArray<wchar_t> buffer(int(length) + 1);
+ if (SUCCEEDED(names->GetString(index, buffer.data(), length + 1)))
+ return QString::fromWCharArray(buffer.data());
+ }
+ }
+
+ return QString();
+}
+
+static QFont::Stretch fromDirectWriteStretch(DWRITE_FONT_STRETCH stretch)
+{
+ switch (stretch) {
+ case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: return QFont::UltraCondensed;
+ case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: return QFont::ExtraCondensed;
+ case DWRITE_FONT_STRETCH_CONDENSED: return QFont::Condensed;
+ case DWRITE_FONT_STRETCH_SEMI_CONDENSED: return QFont::SemiCondensed;
+ case DWRITE_FONT_STRETCH_NORMAL: return QFont::Unstretched;
+ case DWRITE_FONT_STRETCH_SEMI_EXPANDED: return QFont::SemiExpanded;
+ case DWRITE_FONT_STRETCH_EXPANDED: return QFont::Expanded;
+ case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: return QFont::ExtraExpanded;
+ case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: return QFont::UltraExpanded;
+ default: return QFont::AnyStretch;
+ }
+}
+
+static QFont::Weight fromDirectWriteWeight(DWRITE_FONT_WEIGHT weight)
+{
+ return QPlatformFontDatabase::weightFromInteger(int(weight));
+}
+
+static DWRITE_FONT_STYLE toDirectWriteStyle(QFont::Style style)
+{
+ switch (style) {
+ case QFont::StyleNormal: return DWRITE_FONT_STYLE_NORMAL;
+ case QFont::StyleOblique: return DWRITE_FONT_STYLE_OBLIQUE;
+ case QFont::StyleItalic: return DWRITE_FONT_STYLE_ITALIC;
+ default: return DWRITE_FONT_STYLE_NORMAL;
+ }
+}
+
+static QFont::Style fromDirectWriteStyle(DWRITE_FONT_STYLE style)
+{
+ switch (style) {
+ case DWRITE_FONT_STYLE_NORMAL: return QFont::StyleNormal;
+ case DWRITE_FONT_STYLE_OBLIQUE: return QFont::StyleOblique;
+ case DWRITE_FONT_STYLE_ITALIC: return QFont::StyleItalic;
+ default: return QFont::StyleNormal;
+ }
+}
+
+void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
+{
+ auto it = m_populatedFonts.find(familyName);
+ IDWriteFontFamily *fontFamily = it != m_populatedFonts.end() ? it.value() : nullptr;
+ if (fontFamily == nullptr) {
+ qCWarning(lcQpaFonts) << "Cannot find" << familyName << "in list of fonts";
+ return;
+ }
+
+ qCDebug(lcQpaFonts) << "Populate family:" << familyName;
+
+ wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
+ bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
+ wchar_t englishLocale[] = L"en-us";
+
+ static const int SMOOTH_SCALABLE = 0xffff;
+ const QString foundryName; // No such concept.
+ const bool scalable = true;
+ const bool antialias = false;
+ const int size = SMOOTH_SCALABLE;
+
+ IDWriteFontList *matchingFonts;
+ if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR,
+ DWRITE_FONT_STRETCH_NORMAL,
+ DWRITE_FONT_STYLE_NORMAL,
+ &matchingFonts))) {
+ for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) {
+ IDWriteFont *font;
+ if (SUCCEEDED(matchingFonts->GetFont(j, &font))) {
+ IDWriteFont1 *font1 = nullptr;
+ if (!SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1),
+ reinterpret_cast<void **>(&font1)))) {
+ qCWarning(lcQpaFonts) << "COM object does not support IDWriteFont1";
+ continue;
+ }
+
+ QString defaultLocaleFamilyName;
+ QString englishLocaleFamilyName;
+
+ IDWriteFontFamily *fontFamily2;
+ if (SUCCEEDED(font1->GetFontFamily(&fontFamily2))) {
+ IDWriteLocalizedStrings *names;
+ if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) {
+ defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleFamilyName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ fontFamily2->Release();
+ }
+
+ if (defaultLocaleFamilyName.isEmpty() && englishLocaleFamilyName.isEmpty())
+ englishLocaleFamilyName = familyName;
+
+ QVarLengthArray<DWRITE_UNICODE_RANGE, 64> ranges(QFontDatabase::WritingSystemsCount);
+
+ uint count = 0;
+ if (SUCCEEDED(font1->GetUnicodeRanges(QFontDatabase::WritingSystemsCount, ranges.data(), &count))) {
+ // ###
+ }
+ QSupportedWritingSystems writingSystems;
+ writingSystems.setSupported(QFontDatabase::Any);
+ writingSystems.setSupported(QFontDatabase::Latin);
+
+ {
+ IDWriteLocalizedStrings *names;
+ if (SUCCEEDED(font1->GetFaceNames(&names))) {
+ QString defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ QString englishLocaleStyleName = localeString(names, englishLocale);
+
+ QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch());
+ QFont::Style style = fromDirectWriteStyle(font1->GetStyle());
+ QFont::Weight weight = fromDirectWriteWeight(font1->GetWeight());
+ bool fixed = font1->IsMonospacedFont();
+
+ qCDebug(lcQpaFonts) << "Family" << familyName << "has english variant" << englishLocaleStyleName << ", in default locale:" << defaultLocaleStyleName << stretch << style << weight << fixed;
+
+ IDWriteFontFace *face = nullptr;
+ if (SUCCEEDED(font->CreateFontFace(&face))) {
+ if (!englishLocaleStyleName.isEmpty() || defaultLocaleStyleName.isEmpty()) {
+ QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
+ face->AddRef();
+ }
+
+ if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
+ QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
+ face->AddRef();
+ }
+
+ face->Release();
+ }
+
+ names->Release();
+ }
+ }
+
+ font1->Release();
+ font->Release();
+ }
+ }
+
+ matchingFonts->Release();
+ }
+}
+
+QFontEngine *QWindowsDirectWriteFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
+{
+ IDWriteFontFace *face = reinterpret_cast<IDWriteFontFace *>(handle);
+ Q_ASSERT(face != nullptr);
+
+ QWindowsFontEngineDirectWrite *fontEngine = new QWindowsFontEngineDirectWrite(face, fontDef.pixelSize, data());
+ fontEngine->initFontInfo(fontDef, defaultVerticalDPI());
+
+ return fontEngine;
+}
+
+QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+{
+ Q_UNUSED(styleHint);
+ Q_UNUSED(script);
+
+ wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
+ bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
+ wchar_t englishLocale[] = L"en-us";
+
+ QStringList ret;
+
+ auto it = m_populatedFonts.find(family);
+ IDWriteFontFamily *fontFamily = it != m_populatedFonts.end() ? it.value() : nullptr;
+ if (fontFamily != nullptr) {
+ IDWriteFontList *matchingFonts = nullptr;
+ if (SUCCEEDED(fontFamily->GetMatchingFonts(DWRITE_FONT_WEIGHT_REGULAR,
+ DWRITE_FONT_STRETCH_NORMAL,
+ toDirectWriteStyle(style),
+ &matchingFonts))) {
+ for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) {
+ IDWriteFont *font = nullptr;
+ if (SUCCEEDED(matchingFonts->GetFont(j, &font))) {
+ IDWriteFontFamily *fontFamily2;
+ if (SUCCEEDED(font->GetFontFamily(&fontFamily2))) {
+ IDWriteLocalizedStrings *names;
+ if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) {
+ QString name = localeString(names, englishLocale);
+ if (name.isEmpty() && hasDefaultLocale)
+ name = localeString(names, defaultLocale);
+
+ if (!name.isEmpty() && m_populatedFonts.contains(name))
+ ret.append(name);
+
+ names->Release();
+ }
+
+ fontFamily2->Release();
+ }
+
+ font->Release();
+ }
+ }
+
+ matchingFonts->Release();
+ }
+ }
+
+ qDebug(lcQpaFonts) << "fallbacks for" << family << "is" << ret;
+
+ return ret;
+}
+
+QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ qCDebug(lcQpaFonts) << "Adding application font" << fileName;
+
+ QByteArray loadedData = fontData;
+ if (loadedData.isEmpty()) {
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCWarning(lcQpaFonts) << "Cannot open" << fileName << "for reading.";
+ return QStringList();
+ }
+ loadedData = file.readAll();
+ }
+
+ IDWriteFontFace *face = createDirectWriteFace(loadedData);
+ if (face == nullptr) {
+ qCWarning(lcQpaFonts) << "Failed to create DirectWrite face from font data. Font may be unsupported.";
+ return QStringList();
+ }
+
+ wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
+ bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
+ wchar_t englishLocale[] = L"en-us";
+
+ static const int SMOOTH_SCALABLE = 0xffff;
+ const QString foundryName; // No such concept.
+ const bool scalable = true;
+ const bool antialias = false;
+ const int size = SMOOTH_SCALABLE;
+
+ QSupportedWritingSystems writingSystems;
+ writingSystems.setSupported(QFontDatabase::Any);
+ writingSystems.setSupported(QFontDatabase::Latin);
+
+ QStringList ret;
+ IDWriteFontFace3 *face3 = nullptr;
+ if (SUCCEEDED(face->QueryInterface(__uuidof(IDWriteFontFace3),
+ reinterpret_cast<void **>(&face3)))) {
+ QString defaultLocaleFamilyName;
+ QString englishLocaleFamilyName;
+
+ IDWriteLocalizedStrings *names;
+ if (SUCCEEDED(face3->GetFamilyNames(&names))) {
+ defaultLocaleFamilyName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleFamilyName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ QString defaultLocaleStyleName;
+ QString englishLocaleStyleName;
+ if (SUCCEEDED(face3->GetFaceNames(&names))) {
+ defaultLocaleStyleName = hasDefaultLocale ? localeString(names, defaultLocale) : QString();
+ englishLocaleStyleName = localeString(names, englishLocale);
+
+ names->Release();
+ }
+
+ QFont::Stretch stretch = fromDirectWriteStretch(face3->GetStretch());
+ QFont::Style style = fromDirectWriteStyle(face3->GetStyle());
+ QFont::Weight weight = fromDirectWriteWeight(face3->GetWeight());
+ bool fixed = face3->IsMonospacedFont();
+
+ qCDebug(lcQpaFonts) << "\tFont names:" << englishLocaleFamilyName << ", " << defaultLocaleFamilyName
+ << ", style names:" << englishLocaleStyleName << ", " << defaultLocaleStyleName
+ << ", stretch:" << stretch
+ << ", style:" << style
+ << ", weight:" << weight
+ << ", fixed:" << fixed;
+
+ if (!englishLocaleFamilyName.isEmpty()) {
+ ret.append(englishLocaleFamilyName);
+ QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
+ face->AddRef();
+ }
+
+ if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
+ ret.append(defaultLocaleFamilyName);
+ QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
+ face->AddRef();
+ }
+
+ face3->Release();
+ } else {
+ qCWarning(lcQpaFonts) << "Unable to query IDWriteFontFace3 interface from font face.";
+ }
+
+ face->Release();
+
+ return ret;
+}
+
+void QWindowsDirectWriteFontDatabase::releaseHandle(void *handle)
+{
+ IDWriteFontFace *face = reinterpret_cast<IDWriteFontFace *>(handle);
+ face->Release();
+}
+
+bool QWindowsDirectWriteFontDatabase::fontsAlwaysScalable() const
+{
+ return true;
+}
+
+bool QWindowsDirectWriteFontDatabase::isPrivateFontFamily(const QString &family) const
+{
+ Q_UNUSED(family);
+ return false;
+}
+
+void QWindowsDirectWriteFontDatabase::populateFontDatabase()
+{
+ wchar_t defaultLocale[LOCALE_NAME_MAX_LENGTH];
+ bool hasDefaultLocale = GetUserDefaultLocaleName(defaultLocale, LOCALE_NAME_MAX_LENGTH) != 0;
+ wchar_t englishLocale[] = L"en-us";
+
+ QString defaultFontName = defaultFont().family();
+ QString systemDefaultFontName = systemDefaultFont().family();
+
+ IDWriteFontCollection *fontCollection;
+ if (SUCCEEDED(data()->directWriteFactory->GetSystemFontCollection(&fontCollection))) {
+ for (uint i = 0; i < fontCollection->GetFontFamilyCount(); ++i) {
+ IDWriteFontFamily *fontFamily;
+ if (SUCCEEDED(fontCollection->GetFontFamily(i, &fontFamily))) {
+ QString defaultLocaleName;
+ QString englishLocaleName;
+
+ IDWriteLocalizedStrings *names;
+ if (SUCCEEDED(fontFamily->GetFamilyNames(&names))) {
+ if (hasDefaultLocale)
+ defaultLocaleName = localeString(names, defaultLocale);
+
+ englishLocaleName = localeString(names, englishLocale);
+ }
+
+ qCDebug(lcQpaFonts) << "Registering font, english name = " << englishLocaleName << ", name in current locale = " << defaultLocaleName;
+ if (!defaultLocaleName.isEmpty()) {
+ registerFontFamily(defaultLocaleName);
+ m_populatedFonts.insert(defaultLocaleName, fontFamily);
+ fontFamily->AddRef();
+
+ if (defaultLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
+ qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << defaultLocaleName;
+
+ m_populatedFonts.insert(systemDefaultFontName, fontFamily);
+ fontFamily->AddRef();
+ }
+ }
+
+ if (!englishLocaleName.isEmpty() && englishLocaleName != defaultLocaleName) {
+ registerFontFamily(englishLocaleName);
+ m_populatedFonts.insert(englishLocaleName, fontFamily);
+ fontFamily->AddRef();
+
+ if (englishLocaleName == defaultFontName && defaultFontName != systemDefaultFontName) {
+ qDebug(lcQpaFonts) << "Adding default font" << systemDefaultFontName << "as alternative to" << englishLocaleName;
+
+ m_populatedFonts.insert(systemDefaultFontName, fontFamily);
+ fontFamily->AddRef();
+ }
+ }
+
+ fontFamily->Release();
+ }
+ }
+ }
+}
+
+QFont QWindowsDirectWriteFontDatabase::defaultFont() const
+{
+ return QFont(QStringLiteral("Segoe UI"));
+}
+
+#endif // QT_USE_DIRECTWRITE3
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase_p.h
new file mode 100644
index 0000000000..2110043df6
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECTWRITEFONTDATABASE_P_H
+#define QWINDOWSDIRECTWRITEFONTDATABASE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsfontdatabasebase_p.h"
+
+#include <qpa/qplatformfontdatabase.h>
+#include <QtCore/qloggingcategory.h>
+
+struct IDWriteFactory;
+struct IDWriteFont;
+struct IDWriteFontFamily;
+struct IDWriteLocalizedStrings;
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_USE_DIRECTWRITE3
+
+class QWindowsDirectWriteFontDatabase : public QWindowsFontDatabaseBase
+{
+ Q_DISABLE_COPY_MOVE(QWindowsDirectWriteFontDatabase)
+public:
+ QWindowsDirectWriteFontDatabase();
+ ~QWindowsDirectWriteFontDatabase() override;
+
+ void populateFontDatabase() override;
+ void populateFamily(const QString &familyName) override;
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
+ void releaseHandle(void *handle) override;
+ QFont defaultFont() const override;
+
+ bool fontsAlwaysScalable() const override;
+ bool isPrivateFontFamily(const QString &family) const override;
+
+private:
+ static QString localeString(IDWriteLocalizedStrings *names, wchar_t localeName[]);
+
+ QHash<QString, IDWriteFontFamily *> m_populatedFonts;
+};
+
+#endif // QT_USE_DIRECTWRITE3
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECTWRITEFONTDATABASE_P_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index 011476cf13..cf5763fdbe 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -51,7 +51,6 @@
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QtEndian>
-#include <QtCore/QThreadStorage>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtCore/private/qwinregistry_p.h>
@@ -64,6 +63,7 @@
# include <dwrite.h>
# endif
# include <d2d1.h>
+# include "qwindowsdirectwritefontdatabase_p.h"
#endif
QT_BEGIN_NAMESPACE
@@ -75,40 +75,6 @@ Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
typedef HRESULT (WINAPI *DWriteCreateFactoryType)(DWRITE_FACTORY_TYPE, const IID &, IUnknown **);
-static inline DWriteCreateFactoryType resolveDWriteCreateFactory()
-{
- QSystemLibrary library(QStringLiteral("dwrite"));
- QFunctionPointer result = library.resolve("DWriteCreateFactory");
- if (Q_UNLIKELY(!result)) {
- qWarning("Unable to load dwrite.dll");
- return nullptr;
- }
- return reinterpret_cast<DWriteCreateFactoryType>(result);
-}
-
-static void createDirectWriteFactory(IDWriteFactory **factory)
-{
- *factory = nullptr;
-
- static const DWriteCreateFactoryType dWriteCreateFactory = resolveDWriteCreateFactory();
- if (!dWriteCreateFactory)
- return;
-
- IUnknown *result = NULL;
-#if defined(QT_USE_DIRECTWRITE2)
- dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), &result);
-#endif
-
- if (result == NULL) {
- if (FAILED(dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &result))) {
- qErrnoWarning("DWriteCreateFactory failed");
- return;
- }
- }
-
- *factory = static_cast<IDWriteFactory *>(result);
-}
-
static inline bool useDirectWrite(QFont::HintingPreference hintingPreference,
const QString &familyName = QString(),
bool isColorFont = false)
@@ -131,459 +97,6 @@ static inline bool useDirectWrite(QFont::HintingPreference hintingPreference,
}
#endif // !QT_NO_DIRECTWRITE
-// Helper classes for creating font engines directly from font data
-namespace {
-
-# pragma pack(1)
-
- // Common structure for all formats of the "name" table
- struct NameTable
- {
- quint16 format;
- quint16 count;
- quint16 stringOffset;
- };
-
- struct NameRecord
- {
- quint16 platformID;
- quint16 encodingID;
- quint16 languageID;
- quint16 nameID;
- quint16 length;
- quint16 offset;
- };
-
- struct OffsetSubTable
- {
- quint32 scalerType;
- quint16 numTables;
- quint16 searchRange;
- quint16 entrySelector;
- quint16 rangeShift;
- };
-
- struct TableDirectory
- {
- quint32 identifier;
- quint32 checkSum;
- quint32 offset;
- quint32 length;
- };
-
- struct OS2Table
- {
- quint16 version;
- qint16 avgCharWidth;
- quint16 weightClass;
- quint16 widthClass;
- quint16 type;
- qint16 subscriptXSize;
- qint16 subscriptYSize;
- qint16 subscriptXOffset;
- qint16 subscriptYOffset;
- qint16 superscriptXSize;
- qint16 superscriptYSize;
- qint16 superscriptXOffset;
- qint16 superscriptYOffset;
- qint16 strikeOutSize;
- qint16 strikeOutPosition;
- qint16 familyClass;
- quint8 panose[10];
- quint32 unicodeRanges[4];
- quint8 vendorID[4];
- quint16 selection;
- quint16 firstCharIndex;
- quint16 lastCharIndex;
- qint16 typoAscender;
- qint16 typoDescender;
- qint16 typoLineGap;
- quint16 winAscent;
- quint16 winDescent;
- quint32 codepageRanges[2];
- qint16 height;
- qint16 capHeight;
- quint16 defaultChar;
- quint16 breakChar;
- quint16 maxContext;
- };
-
-# pragma pack()
-
- class EmbeddedFont
- {
- public:
- EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
-
- QString changeFamilyName(const QString &newFamilyName);
- QByteArray data() const { return m_fontData; }
- TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
- QString familyName(TableDirectory *nameTableDirectory = 0);
-
- private:
- QByteArray m_fontData;
- };
-
- TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
- {
- Q_ASSERT(tagName.size() == 4);
- quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
- const size_t fontDataSize = m_fontData.size();
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable)))
- return 0;
-
- OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
- TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
-
- const size_t tableCount = qFromBigEndian<quint16>(offsetSubTable->numTables);
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount))
- return 0;
-
- TableDirectory *tableDirectoryEnd = tableDirectory + tableCount;
- for (TableDirectory *entry = tableDirectory; entry < tableDirectoryEnd; ++entry) {
- if (entry->identifier == tagId)
- return entry;
- }
-
- return 0;
- }
-
- QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
- {
- QString name;
-
- if (nameTableDirectoryEntry == 0)
- nameTableDirectoryEntry = tableDirectoryEntry("name");
-
- if (nameTableDirectoryEntry != 0) {
- quint32 offset = qFromBigEndian<quint32>(nameTableDirectoryEntry->offset);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable)))
- return QString();
-
- NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() + offset);
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
-
- quint16 nameTableCount = qFromBigEndian<quint16>(nameTable->count);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount))
- return QString();
-
- for (int i = 0; i < nameTableCount; ++i, ++nameRecord) {
- if (qFromBigEndian<quint16>(nameRecord->nameID) == 1
- && qFromBigEndian<quint16>(nameRecord->platformID) == 3 // Windows
- && qFromBigEndian<quint16>(nameRecord->languageID) == 0x0409) { // US English
- quint16 stringOffset = qFromBigEndian<quint16>(nameTable->stringOffset);
- quint16 nameOffset = qFromBigEndian<quint16>(nameRecord->offset);
- quint16 nameLength = qFromBigEndian<quint16>(nameRecord->length);
-
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength))
- return QString();
-
- const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
- + stringOffset
- + nameOffset;
-
- const quint16 *s = reinterpret_cast<const quint16 *>(ptr);
- const quint16 *e = s + nameLength / sizeof(quint16);
- while (s != e)
- name += QChar( qFromBigEndian<quint16>(*s++));
- break;
- }
- }
- }
-
- return name;
- }
-
- QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
- {
- TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
- if (nameTableDirectoryEntry == 0)
- return QString();
-
- QString oldFamilyName = familyName(nameTableDirectoryEntry);
-
- // Reserve size for name table header, five required name records and string
- const int requiredRecordCount = 5;
- quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
-
- int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
- int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16));
-
- const QString regularString = QString::fromLatin1("Regular");
- int regularStringSize = regularString.size() * int(sizeof(quint16));
-
- // Align table size of table to 32 bits (pad with 0)
- int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
-
- QByteArray newNameTable(fullSize, char(0));
-
- {
- NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
- nameTable->count = qbswap<quint16>(requiredRecordCount);
- nameTable->stringOffset = qbswap<quint16>(sizeOfHeader);
-
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i = 0; i < requiredRecordCount; ++i, nameRecord++) {
- nameRecord->nameID = qbswap<quint16>(nameIds[i]);
- nameRecord->encodingID = qbswap<quint16>(1);
- nameRecord->languageID = qbswap<quint16>(0x0409);
- nameRecord->platformID = qbswap<quint16>(3);
- nameRecord->length = qbswap<quint16>(newFamilyNameSize);
-
- // Special case for sub-family
- if (nameIds[i] == 4) {
- nameRecord->offset = qbswap<quint16>(newFamilyNameSize);
- nameRecord->length = qbswap<quint16>(regularStringSize);
- }
- }
-
- // nameRecord now points to string data
- quint16 *stringStorage = reinterpret_cast<quint16 *>(nameRecord);
- const quint16 *sourceString = newFamilyName.utf16();
- for (int i = 0; i < newFamilyName.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- stringStorage += newFamilyName.size();
-
- sourceString = regularString.utf16();
- for (int i = 0; i < regularString.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- }
-
- quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
- quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
-
- quint32 checkSum = 0;
- while (p < tableEnd)
- checkSum += qFromBigEndian<quint32>(*(p++));
-
- nameTableDirectoryEntry->checkSum = qbswap<quint32>(checkSum);
- nameTableDirectoryEntry->offset = qbswap<quint32>(m_fontData.size());
- nameTableDirectoryEntry->length = qbswap<quint32>(fullSize);
-
- m_fontData.append(newNameTable);
-
- return oldFamilyName;
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
-
- class DirectWriteFontFileStream: public IDWriteFontFileStream
- {
- Q_DISABLE_COPY(DirectWriteFontFileStream)
- public:
- DirectWriteFontFileStream(const QByteArray &fontData)
- : m_fontData(fontData)
- , m_referenceCount(0)
- {
- }
- virtual ~DirectWriteFontFileStream()
- {
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
- UINT64 fragmentSize, OUT void **fragmentContext);
- void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
- HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
- HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
-
- private:
- QByteArray m_fontData;
- ULONG m_referenceCount;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
- const void **fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void **fragmentContext)
- {
- *fragmentContext = NULL;
- if (fileOffset + fragmentSize <= quint64(m_fontData.size())) {
- *fragmentStart = m_fontData.data() + fileOffset;
- return S_OK;
- } else {
- *fragmentStart = NULL;
- return E_FAIL;
- }
- }
-
- void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
- {
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
- {
- *fileSize = m_fontData.size();
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
- {
- *lastWriteTime = 0;
- return E_NOTIMPL;
- }
-
- class DirectWriteFontFileLoader: public IDWriteFontFileLoader
- {
- public:
- DirectWriteFontFileLoader() : m_referenceCount(0) {}
- virtual ~DirectWriteFontFileLoader()
- {
- }
-
- inline void addKey(const void *key, const QByteArray &fontData)
- {
- Q_ASSERT(!m_fontDatas.contains(key));
- m_fontDatas.insert(key, fontData);
- }
-
- inline void removeKey(const void *key)
- {
- m_fontDatas.remove(key);
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- OUT IDWriteFontFileStream **fontFileStream);
-
- private:
- ULONG m_referenceCount;
- QHash<const void *, QByteArray> m_fontDatas;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
- void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
- void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- IDWriteFontFileStream **fontFileStream)
- {
- Q_UNUSED(fontFileReferenceKeySize);
-
- if (fontFileReferenceKeySize != sizeof(const void *)) {
- qWarning("%s: Wrong key size", __FUNCTION__);
- return E_FAIL;
- }
-
- const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
- *fontFileStream = NULL;
- auto it = m_fontDatas.constFind(key);
- if (it == m_fontDatas.constEnd())
- return E_FAIL;
-
- QByteArray fontData = it.value();
- DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
- stream->AddRef();
- *fontFileStream = stream;
-
- return S_OK;
- }
-
- class CustomFontFileLoader
- {
- public:
- CustomFontFileLoader() : m_directWriteFontFileLoader(nullptr)
- {
- createDirectWriteFactory(&m_directWriteFactory);
-
- if (m_directWriteFactory) {
- m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
- m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
- }
- }
-
- ~CustomFontFileLoader()
- {
- if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0)
- m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
-
- if (m_directWriteFactory != 0)
- m_directWriteFactory->Release();
- }
-
- void addKey(const void *key, const QByteArray &fontData)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->addKey(key, fontData);
- }
-
- void removeKey(const void *key)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->removeKey(key);
- }
-
- IDWriteFontFileLoader *loader() const
- {
- return m_directWriteFontFileLoader;
- }
-
- private:
- IDWriteFactory *m_directWriteFactory;
- DirectWriteFontFileLoader *m_directWriteFontFileLoader;
- };
-
-#endif
-
-} // Anonymous namespace
-
/*!
\struct QWindowsFontEngineData
\brief Static constant data shared by the font engines.
@@ -620,18 +133,6 @@ unsigned QWindowsFontDatabase::fontOptions()
return m_fontOptions;
}
-QWindowsFontEngineData::~QWindowsFontEngineData()
-{
- if (hdc)
- DeleteDC(hdc);
-#if !defined(QT_NO_DIRECTWRITE)
- if (directWriteGdiInterop)
- directWriteGdiInterop->Release();
- if (directWriteFactory)
- directWriteFactory->Release();
-#endif
-}
-
qreal QWindowsFontDatabase::fontSmoothingGamma()
{
int winSmooth;
@@ -645,26 +146,6 @@ qreal QWindowsFontDatabase::fontSmoothingGamma()
return result;
}
-#if !defined(QT_NO_DIRECTWRITE)
-static inline bool initDirectWrite(QWindowsFontEngineData *d)
-{
- if (!d->directWriteFactory) {
- createDirectWriteFactory(&d->directWriteFactory);
- if (!d->directWriteFactory)
- return false;
- }
- if (!d->directWriteGdiInterop) {
- const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
- if (FAILED(hr)) {
- qErrnoWarning("%s: GetGdiInterop failed", __FUNCTION__);
- return false;
- }
- }
- return true;
-}
-
-#endif // !defined(QT_NO_DIRECTWRITE)
-
/*!
\class QWindowsFontDatabase
\brief Font database for Windows
@@ -1069,18 +550,16 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyName;
QString subFamilyStyle;
- if (ttf) {
- // Look-up names registered in the font
- QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
- if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
- englishName = canonicalNames.name;
- if (!canonicalNames.preferredName.isEmpty()) {
- subFamilyName = familyName;
- subFamilyStyle = styleName;
- faceName = familyName; // Remember the original name for later lookups
- familyName = canonicalNames.preferredName;
- styleName = canonicalNames.preferredStyle;
- }
+ // Look-up names registered in the font
+ QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
+ if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
+ englishName = canonicalNames.name;
+ if (!canonicalNames.preferredName.isEmpty()) {
+ subFamilyName = familyName;
+ subFamilyStyle = styleName;
+ faceName = familyName; // Remember the original name for later lookups
+ familyName = canonicalNames.preferredName;
+ styleName = canonicalNames.preferredStyle;
}
QSupportedWritingSystems writingSystems;
@@ -1241,20 +720,6 @@ void QWindowsFontDatabase::populateFontDatabase()
addDefaultEUDCFont();
}
-typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
-
-typedef QThreadStorage<QWindowsFontEngineDataPtr> FontEngineThreadLocalData;
-
-Q_GLOBAL_STATIC(FontEngineThreadLocalData, fontEngineThreadLocalData)
-
-QSharedPointer<QWindowsFontEngineData> sharedFontData()
-{
- FontEngineThreadLocalData *data = fontEngineThreadLocalData();
- if (!data->hasLocalData())
- data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create());
- return data->localData();
-}
-
QWindowsFontDatabase::QWindowsFontDatabase()
{
// Properties accessed by QWin32PrintEngine (Qt Print Support)
@@ -1264,9 +729,9 @@ QWindowsFontDatabase::QWindowsFontDatabase()
Q_UNUSED(logFontMetaTypeId)
if (lcQpaFonts().isDebugEnabled()) {
- const QWindowsFontEngineDataPtr data = sharedFontData();
+ QSharedPointer<QWindowsFontEngineData> d = data();
qCDebug(lcQpaFonts) << __FUNCTION__ << "Clear type: "
- << data->clearTypeEnabled << "gamma: " << data->fontSmoothingGamma;
+ << d->clearTypeEnabled << "gamma: " << d->fontSmoothingGamma;
}
}
@@ -1280,7 +745,7 @@ QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *ha
const QString faceName(static_cast<const QChar*>(handle));
QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef, faceName,
defaultVerticalDPI(),
- sharedFontData());
+ data());
qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle;
return fe;
}
@@ -1334,7 +799,7 @@ QT_WARNING_POP
fontEngine = QWindowsFontDatabase::createEngine(request, QString(),
defaultVerticalDPI(),
- sharedFontData());
+ data());
if (fontEngine) {
if (request.family != fontEngine->fontDef.family) {
@@ -1373,87 +838,17 @@ QT_WARNING_POP
RemoveFontMemResourceEx(fontHandle);
}
}
+
+ // Get style and weight info
+ if (fontEngine != nullptr)
+ font.updateFromOS2Table(fontEngine);
}
#if !defined(QT_NO_DIRECTWRITE)
else {
- CustomFontFileLoader fontFileLoader;
- fontFileLoader.addKey(this, fontData);
-
- QSharedPointer<QWindowsFontEngineData> fontEngineData = sharedFontData();
- if (!initDirectWrite(fontEngineData.data()))
- return 0;
-
- IDWriteFontFile *fontFile = 0;
- void *key = this;
-
- HRESULT hres = fontEngineData->directWriteFactory->CreateCustomFontFileReference(&key,
- sizeof(void *),
- fontFileLoader.loader(),
- &fontFile);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "%s: CreateCustomFontFileReference failed", __FUNCTION__);
- return 0;
- }
-
- BOOL isSupportedFontType;
- DWRITE_FONT_FILE_TYPE fontFileType;
- DWRITE_FONT_FACE_TYPE fontFaceType;
- UINT32 numberOfFaces;
- fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
- if (!isSupportedFontType) {
- fontFile->Release();
- return 0;
- }
-
- IDWriteFontFace *directWriteFontFace = 0;
- hres = fontEngineData->directWriteFactory->CreateFontFace(fontFaceType,
- 1,
- &fontFile,
- 0,
- DWRITE_FONT_SIMULATIONS_NONE,
- &directWriteFontFace);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "%s: CreateFontFace failed", __FUNCTION__);
- fontFile->Release();
- return 0;
- }
-
- fontFile->Release();
-
- fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace,
- pixelSize,
- fontEngineData);
-
- // Get font family from font data
- fontEngine->fontDef.family = font.familyName();
- fontEngine->fontDef.hintingPreference = hintingPreference;
-
- directWriteFontFace->Release();
+ fontEngine = QWindowsFontDatabaseBase::fontEngine(fontData, pixelSize, hintingPreference);
}
#endif
- // Get style and weight info
- if (fontEngine != 0) {
- TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2");
- if (os2TableEntry != 0) {
- const OS2Table *os2Table =
- reinterpret_cast<const OS2Table *>(fontData.constData()
- + qFromBigEndian<quint32>(os2TableEntry->offset));
-
- bool italic = qFromBigEndian<quint16>(os2Table->selection) & (1 << 0);
- bool oblique = qFromBigEndian<quint16>(os2Table->selection) & (1 << 9);
-
- if (italic)
- fontEngine->fontDef.style = QFont::StyleItalic;
- else if (oblique)
- fontEngine->fontDef.style = QFont::StyleOblique;
- else
- fontEngine->fontDef.style = QFont::StyleNormal;
-
- fontEngine->fontDef.weight = QPlatformFontDatabase::weightFromInteger(qFromBigEndian<quint16>(os2Table->weightClass));
- }
- }
-
qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
return fontEngine;
}
@@ -1685,14 +1080,6 @@ void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
m_uniqueFontData[uniqueFont].refCount.ref();
}
-// ### fixme Qt 6 (QTBUG-58610): See comment at QWindowsFontDatabase::systemDefaultFont()
-HFONT QWindowsFontDatabase::systemFont()
-{
- static const auto stock_sysfont =
- reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
- return stock_sysfont;
-}
-
// Creation functions
static const char *other_tryFonts[] = {
@@ -1747,101 +1134,6 @@ static const char *kr_tryFonts[] = {
static const char **tryFonts = 0;
-LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request, const QString &faceName)
-{
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
-
- lf.lfHeight = -qRound(request.pixelSize);
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- if (request.weight == 50)
- lf.lfWeight = FW_DONTCARE;
- else
- lf.lfWeight = (request.weight*900)/99;
- lf.lfItalic = request.style != QFont::StyleNormal;
- lf.lfCharSet = DEFAULT_CHARSET;
-
- int strat = OUT_DEFAULT_PRECIS;
- if (request.styleStrategy & QFont::PreferBitmap) {
- strat = OUT_RASTER_PRECIS;
- } else if (request.styleStrategy & QFont::PreferDevice) {
- strat = OUT_DEVICE_PRECIS;
- } else if (request.styleStrategy & QFont::PreferOutline) {
- strat = OUT_OUTLINE_PRECIS;
- } else if (request.styleStrategy & QFont::ForceOutline) {
- strat = OUT_TT_ONLY_PRECIS;
- }
-
- lf.lfOutPrecision = strat;
-
- int qual = DEFAULT_QUALITY;
-
- if (request.styleStrategy & QFont::PreferMatch)
- qual = DRAFT_QUALITY;
- else if (request.styleStrategy & QFont::PreferQuality)
- qual = PROOF_QUALITY;
-
- if (request.styleStrategy & QFont::PreferAntialias) {
- qual = (request.styleStrategy & QFont::NoSubpixelAntialias) == 0
- ? CLEARTYPE_QUALITY : ANTIALIASED_QUALITY;
- } else if (request.styleStrategy & QFont::NoAntialias) {
- qual = NONANTIALIASED_QUALITY;
- } else if ((request.styleStrategy & QFont::NoSubpixelAntialias) && sharedFontData()->clearTypeEnabled) {
- qual = ANTIALIASED_QUALITY;
- }
-
- lf.lfQuality = qual;
-
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-
- int hint = FF_DONTCARE;
- switch (request.styleHint) {
- case QFont::Helvetica:
- hint = FF_SWISS;
- break;
- case QFont::Times:
- hint = FF_ROMAN;
- break;
- case QFont::Courier:
- hint = FF_MODERN;
- break;
- case QFont::OldEnglish:
- hint = FF_DECORATIVE;
- break;
- case QFont::System:
- hint = FF_MODERN;
- break;
- default:
- break;
- }
-
- lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
-
- QString fam = faceName;
- if (fam.isEmpty())
- fam = request.families.size() > 0 ? request.families.at(0) : request.family;
- if (Q_UNLIKELY(fam.size() >= LF_FACESIZE)) {
- qCritical("%s: Family name '%s' is too long.", __FUNCTION__, qPrintable(fam));
- fam.truncate(LF_FACESIZE - 1);
- }
-
- if (fam.isEmpty())
- fam = QStringLiteral("MS Sans Serif");
-
- if (fam == QLatin1String("MS Sans Serif")
- && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
- fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
- }
- if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
- fam = QStringLiteral("Courier New");
-
- memcpy(lf.lfFaceName, fam.utf16(), fam.size() * sizeof(wchar_t));
-
- return lf;
-}
-
QStringList QWindowsFontDatabase::extraTryFontsForFamily(const QString &family)
{
QStringList result;
@@ -1949,7 +1241,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q
}
#if !defined(QT_NO_DIRECTWRITE)
- if (initDirectWrite(data.data())) {
+ if (data->directWriteFactory != nullptr) {
const QString fam = QString::fromWCharArray(lf.lfFaceName);
const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam);
if (nameSubstitute != fam) {
@@ -2025,62 +1317,6 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q
return fe;
}
-QFont QWindowsFontDatabase::systemDefaultFont()
-{
-#if QT_VERSION >= 0x060000
- // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
- NONCLIENTMETRICS ncm;
- ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
- const QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
-#else
- LOGFONT lf;
- GetObject(QWindowsFontDatabase::systemFont(), sizeof(lf), &lf);
- QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf);
- // "MS Shell Dlg 2" is the correct system font >= Win2k
- if (systemFont.family() == QLatin1String("MS Shell Dlg"))
- systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
- // Qt 5 by (Qt 4) legacy uses GetStockObject(DEFAULT_GUI_FONT) to
- // obtain the default GUI font (typically "MS Shell Dlg 2, 8pt"). This has been
- // long deprecated; the message font of the NONCLIENTMETRICS structure obtained by
- // SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see
- // QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger.
-#endif // Qt 5
- qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
- return systemFont;
-}
-
-QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
-{
- if (verticalDPI_In <= 0)
- verticalDPI_In = defaultVerticalDPI();
- QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
- qFont.setItalic(logFont.lfItalic);
- if (logFont.lfWeight != FW_DONTCARE)
- qFont.setWeight(QPlatformFontDatabase::weightFromInteger(logFont.lfWeight));
- const qreal logFontHeight = qAbs(logFont.lfHeight);
- qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(logFont.lfUnderline);
- qFont.setOverline(false);
- qFont.setStrikeOut(logFont.lfStrikeOut);
- return qFont;
-}
-
-int QWindowsFontDatabase::defaultVerticalDPI()
-{
- static int vDPI = -1;
- if (vDPI == -1) {
- if (HDC defaultDC = GetDC(0)) {
- vDPI = GetDeviceCaps(defaultDC, LOGPIXELSY);
- ReleaseDC(0, defaultDC);
- } else {
- // FIXME: Resolve now or return 96 and keep unresolved?
- vDPI = 96;
- }
- }
- return vDPI;
-}
-
bool QWindowsFontDatabase::isPrivateFontFamily(const QString &family) const
{
return m_eudcFonts.contains(family) || QPlatformFontDatabase::isPrivateFontFamily(family);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
index a6b7fcf31e..5c2742d295 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
@@ -215,17 +215,15 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyName;
QString subFamilyStyle;
- if (ttf) {
- // Look-up names registered in the font
- QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
- if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
- englishName = canonicalNames.name;
- if (!canonicalNames.preferredName.isEmpty()) {
- subFamilyName = familyName;
- subFamilyStyle = styleName;
- familyName = canonicalNames.preferredName;
- styleName = canonicalNames.preferredStyle;
- }
+ // Look-up names registered in the font
+ QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
+ if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
+ englishName = canonicalNames.name;
+ if (!canonicalNames.preferredName.isEmpty()) {
+ subFamilyName = familyName;
+ subFamilyStyle = styleName;
+ familyName = canonicalNames.preferredName;
+ styleName = canonicalNames.preferredStyle;
}
QSupportedWritingSystems writingSystems;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
index f132e69d4d..a76fdc0810 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
@@ -51,39 +51,16 @@
// We mean it.
//
+#include "qwindowsfontdatabasebase_p.h"
+
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/QSharedPointer>
#include <QtCore/QLoggingCategory>
#include <QtCore/qt_windows.h>
-#if !defined(QT_NO_DIRECTWRITE)
- struct IDWriteFactory;
- struct IDWriteGdiInterop;
-#endif
-
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
-
-class QWindowsFontEngineData
-{
- Q_DISABLE_COPY_MOVE(QWindowsFontEngineData)
-public:
- QWindowsFontEngineData();
- ~QWindowsFontEngineData();
-
- uint pow_gamma[256];
-
- bool clearTypeEnabled = false;
- qreal fontSmoothingGamma;
- HDC hdc = 0;
-#if !defined(QT_NO_DIRECTWRITE)
- IDWriteFactory *directWriteFactory = nullptr;
- IDWriteGdiInterop *directWriteGdiInterop = nullptr;
-#endif
-};
-
-class QWindowsFontDatabase : public QPlatformFontDatabase
+class QWindowsFontDatabase : public QWindowsFontDatabaseBase
{
Q_DISABLE_COPY_MOVE(QWindowsFontDatabase)
public:
@@ -113,23 +90,15 @@ public:
void refUniqueFont(const QString &uniqueFont);
bool isPrivateFontFamily(const QString &family) const override;
- static QFont systemDefaultFont();
-
static QFontEngine *createEngine(const QFontDef &request, const QString &faceName,
int dpi,
const QSharedPointer<QWindowsFontEngineData> &data);
- static HFONT systemFont();
- static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
-
static qreal fontSmoothingGamma();
- static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef, const QString &faceName);
static QStringList extraTryFontsForFamily(const QString &family);
static QString familyForStyleHint(QFont::StyleHint styleHint);
- static int defaultVerticalDPI();
-
static void setFontOptions(unsigned options);
static unsigned fontOptions();
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp
new file mode 100644
index 0000000000..5b8707cdec
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp
@@ -0,0 +1,869 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsfontdatabasebase_p.h"
+#include "qwindowsfontdatabase_p.h"
+
+#include <QtCore/private/qsystemlibrary_p.h>
+#include <QtCore/QThreadStorage>
+#include <QtCore/QtEndian>
+
+#if !defined(QT_NO_DIRECTWRITE)
+# if defined(QT_USE_DIRECTWRITE3)
+# include <dwrite_3.h>
+# elif defined(QT_USE_DIRECTWRITE2)
+# include <dwrite_2.h>
+# else
+# include <dwrite.h>
+# endif
+# include <d2d1.h>
+# include "qwindowsfontenginedirectwrite_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Helper classes for creating font engines directly from font data
+namespace {
+
+# pragma pack(1)
+
+ // Common structure for all formats of the "name" table
+ struct NameTable
+ {
+ quint16 format;
+ quint16 count;
+ quint16 stringOffset;
+ };
+
+ struct NameRecord
+ {
+ quint16 platformID;
+ quint16 encodingID;
+ quint16 languageID;
+ quint16 nameID;
+ quint16 length;
+ quint16 offset;
+ };
+
+ struct OffsetSubTable
+ {
+ quint32 scalerType;
+ quint16 numTables;
+ quint16 searchRange;
+ quint16 entrySelector;
+ quint16 rangeShift;
+ };
+
+ struct TableDirectory : public QWindowsFontDatabaseBase::FontTable
+ {
+ quint32 identifier;
+ quint32 checkSum;
+ quint32 offset;
+ quint32 length;
+ };
+
+ struct OS2Table
+ {
+ quint16 version;
+ qint16 avgCharWidth;
+ quint16 weightClass;
+ quint16 widthClass;
+ quint16 type;
+ qint16 subscriptXSize;
+ qint16 subscriptYSize;
+ qint16 subscriptXOffset;
+ qint16 subscriptYOffset;
+ qint16 superscriptXSize;
+ qint16 superscriptYSize;
+ qint16 superscriptXOffset;
+ qint16 superscriptYOffset;
+ qint16 strikeOutSize;
+ qint16 strikeOutPosition;
+ qint16 familyClass;
+ quint8 panose[10];
+ quint32 unicodeRanges[4];
+ quint8 vendorID[4];
+ quint16 selection;
+ quint16 firstCharIndex;
+ quint16 lastCharIndex;
+ qint16 typoAscender;
+ qint16 typoDescender;
+ qint16 typoLineGap;
+ quint16 winAscent;
+ quint16 winDescent;
+ quint32 codepageRanges[2];
+ qint16 height;
+ qint16 capHeight;
+ quint16 defaultChar;
+ quint16 breakChar;
+ quint16 maxContext;
+ };
+
+# pragma pack()
+
+} // Anonymous namespace
+
+QWindowsFontDatabaseBase::FontTable *QWindowsFontDatabaseBase::EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
+{
+ Q_ASSERT(tagName.size() == 4);
+ quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
+ const size_t fontDataSize = m_fontData.size();
+ if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable)))
+ return nullptr;
+
+ OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
+ TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
+
+ const size_t tableCount = qFromBigEndian<quint16>(offsetSubTable->numTables);
+ if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount))
+ return nullptr;
+
+ TableDirectory *tableDirectoryEnd = tableDirectory + tableCount;
+ for (TableDirectory *entry = tableDirectory; entry < tableDirectoryEnd; ++entry) {
+ if (entry->identifier == tagId)
+ return entry;
+ }
+
+ return nullptr;
+}
+
+QString QWindowsFontDatabaseBase::EmbeddedFont::familyName(QWindowsFontDatabaseBase::FontTable *directoryEntry)
+{
+ QString name;
+
+ TableDirectory *nameTableDirectoryEntry = static_cast<TableDirectory *>(directoryEntry);
+ if (nameTableDirectoryEntry == nullptr)
+ nameTableDirectoryEntry = static_cast<TableDirectory *>(tableDirectoryEntry("name"));
+
+ if (nameTableDirectoryEntry != nullptr) {
+ quint32 offset = qFromBigEndian<quint32>(nameTableDirectoryEntry->offset);
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable)))
+ return QString();
+
+ NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() + offset);
+ NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
+
+ quint16 nameTableCount = qFromBigEndian<quint16>(nameTable->count);
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount))
+ return QString();
+
+ for (int i = 0; i < nameTableCount; ++i, ++nameRecord) {
+ if (qFromBigEndian<quint16>(nameRecord->nameID) == 1
+ && qFromBigEndian<quint16>(nameRecord->platformID) == 3 // Windows
+ && qFromBigEndian<quint16>(nameRecord->languageID) == 0x0409) { // US English
+ quint16 stringOffset = qFromBigEndian<quint16>(nameTable->stringOffset);
+ quint16 nameOffset = qFromBigEndian<quint16>(nameRecord->offset);
+ quint16 nameLength = qFromBigEndian<quint16>(nameRecord->length);
+
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength))
+ return QString();
+
+ const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
+ + stringOffset
+ + nameOffset;
+
+ const quint16 *s = reinterpret_cast<const quint16 *>(ptr);
+ const quint16 *e = s + nameLength / sizeof(quint16);
+ while (s != e)
+ name += QChar( qFromBigEndian<quint16>(*s++));
+ break;
+ }
+ }
+ }
+
+ return name;
+}
+
+void QWindowsFontDatabaseBase::EmbeddedFont::updateFromOS2Table(QFontEngine *fontEngine)
+{
+ TableDirectory *os2TableEntry = static_cast<TableDirectory *>(tableDirectoryEntry("OS/2"));
+ if (os2TableEntry != nullptr) {
+ const OS2Table *os2Table =
+ reinterpret_cast<const OS2Table *>(m_fontData.constData()
+ + qFromBigEndian<quint32>(os2TableEntry->offset));
+
+ bool italic = qFromBigEndian<quint16>(os2Table->selection) & (1 << 0);
+ bool oblique = qFromBigEndian<quint16>(os2Table->selection) & (1 << 9);
+
+ if (italic)
+ fontEngine->fontDef.style = QFont::StyleItalic;
+ else if (oblique)
+ fontEngine->fontDef.style = QFont::StyleOblique;
+ else
+ fontEngine->fontDef.style = QFont::StyleNormal;
+
+ fontEngine->fontDef.weight = QPlatformFontDatabase::weightFromInteger(qFromBigEndian<quint16>(os2Table->weightClass));
+ }
+}
+
+QString QWindowsFontDatabaseBase::EmbeddedFont::changeFamilyName(const QString &newFamilyName)
+{
+ TableDirectory *nameTableDirectoryEntry = static_cast<TableDirectory *>(tableDirectoryEntry("name"));
+ if (nameTableDirectoryEntry == nullptr)
+ return QString();
+
+ QString oldFamilyName = familyName(nameTableDirectoryEntry);
+
+ // Reserve size for name table header, five required name records and string
+ const int requiredRecordCount = 5;
+ quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
+
+ int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
+ int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16));
+
+ const QString regularString = QString::fromLatin1("Regular");
+ int regularStringSize = regularString.size() * int(sizeof(quint16));
+
+ // Align table size of table to 32 bits (pad with 0)
+ int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
+
+ QByteArray newNameTable(fullSize, char(0));
+
+ {
+ NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
+ nameTable->count = qbswap<quint16>(requiredRecordCount);
+ nameTable->stringOffset = qbswap<quint16>(sizeOfHeader);
+
+ NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
+ for (int i = 0; i < requiredRecordCount; ++i, nameRecord++) {
+ nameRecord->nameID = qbswap<quint16>(nameIds[i]);
+ nameRecord->encodingID = qbswap<quint16>(1);
+ nameRecord->languageID = qbswap<quint16>(0x0409);
+ nameRecord->platformID = qbswap<quint16>(3);
+ nameRecord->length = qbswap<quint16>(newFamilyNameSize);
+
+ // Special case for sub-family
+ if (nameIds[i] == 4) {
+ nameRecord->offset = qbswap<quint16>(newFamilyNameSize);
+ nameRecord->length = qbswap<quint16>(regularStringSize);
+ }
+ }
+
+ // nameRecord now points to string data
+ quint16 *stringStorage = reinterpret_cast<quint16 *>(nameRecord);
+ const quint16 *sourceString = newFamilyName.utf16();
+ for (int i = 0; i < newFamilyName.size(); ++i)
+ stringStorage[i] = qbswap<quint16>(sourceString[i]);
+ stringStorage += newFamilyName.size();
+
+ sourceString = regularString.utf16();
+ for (int i = 0; i < regularString.size(); ++i)
+ stringStorage[i] = qbswap<quint16>(sourceString[i]);
+ }
+
+ quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
+ quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
+
+ quint32 checkSum = 0;
+ while (p < tableEnd)
+ checkSum += qFromBigEndian<quint32>(*(p++));
+
+ nameTableDirectoryEntry->checkSum = qbswap<quint32>(checkSum);
+ nameTableDirectoryEntry->offset = qbswap<quint32>(m_fontData.size());
+ nameTableDirectoryEntry->length = qbswap<quint32>(fullSize);
+
+ m_fontData.append(newNameTable);
+
+ return oldFamilyName;
+}
+
+#if !defined(QT_NO_DIRECTWRITE)
+
+namespace {
+ class DirectWriteFontFileStream: public IDWriteFontFileStream
+ {
+ Q_DISABLE_COPY(DirectWriteFontFileStream)
+ public:
+ DirectWriteFontFileStream(const QByteArray &fontData)
+ : m_fontData(fontData)
+ , m_referenceCount(0)
+ {
+ }
+ virtual ~DirectWriteFontFileStream()
+ {
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
+ UINT64 fragmentSize, OUT void **fragmentContext);
+ void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
+ HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
+ HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
+
+ private:
+ QByteArray m_fontData;
+ ULONG m_referenceCount;
+ };
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
+ {
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
+ *object = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
+ {
+ return InterlockedIncrement(&m_referenceCount);
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
+ {
+ ULONG newCount = InterlockedDecrement(&m_referenceCount);
+ if (newCount == 0)
+ delete this;
+ return newCount;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
+ const void **fragmentStart,
+ UINT64 fileOffset,
+ UINT64 fragmentSize,
+ OUT void **fragmentContext)
+ {
+ *fragmentContext = NULL;
+ if (fileOffset + fragmentSize <= quint64(m_fontData.size())) {
+ *fragmentStart = m_fontData.data() + fileOffset;
+ return S_OK;
+ } else {
+ *fragmentStart = NULL;
+ return E_FAIL;
+ }
+ }
+
+ void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
+ {
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
+ {
+ *fileSize = m_fontData.size();
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
+ {
+ *lastWriteTime = 0;
+ return E_NOTIMPL;
+ }
+
+ class DirectWriteFontFileLoader: public IDWriteFontFileLoader
+ {
+ public:
+ DirectWriteFontFileLoader() : m_referenceCount(0) {}
+ virtual ~DirectWriteFontFileLoader()
+ {
+ }
+
+ inline void addKey(const void *key, const QByteArray &fontData)
+ {
+ Q_ASSERT(!m_fontDatas.contains(key));
+ m_fontDatas.insert(key, fontData);
+ }
+
+ inline void removeKey(const void *key)
+ {
+ m_fontDatas.remove(key);
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ OUT IDWriteFontFileStream **fontFileStream);
+
+ private:
+ ULONG m_referenceCount;
+ QHash<const void *, QByteArray> m_fontDatas;
+ };
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
+ void **object)
+ {
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
+ *object = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
+ {
+ return InterlockedIncrement(&m_referenceCount);
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
+ {
+ ULONG newCount = InterlockedDecrement(&m_referenceCount);
+ if (newCount == 0)
+ delete this;
+ return newCount;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
+ void const *fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ IDWriteFontFileStream **fontFileStream)
+ {
+ Q_UNUSED(fontFileReferenceKeySize);
+
+ if (fontFileReferenceKeySize != sizeof(const void *)) {
+ qWarning("%s: Wrong key size", __FUNCTION__);
+ return E_FAIL;
+ }
+
+ const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
+ *fontFileStream = NULL;
+ auto it = m_fontDatas.constFind(key);
+ if (it == m_fontDatas.constEnd())
+ return E_FAIL;
+
+ QByteArray fontData = it.value();
+ DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
+ stream->AddRef();
+ *fontFileStream = stream;
+
+ return S_OK;
+ }
+
+ class CustomFontFileLoader
+ {
+ public:
+ CustomFontFileLoader(IDWriteFactory *factory)
+ {
+ m_directWriteFactory = factory;
+
+ if (m_directWriteFactory) {
+ m_directWriteFactory->AddRef();
+
+ m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
+ m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
+ }
+ }
+
+ ~CustomFontFileLoader()
+ {
+ if (m_directWriteFactory != nullptr && m_directWriteFontFileLoader != nullptr)
+ m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
+
+ if (m_directWriteFactory != nullptr)
+ m_directWriteFactory->Release();
+ }
+
+ void addKey(const void *key, const QByteArray &fontData)
+ {
+ if (m_directWriteFontFileLoader != nullptr)
+ m_directWriteFontFileLoader->addKey(key, fontData);
+ }
+
+ void removeKey(const void *key)
+ {
+ if (m_directWriteFontFileLoader != nullptr)
+ m_directWriteFontFileLoader->removeKey(key);
+ }
+
+ IDWriteFontFileLoader *loader() const
+ {
+ return m_directWriteFontFileLoader;
+ }
+
+ private:
+ IDWriteFactory *m_directWriteFactory = nullptr;
+ DirectWriteFontFileLoader *m_directWriteFontFileLoader = nullptr;
+ };
+} // Anonymous namespace
+
+#endif // !defined(QT_NO_DIRECTWRITE)
+
+
+QWindowsFontEngineData::~QWindowsFontEngineData()
+{
+ if (hdc)
+ DeleteDC(hdc);
+
+#if !defined(QT_NO_DIRECTWRITE)
+ if (directWriteGdiInterop)
+ directWriteGdiInterop->Release();
+ if (directWriteFactory)
+ directWriteFactory->Release();
+#endif
+}
+
+QWindowsFontDatabaseBase::QWindowsFontDatabaseBase()
+{
+}
+
+QWindowsFontDatabaseBase::~QWindowsFontDatabaseBase()
+{
+}
+
+typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
+typedef QThreadStorage<QWindowsFontEngineDataPtr> FontEngineThreadLocalData;
+Q_GLOBAL_STATIC(FontEngineThreadLocalData, fontEngineThreadLocalData)
+
+QSharedPointer<QWindowsFontEngineData> QWindowsFontDatabaseBase::data()
+{
+ FontEngineThreadLocalData *data = fontEngineThreadLocalData();
+ if (!data->hasLocalData())
+ data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create());
+
+ if (!init(data->localData()))
+ qCWarning(lcQpaFonts) << "Cannot initialize common font database data";
+
+ return data->localData();
+}
+
+bool QWindowsFontDatabaseBase::init(QSharedPointer<QWindowsFontEngineData> d)
+{
+#if !defined(QT_NO_DIRECTWRITE)
+ if (!d->directWriteFactory) {
+ createDirectWriteFactory(&d->directWriteFactory);
+ if (!d->directWriteFactory)
+ return false;
+ }
+ if (!d->directWriteGdiInterop) {
+ const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGdiInterop failed", __FUNCTION__);
+ return false;
+ }
+ }
+#endif
+ return true;
+}
+
+#if !defined(QT_NO_DIRECTWRITE)
+// ### Qt 6: Link directly to dwrite instead
+typedef HRESULT (WINAPI *DWriteCreateFactoryType)(DWRITE_FACTORY_TYPE, const IID &, IUnknown **);
+static inline DWriteCreateFactoryType resolveDWriteCreateFactory()
+{
+ QSystemLibrary library(QStringLiteral("dwrite"));
+ QFunctionPointer result = library.resolve("DWriteCreateFactory");
+ if (Q_UNLIKELY(!result)) {
+ qWarning("Unable to load dwrite.dll");
+ return nullptr;
+ }
+ return reinterpret_cast<DWriteCreateFactoryType>(result);
+}
+
+void QWindowsFontDatabaseBase::createDirectWriteFactory(IDWriteFactory **factory)
+{
+ *factory = nullptr;
+
+ static const DWriteCreateFactoryType dWriteCreateFactory = resolveDWriteCreateFactory();
+ if (!dWriteCreateFactory)
+ return;
+
+ IUnknown *result = nullptr;
+# if defined(QT_USE_DIRECTWRITE3)
+ dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory3), &result);
+# endif
+
+# if defined(QT_USE_DIRECTWRITE2)
+ if (result == nullptr)
+ dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), &result);
+# endif
+
+ if (result == nullptr) {
+ if (FAILED(dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &result))) {
+ qErrnoWarning("DWriteCreateFactory failed");
+ return;
+ }
+ }
+
+ *factory = static_cast<IDWriteFactory *>(result);
+}
+#endif // !defined(QT_NO_DIRECTWRITE)
+
+int QWindowsFontDatabaseBase::defaultVerticalDPI()
+{
+ static int vDPI = -1;
+ if (vDPI == -1) {
+ if (HDC defaultDC = GetDC(0)) {
+ vDPI = GetDeviceCaps(defaultDC, LOGPIXELSY);
+ ReleaseDC(0, defaultDC);
+ } else {
+ // FIXME: Resolve now or return 96 and keep unresolved?
+ vDPI = 96;
+ }
+ }
+ return vDPI;
+}
+
+LOGFONT QWindowsFontDatabaseBase::fontDefToLOGFONT(const QFontDef &request, const QString &faceName)
+{
+ LOGFONT lf;
+ memset(&lf, 0, sizeof(LOGFONT));
+
+ lf.lfHeight = -qRound(request.pixelSize);
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ if (request.weight == 50)
+ lf.lfWeight = FW_DONTCARE;
+ else
+ lf.lfWeight = (request.weight*900)/99;
+ lf.lfItalic = request.style != QFont::StyleNormal;
+ lf.lfCharSet = DEFAULT_CHARSET;
+
+ int strat = OUT_DEFAULT_PRECIS;
+ if (request.styleStrategy & QFont::PreferBitmap) {
+ strat = OUT_RASTER_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferDevice) {
+ strat = OUT_DEVICE_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferOutline) {
+ strat = OUT_OUTLINE_PRECIS;
+ } else if (request.styleStrategy & QFont::ForceOutline) {
+ strat = OUT_TT_ONLY_PRECIS;
+ }
+
+ lf.lfOutPrecision = strat;
+
+ int qual = DEFAULT_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferMatch)
+ qual = DRAFT_QUALITY;
+ else if (request.styleStrategy & QFont::PreferQuality)
+ qual = PROOF_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferAntialias) {
+ qual = (request.styleStrategy & QFont::NoSubpixelAntialias) == 0
+ ? CLEARTYPE_QUALITY : ANTIALIASED_QUALITY;
+ } else if (request.styleStrategy & QFont::NoAntialias) {
+ qual = NONANTIALIASED_QUALITY;
+ } else if ((request.styleStrategy & QFont::NoSubpixelAntialias) && data()->clearTypeEnabled) {
+ qual = ANTIALIASED_QUALITY;
+ }
+
+ lf.lfQuality = qual;
+
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+
+ int hint = FF_DONTCARE;
+ switch (request.styleHint) {
+ case QFont::Helvetica:
+ hint = FF_SWISS;
+ break;
+ case QFont::Times:
+ hint = FF_ROMAN;
+ break;
+ case QFont::Courier:
+ hint = FF_MODERN;
+ break;
+ case QFont::OldEnglish:
+ hint = FF_DECORATIVE;
+ break;
+ case QFont::System:
+ hint = FF_MODERN;
+ break;
+ default:
+ break;
+ }
+
+ lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
+
+ QString fam = faceName;
+ if (fam.isEmpty())
+ fam = request.families.size() > 0 ? request.families.at(0) : request.family;
+ if (Q_UNLIKELY(fam.size() >= LF_FACESIZE)) {
+ qCritical("%s: Family name '%s' is too long.", __FUNCTION__, qPrintable(fam));
+ fam.truncate(LF_FACESIZE - 1);
+ }
+
+ if (fam.isEmpty())
+ fam = QStringLiteral("MS Sans Serif");
+
+ if (fam == QLatin1String("MS Sans Serif")
+ && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
+ fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
+ }
+ if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
+ fam = QStringLiteral("Courier New");
+
+ memcpy(lf.lfFaceName, fam.utf16(), fam.size() * sizeof(wchar_t));
+
+ return lf;
+}
+
+QFont QWindowsFontDatabaseBase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
+{
+ if (verticalDPI_In <= 0)
+ verticalDPI_In = defaultVerticalDPI();
+ QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
+ qFont.setItalic(logFont.lfItalic);
+ if (logFont.lfWeight != FW_DONTCARE)
+ qFont.setWeight(QPlatformFontDatabase::weightFromInteger(logFont.lfWeight));
+ const qreal logFontHeight = qAbs(logFont.lfHeight);
+ qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
+ qFont.setUnderline(logFont.lfUnderline);
+ qFont.setOverline(false);
+ qFont.setStrikeOut(logFont.lfStrikeOut);
+ return qFont;
+}
+
+// ### fixme Qt 6 (QTBUG-58610): See comment at QWindowsFontDatabase::systemDefaultFont()
+HFONT QWindowsFontDatabaseBase::systemFont()
+{
+ static const auto stock_sysfont =
+ reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
+ return stock_sysfont;
+}
+
+QFont QWindowsFontDatabaseBase::systemDefaultFont()
+{
+#if QT_VERSION >= 0x060000
+ // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
+ const QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
+#else
+ LOGFONT lf;
+ GetObject(systemFont(), sizeof(lf), &lf);
+ QFont systemFont = LOGFONT_to_QFont(lf);
+ // "MS Shell Dlg 2" is the correct system font >= Win2k
+ if (systemFont.family() == QLatin1String("MS Shell Dlg"))
+ systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
+ // Qt 5 by (Qt 4) legacy uses GetStockObject(DEFAULT_GUI_FONT) to
+ // obtain the default GUI font (typically "MS Shell Dlg 2, 8pt"). This has been
+ // long deprecated; the message font of the NONCLIENTMETRICS structure obtained by
+ // SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see
+ // QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger.
+#endif // Qt 5
+ qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
+ return systemFont;
+}
+
+#if !defined(QT_NO_DIRECTWRITE)
+IDWriteFontFace *QWindowsFontDatabaseBase::createDirectWriteFace(const QByteArray &fontData) const
+{
+ QSharedPointer<QWindowsFontEngineData> fontEngineData = data();
+ if (fontEngineData->directWriteFactory == nullptr) {
+ qCWarning(lcQpaFonts) << "DirectWrite factory not created in QWindowsFontDatabaseBase::createDirectWriteFace()";
+ return nullptr;
+ }
+
+ CustomFontFileLoader fontFileLoader(fontEngineData->directWriteFactory);
+ fontFileLoader.addKey(this, fontData);
+
+ IDWriteFontFile *fontFile = nullptr;
+ const void *key = this;
+
+ HRESULT hres = fontEngineData->directWriteFactory->CreateCustomFontFileReference(&key,
+ sizeof(void *),
+ fontFileLoader.loader(),
+ &fontFile);
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "%s: CreateCustomFontFileReference failed", __FUNCTION__);
+ return nullptr;
+ }
+
+ BOOL isSupportedFontType;
+ DWRITE_FONT_FILE_TYPE fontFileType;
+ DWRITE_FONT_FACE_TYPE fontFaceType;
+ UINT32 numberOfFaces;
+ fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
+ if (!isSupportedFontType) {
+ fontFile->Release();
+ return nullptr;
+ }
+
+ // ### Currently no support for .ttc, but we could easily return a list here.
+ IDWriteFontFace *directWriteFontFace = nullptr;
+ hres = fontEngineData->directWriteFactory->CreateFontFace(fontFaceType,
+ 1,
+ &fontFile,
+ 0,
+ DWRITE_FONT_SIMULATIONS_NONE,
+ &directWriteFontFace);
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "%s: CreateFontFace failed", __FUNCTION__);
+ fontFile->Release();
+ return nullptr;
+ }
+
+ fontFile->Release();
+ return directWriteFontFace;
+}
+#endif // !defined(QT_NO_DIRECTWRITE)
+
+QFontEngine *QWindowsFontDatabaseBase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
+{
+ QFontEngine *fontEngine = nullptr;
+
+#if !defined(QT_NO_DIRECTWRITE)
+ QSharedPointer<QWindowsFontEngineData> fontEngineData = data();
+ if (fontEngineData->directWriteFactory == nullptr)
+ return nullptr;
+
+ IDWriteFontFace *directWriteFontFace = createDirectWriteFace(fontData);
+ fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace,
+ pixelSize,
+ fontEngineData);
+
+ // Get font family from font data
+ EmbeddedFont font(fontData);
+ font.updateFromOS2Table(fontEngine);
+ fontEngine->fontDef.family = font.familyName();
+ fontEngine->fontDef.hintingPreference = hintingPreference;
+
+ directWriteFontFace->Release();
+#else // !defined(QT_NO_DIRECTWRITE)
+ Q_UNUSED(fontData);
+ Q_UNUSED(pixelSize);
+ Q_UNUSED(hintingPreference);
+#endif
+
+ return fontEngine;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h
new file mode 100644
index 0000000000..fbaa98b663
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTDATABASEBASE_P_H
+#define QWINDOWSFONTDATABASEBASE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformfontdatabase.h>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/qt_windows.h>
+
+#if !defined(QT_NO_DIRECTWRITE)
+ struct IDWriteFactory;
+ struct IDWriteGdiInterop;
+ struct IDWriteFontFace;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts);
+
+class QWindowsFontEngineData
+{
+ Q_DISABLE_COPY_MOVE(QWindowsFontEngineData)
+public:
+ QWindowsFontEngineData();
+ ~QWindowsFontEngineData();
+
+ uint pow_gamma[256];
+
+ bool clearTypeEnabled = false;
+ qreal fontSmoothingGamma;
+ HDC hdc = 0;
+#if !defined(QT_NO_DIRECTWRITE)
+ IDWriteFactory *directWriteFactory = nullptr;
+ IDWriteGdiInterop *directWriteGdiInterop = nullptr;
+#endif
+};
+
+class QWindowsFontDatabaseBase : public QPlatformFontDatabase
+{
+public:
+ QWindowsFontDatabaseBase();
+ ~QWindowsFontDatabaseBase() override;
+
+ QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
+
+ static int defaultVerticalDPI();
+ static QSharedPointer<QWindowsFontEngineData> data();
+#if !defined(QT_NO_DIRECTWRITE)
+ static void createDirectWriteFactory(IDWriteFactory **factory);
+#endif
+ static QFont systemDefaultFont();
+ static HFONT systemFont();
+ static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef, const QString &faceName);
+ static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
+
+ class FontTable{};
+ class EmbeddedFont
+ {
+ public:
+ EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
+
+ QString changeFamilyName(const QString &newFamilyName);
+ QByteArray data() const { return m_fontData; }
+ void updateFromOS2Table(QFontEngine *fontEngine);
+ FontTable *tableDirectoryEntry(const QByteArray &tagName);
+ QString familyName(FontTable *nameTableDirectory = nullptr);
+
+ private:
+ QByteArray m_fontData;
+ };
+
+protected:
+
+#if !defined(QT_NO_DIRECTWRITE)
+ IDWriteFontFace *createDirectWriteFace(const QByteArray &fontData) const;
+#endif
+
+private:
+ static bool init(QSharedPointer<QWindowsFontEngineData> data);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSFONTDATABASEBASE_P_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
index e796c18e79..45ce396d5e 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -62,6 +62,9 @@
QT_BEGIN_NAMESPACE
+// Clang does not consider __declspec(nothrow) as nothrow
+QT_WARNING_DISABLE_CLANG("-Wmicrosoft-exception-spec")
+
// Convert from design units to logical pixels
#define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \
QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize)
@@ -184,6 +187,18 @@ namespace {
}
+static DWRITE_MEASURING_MODE renderModeToMeasureMode(DWRITE_RENDERING_MODE renderMode)
+{
+ switch (renderMode) {
+ case DWRITE_RENDERING_MODE_GDI_CLASSIC:
+ return DWRITE_MEASURING_MODE_GDI_CLASSIC;
+ case DWRITE_RENDERING_MODE_GDI_NATURAL:
+ return DWRITE_MEASURING_MODE_GDI_NATURAL;
+ default:
+ return DWRITE_MEASURING_MODE_NATURAL;
+ }
+}
+
static DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(QFont::HintingPreference hintingPreference)
{
if (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting)
@@ -206,13 +221,10 @@ static DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(QFont::HintingPref
\ingroup qt-lighthouse-win
Font engine for subpixel positioned text on Windows Vista
- (with platform update) and Windows 7. If selected during
+ (with platform update) and later. If selected during
configuration, the engine will be selected only when the hinting
- preference of a font is set to None or Vertical hinting. The font
- database uses most of the same logic but creates a direct write
- font based on the LOGFONT rather than a GDI handle.
-
- Will probably be superseded by a common Free Type font engine in Qt 5.X.
+ preference of a font is set to None or Vertical hinting, or
+ when fontengine=directwrite is selected as platform option.
*/
QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
@@ -458,7 +470,7 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly
glyphs->numGlyphs = actualLength;
if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
+ recalcAdvances(glyphs, {});
return true;
}
@@ -477,9 +489,22 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
glyphIndices[i] = UINT16(glyphs->glyphs[i]);
QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size());
- HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
- glyphIndices.size(),
- glyphMetrics.data());
+
+ HRESULT hr;
+ DWRITE_RENDERING_MODE renderMode = hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
+ if (renderMode == DWRITE_RENDERING_MODE_GDI_CLASSIC || renderMode == DWRITE_RENDERING_MODE_GDI_NATURAL) {
+ hr = m_directWriteFontFace->GetGdiCompatibleGlyphMetrics(float(fontDef.pixelSize),
+ 1.0f,
+ NULL,
+ TRUE,
+ glyphIndices.data(),
+ glyphIndices.size(),
+ glyphMetrics.data());
+ } else {
+ hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
+ glyphIndices.size(),
+ glyphMetrics.data());
+ }
if (SUCCEEDED(hr)) {
qreal stretch = fontDef.stretch != QFont::AnyStretch ? fontDef.stretch / 100.0 : 1.0;
for (int i = 0; i < glyphs->numGlyphs; ++i)
@@ -685,6 +710,8 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
DWRITE_RENDERING_MODE renderMode =
hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
+ DWRITE_MEASURING_MODE measureMode =
+ renderModeToMeasureMode(renderMode);
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
@@ -692,7 +719,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
0.0, 0.0,
&glyphAnalysis
);
@@ -722,7 +749,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
0.0f,
&glyphRun,
NULL,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
NULL,
0,
&enumerator);
@@ -753,7 +780,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
0.0, 0.0,
&colorGlyphsAnalysis
);
@@ -993,6 +1020,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
DWRITE_RENDERING_MODE renderMode =
hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
+ DWRITE_MEASURING_MODE measureMode = renderModeToMeasureMode(renderMode);
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
@@ -1000,7 +1028,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
0.0, 0.0,
&glyphAnalysis
);
@@ -1012,8 +1040,8 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
int margin = glyphMargin(QFontEngine::Format_A32);
- return glyph_metrics_t(rect.left,
- rect.top,
+ return glyph_metrics_t(rect.left - margin,
+ rect.top - margin,
rect.right - rect.left + margin * 2,
rect.bottom - rect.top + margin * 2,
bbox.xoff, bbox.yoff);
diff --git a/src/platformsupport/fontdatabases/windows/windows.pri b/src/platformsupport/fontdatabases/windows/windows.pri
index 7ddfb2c281..fbe6d490f9 100644
--- a/src/platformsupport/fontdatabases/windows/windows.pri
+++ b/src/platformsupport/fontdatabases/windows/windows.pri
@@ -2,11 +2,13 @@ QT *= gui-private
SOURCES += \
$$PWD/qwindowsfontdatabase.cpp \
+ $$PWD/qwindowsfontdatabasebase.cpp \
$$PWD/qwindowsfontengine.cpp \
$$PWD/qwindowsnativeimage.cpp
HEADERS += \
$$PWD/qwindowsfontdatabase_p.h \
+ $$PWD/qwindowsfontdatabasebase_p.h \
$$PWD/qwindowsfontengine_p.h \
$$PWD/qwindowsnativeimage_p.h
@@ -16,7 +18,13 @@ qtConfig(freetype) {
}
qtConfig(directwrite):qtConfig(direct2d) {
- qtConfig(directwrite2) {
+ qtConfig(directwrite3) {
+ QMAKE_USE_PRIVATE += dwrite_3
+ DEFINES *= QT_USE_DIRECTWRITE3 QT_USE_DIRECTWRITE2
+
+ SOURCES += $$PWD/qwindowsdirectwritefontdatabase.cpp
+ HEADERS += $$PWD/qwindowsdirectwritefontdatabase_p.h
+ } else: qtConfig(directwrite2) {
QMAKE_USE_PRIVATE += dwrite_2
DEFINES *= QT_USE_DIRECTWRITE2
} else {
diff --git a/src/platformsupport/glxconvenience/.prev_CMakeLists.txt b/src/platformsupport/glxconvenience/.prev_CMakeLists.txt
index ecee19fc8b..f9a2fed5b2 100644
--- a/src/platformsupport/glxconvenience/.prev_CMakeLists.txt
+++ b/src/platformsupport/glxconvenience/.prev_CMakeLists.txt
@@ -4,22 +4,18 @@
## GlxSupport Module:
#####################################################################
-add_qt_module(GlxSupport
+qt_add_module(GlxSupport
STATIC
INTERNAL_MODULE
SOURCES
qglxconvenience.cpp qglxconvenience_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
X11::XCB
)
#### Keys ignored in scope 1:.:.:glxconvenience.pro:<TRUE>:
# MODULE = "glx_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/glxconvenience/CMakeLists.txt b/src/platformsupport/glxconvenience/CMakeLists.txt
index ff2357d52c..00bc78d429 100644
--- a/src/platformsupport/glxconvenience/CMakeLists.txt
+++ b/src/platformsupport/glxconvenience/CMakeLists.txt
@@ -6,22 +6,18 @@ qt_find_package(X11) # special case
## GlxSupport Module:
#####################################################################
-add_qt_module(GlxSupport
+qt_add_module(GlxSupport
STATIC
INTERNAL_MODULE
SOURCES
qglxconvenience.cpp qglxconvenience_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
X11::X11 # special case
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
)
#### Keys ignored in scope 1:.:.:glxconvenience.pro:<TRUE>:
# MODULE = "glx_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
index 81bccb1c25..5387214e8c 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience.cpp
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -193,7 +193,7 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
{
QXcbSoftwareOpenGLEnforcer softwareOpenGLEnforcer;
- GLXFBConfig config = 0;
+ GLXFBConfig config = nullptr;
do {
const QVector<int> spec = qglx_buildSpec(format, drawableBit, flags);
@@ -273,7 +273,7 @@ XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *f
{
Q_ASSERT(format);
- XVisualInfo *visualInfo = 0;
+ XVisualInfo *visualInfo = nullptr;
GLXFBConfig config = qglx_findConfig(display, screen, *format, false, drawableBit, flags);
if (config)
diff --git a/src/platformsupport/graphics/CMakeLists.txt b/src/platformsupport/graphics/CMakeLists.txt
index f342fd0c08..e9f0245dbe 100644
--- a/src/platformsupport/graphics/CMakeLists.txt
+++ b/src/platformsupport/graphics/CMakeLists.txt
@@ -4,21 +4,17 @@
## GraphicsSupport Module:
#####################################################################
-add_qt_module(GraphicsSupport
+qt_add_module(GraphicsSupport
STATIC
INTERNAL_MODULE
SOURCES
qrasterbackingstore.cpp qrasterbackingstore_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
)
#### Keys ignored in scope 1:.:.:graphics.pro:<TRUE>:
# MODULE = "graphics_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/input/.prev_CMakeLists.txt b/src/platformsupport/input/.prev_CMakeLists.txt
index 1d5270f234..f8c05e9f97 100644
--- a/src/platformsupport/input/.prev_CMakeLists.txt
+++ b/src/platformsupport/input/.prev_CMakeLists.txt
@@ -4,31 +4,26 @@
## InputSupport Module:
#####################################################################
-add_qt_module(InputSupport
+qt_add_module(InputSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::DeviceDiscoverySupportPrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::DeviceDiscoverySupport
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 3:.:.:input-support.pro:<TRUE>:
# MODULE = "input_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(InputSupport CONDITION QT_FEATURE_evdev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev
SOURCES
evdevkeyboard/qevdevkeyboard_defaultmap_p.h
evdevkeyboard/qevdevkeyboardhandler.cpp evdevkeyboard/qevdevkeyboardhandler_p.h
@@ -41,35 +36,35 @@ extend_target(InputSupport CONDITION QT_FEATURE_evdev
evdevtouch/../shared
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_tabletevent
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_tabletevent
SOURCES
evdevtablet/qevdevtablethandler.cpp evdevtablet/qevdevtablethandler_p.h
evdevtablet/qevdevtabletmanager.cpp evdevtablet/qevdevtabletmanager_p.h
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
LIBRARIES
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
LIBRARIES
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
LIBRARIES
PkgConfig::Mtdev
)
-extend_target(InputSupport CONDITION QT_FEATURE_tslib
+qt_extend_target(InputSupport CONDITION QT_FEATURE_tslib
SOURCES
tslib/qtslib.cpp tslib/qtslib_p.h
PUBLIC_LIBRARIES
PkgConfig::Tslib
)
-extend_target(InputSupport CONDITION QT_FEATURE_libinput
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput
SOURCES
libinput/qlibinputhandler.cpp libinput/qlibinputhandler_p.h
libinput/qlibinputkeyboard.cpp libinput/qlibinputkeyboard_p.h
@@ -82,22 +77,21 @@ extend_target(InputSupport CONDITION QT_FEATURE_libinput
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
LIBRARIES
- Qt::XkbCommonSupportPrivate
XKB::XKB
PUBLIC_LIBRARIES
- Qt::XkbCommonSupport
+ Qt::XkbCommonSupportPrivate
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput
SOURCES
shared/devicehandlerlist_p.h
shared/qevdevutil.cpp shared/qevdevutil_p.h
shared/qtouchoutputmapping.cpp shared/qtouchoutputmapping_p.h
)
-extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
+qt_extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
SOURCES
integrityhid/qintegrityhidmanager.cpp integrityhid/qintegrityhidmanager.h
LIBRARIES
diff --git a/src/platformsupport/input/CMakeLists.txt b/src/platformsupport/input/CMakeLists.txt
index 3c5cbaa4ce..7ab93df062 100644
--- a/src/platformsupport/input/CMakeLists.txt
+++ b/src/platformsupport/input/CMakeLists.txt
@@ -9,31 +9,26 @@ qt_find_package(Mtdev) # special case
## InputSupport Module:
#####################################################################
-add_qt_module(InputSupport
+qt_add_module(InputSupport
STATIC
INTERNAL_MODULE
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::DeviceDiscoverySupportPrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::DeviceDiscoverySupport
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 3:.:.:input-support.pro:<TRUE>:
# MODULE = "input_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(InputSupport CONDITION QT_FEATURE_evdev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev
SOURCES
evdevkeyboard/qevdevkeyboard_defaultmap_p.h
evdevkeyboard/qevdevkeyboardhandler.cpp evdevkeyboard/qevdevkeyboardhandler_p.h
@@ -46,35 +41,35 @@ extend_target(InputSupport CONDITION QT_FEATURE_evdev
evdevtouch/../shared
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_tabletevent
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_tabletevent
SOURCES
evdevtablet/qevdevtablethandler.cpp evdevtablet/qevdevtablethandler_p.h
evdevtablet/qevdevtabletmanager.cpp evdevtablet/qevdevtabletmanager_p.h
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
LIBRARIES
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
LIBRARIES
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
LIBRARIES
PkgConfig::Mtdev
)
-extend_target(InputSupport CONDITION QT_FEATURE_tslib
+qt_extend_target(InputSupport CONDITION QT_FEATURE_tslib
SOURCES
tslib/qtslib.cpp tslib/qtslib_p.h
PUBLIC_LIBRARIES
PkgConfig::Tslib
)
-extend_target(InputSupport CONDITION QT_FEATURE_libinput
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput
SOURCES
libinput/qlibinputhandler.cpp libinput/qlibinputhandler_p.h
libinput/qlibinputkeyboard.cpp libinput/qlibinputkeyboard_p.h
@@ -87,22 +82,21 @@ extend_target(InputSupport CONDITION QT_FEATURE_libinput
PkgConfig::Libudev
)
-extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
LIBRARIES
- Qt::XkbCommonSupportPrivate
XKB::XKB
PUBLIC_LIBRARIES
- Qt::XkbCommonSupport
+ Qt::XkbCommonSupportPrivate
)
-extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev OR QT_FEATURE_libinput
SOURCES
shared/devicehandlerlist_p.h
shared/qevdevutil.cpp shared/qevdevutil_p.h
shared/qtouchoutputmapping.cpp shared/qtouchoutputmapping_p.h
)
-extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
+qt_extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
SOURCES
integrityhid/qintegrityhidmanager.cpp integrityhid/qintegrityhidmanager.h
LIBRARIES
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
index 6a53ad2088..a729eeb851 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
@@ -99,8 +99,7 @@ std::unique_ptr<QEvdevMouseHandler> QEvdevMouseHandler::create(const QString &de
}
QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool abs, bool compression, int jitterLimit)
- : m_device(device), m_fd(fd), m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
- m_abs(abs), m_compression(compression), m_buttons(0), m_prevInvalid(true)
+ : m_device(device), m_fd(fd), m_abs(abs), m_compression(compression)
{
setObjectName(QLatin1String("Evdev Mouse Handler"));
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
index 727f1a02f9..93314e885f 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler_p.h
@@ -84,16 +84,16 @@ private:
QString m_device;
int m_fd;
- QSocketNotifier *m_notify;
- int m_x, m_y;
- int m_prevx, m_prevy;
+ QSocketNotifier *m_notify = nullptr;
+ int m_x = 0, m_y = 0;
+ int m_prevx = 0, m_prevy = 0;
bool m_abs;
bool m_compression;
Qt::MouseButtons m_buttons;
Qt::MouseButton m_button;
QEvent::Type m_eventType;
int m_jitterLimitSquared;
- bool m_prevInvalid;
+ bool m_prevInvalid = true;
int m_hardwareWidth;
int m_hardwareHeight;
qreal m_hardwareScalerY;
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index c51db59e1f..78728ef4ce 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -113,16 +113,13 @@ public:
QList<QWindowSystemInterface::TouchPoint> m_lastTouchPoints;
struct Contact {
- int trackingId;
- int x;
- int y;
- int maj;
- int pressure;
- Qt::TouchPointState state;
+ int trackingId = -1;
+ int x = 0;
+ int y = 0;
+ int maj = -1;
+ int pressure = 0;
+ Qt::TouchPointState state = Qt::TouchPointPressed;
QTouchEvent::TouchPoint::InfoFlags flags;
- Contact() : trackingId(-1),
- x(0), y(0), maj(-1), pressure(0),
- state(Qt::TouchPointPressed), flags(0) { }
};
QHash<int, Contact> m_contacts; // The key is a tracking id for type A, slot number for type B.
QHash<int, Contact> m_lastContacts;
diff --git a/src/platformsupport/input/integrityhid/qintegrityhidmanager.h b/src/platformsupport/input/integrityhid/qintegrityhidmanager.h
index 36d7587457..fde5fd7dbb 100644
--- a/src/platformsupport/input/integrityhid/qintegrityhidmanager.h
+++ b/src/platformsupport/input/integrityhid/qintegrityhidmanager.h
@@ -52,7 +52,7 @@ class QIntegrityHIDManager : public QThread
{
Q_OBJECT
public:
- QIntegrityHIDManager(const QString &key, const QString &specification, QObject *parent = 0);
+ QIntegrityHIDManager(const QString &key, const QString &specification, QObject *parent = nullptr);
~QIntegrityHIDManager();
void run(void);
diff --git a/src/platformsupport/input/libinput/qlibinputtouch.cpp b/src/platformsupport/input/libinput/qlibinputtouch.cpp
index a65bc91c39..446218e4b3 100644
--- a/src/platformsupport/input/libinput/qlibinputtouch.cpp
+++ b/src/platformsupport/input/libinput/qlibinputtouch.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qlibinputtouch_p.h"
+#include "qtouchoutputmapping_p.h"
#include <libinput.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
@@ -45,6 +46,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(qLcLibInput)
+
QWindowSystemInterface::TouchPoint *QLibInputTouch::DeviceState::point(int32_t slot)
{
const int id = qMax(0, slot);
@@ -62,12 +65,23 @@ QLibInputTouch::DeviceState *QLibInputTouch::deviceState(libinput_event_touch *e
return &m_devState[dev];
}
-static inline QPointF getPos(libinput_event_touch *e)
+QPointF QLibInputTouch::getPos(libinput_event_touch *e)
{
- // TODO Map to correct screen using QTouchOutputMapping.
- // Perhaps investigate libinput_device_get_output_name as well.
- // For now just use the primary screen.
+ DeviceState *state = deviceState(e);
QScreen *screen = QGuiApplication::primaryScreen();
+ if (!state->m_screenName.isEmpty()) {
+ if (!m_screen) {
+ const QList<QScreen *> screens = QGuiApplication::screens();
+ for (QScreen *s : screens) {
+ if (s->name() == state->m_screenName) {
+ m_screen = s;
+ break;
+ }
+ }
+ }
+ if (m_screen)
+ screen = m_screen;
+ }
const QRect geom = QHighDpi::toNativePixels(screen->geometry(), screen);
const double x = libinput_event_touch_get_x_transformed(e, geom.width());
const double y = libinput_event_touch_get_y_transformed(e, geom.height());
@@ -76,9 +90,25 @@ static inline QPointF getPos(libinput_event_touch *e)
void QLibInputTouch::registerDevice(libinput_device *dev)
{
+ struct udev_device *udev_device;
+ udev_device = libinput_device_get_udev_device(dev);
+ QString devNode = QString::fromUtf8(udev_device_get_devnode(udev_device));
+ QString devName = QString::fromUtf8(libinput_device_get_name(dev));
+
+ qCDebug(qLcLibInput, "libinput: registerDevice %s - %s",
+ qPrintable(devNode), qPrintable(devName));
+
+ QTouchOutputMapping mapping;
+ if (mapping.load()) {
+ m_devState[dev].m_screenName = mapping.screenNameForDeviceNode(devNode);
+ if (!m_devState[dev].m_screenName.isEmpty())
+ qCDebug(qLcLibInput, "libinput: Mapping device %s to screen %s",
+ qPrintable(devNode), qPrintable(m_devState[dev].m_screenName));
+ }
+
QTouchDevice *&td = m_devState[dev].m_touchDevice;
td = new QTouchDevice;
- td->setName(QString::fromUtf8(libinput_device_get_name(dev)));
+ td->setName(devName);
td->setType(QTouchDevice::TouchScreen);
td->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
QWindowSystemInterface::registerTouchDevice(td);
@@ -113,16 +143,16 @@ void QLibInputTouch::processTouchMotion(libinput_event_touch *e)
DeviceState *state = deviceState(e);
QWindowSystemInterface::TouchPoint *tp = state->point(slot);
if (tp) {
+ Qt::TouchPointState tmpState = Qt::TouchPointMoved;
const QPointF p = getPos(e);
- if (tp->area.center() != p) {
+ if (tp->area.center() == p)
+ tmpState = Qt::TouchPointStationary;
+ else
tp->area.moveCenter(p);
- // 'down' may be followed by 'motion' within the same "frame".
- // Handle this by compressing and keeping the Pressed state until the 'frame'.
- if (tp->state != Qt::TouchPointPressed)
- tp->state = Qt::TouchPointMoved;
- } else {
- tp->state = Qt::TouchPointStationary;
- }
+ // 'down' may be followed by 'motion' within the same "frame".
+ // Handle this by compressing and keeping the Pressed state until the 'frame'.
+ if (tp->state != Qt::TouchPointPressed && tp->state != Qt::TouchPointReleased)
+ tp->state = tmpState;
} else {
qWarning("Inconsistent touch state (got 'motion' without 'down')");
}
@@ -136,7 +166,7 @@ void QLibInputTouch::processTouchUp(libinput_event_touch *e)
if (tp) {
tp->state = Qt::TouchPointReleased;
// There may not be a Frame event after the last Up. Work this around.
- Qt::TouchPointStates s = 0;
+ Qt::TouchPointStates s;
for (int i = 0; i < state->m_points.count(); ++i)
s |= state->m_points.at(i).state;
if (s == Qt::TouchPointReleased)
diff --git a/src/platformsupport/input/libinput/qlibinputtouch_p.h b/src/platformsupport/input/libinput/qlibinputtouch_p.h
index 51304e6a21..2682b83b26 100644
--- a/src/platformsupport/input/libinput/qlibinputtouch_p.h
+++ b/src/platformsupport/input/libinput/qlibinputtouch_p.h
@@ -42,6 +42,7 @@
#include <QtCore/QHash>
#include <QtCore/QList>
+#include <QtCore/QPointer>
#include <qpa/qwindowsysteminterface.h>
//
@@ -60,6 +61,7 @@ struct libinput_device;
QT_BEGIN_NAMESPACE
+class QScreen;
class QLibInputTouch
{
public:
@@ -73,15 +75,18 @@ public:
private:
struct DeviceState {
- DeviceState() : m_touchDevice(nullptr) { }
+ DeviceState() : m_touchDevice(nullptr), m_screenName() { }
QWindowSystemInterface::TouchPoint *point(int32_t slot);
QList<QWindowSystemInterface::TouchPoint> m_points;
QTouchDevice *m_touchDevice;
+ QString m_screenName;
};
DeviceState *deviceState(libinput_event_touch *e);
+ QPointF getPos(libinput_event_touch *e);
QHash<libinput_device *, DeviceState> m_devState;
+ mutable QPointer<QScreen> m_screen;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/xkbcommon/CMakeLists.txt b/src/platformsupport/input/xkbcommon/CMakeLists.txt
index 958e00fd06..86d132d912 100644
--- a/src/platformsupport/input/xkbcommon/CMakeLists.txt
+++ b/src/platformsupport/input/xkbcommon/CMakeLists.txt
@@ -4,7 +4,7 @@
## XkbCommonSupport Module:
#####################################################################
-add_qt_module(XkbCommonSupport
+qt_add_module(XkbCommonSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -12,12 +12,9 @@ add_qt_module(XkbCommonSupport
qxkbcommon_3rdparty.cpp
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
XKB::XKB
PRECOMPILED_HEADER
"../../../corelib/global/qt_pch.h"
@@ -25,12 +22,11 @@ add_qt_module(XkbCommonSupport
#### Keys ignored in scope 1:.:.:xkbcommon.pro:<TRUE>:
# MODULE = "xkbcommon_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(XkbCommonSupport CONDITION CLANG AND NOT ICC
+qt_extend_target(XkbCommonSupport CONDITION CLANG AND NOT ICC
COMPILE_OPTIONS
-ftemplate-depth=1024
)
diff --git a/src/platformsupport/kmsconvenience/.prev_CMakeLists.txt b/src/platformsupport/kmsconvenience/.prev_CMakeLists.txt
index a595aa40c8..5b0fd00566 100644
--- a/src/platformsupport/kmsconvenience/.prev_CMakeLists.txt
+++ b/src/platformsupport/kmsconvenience/.prev_CMakeLists.txt
@@ -4,22 +4,18 @@
## KmsSupport Module:
#####################################################################
-add_qt_module(KmsSupport
+qt_add_module(KmsSupport
STATIC
INTERNAL_MODULE
SOURCES
qkmsdevice.cpp qkmsdevice_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::CorePrivate
- Qt::GuiPrivate
PUBLIC_LIBRARIES
Libdrm::Libdrm
- Qt::Core
- Qt::Gui
+ Qt::CorePrivate
+ Qt::GuiPrivate
)
#### Keys ignored in scope 1:.:.:kmsconvenience.pro:<TRUE>:
# MODULE = "kms_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/kmsconvenience/CMakeLists.txt b/src/platformsupport/kmsconvenience/CMakeLists.txt
index 9ea4842e52..8001ee27de 100644
--- a/src/platformsupport/kmsconvenience/CMakeLists.txt
+++ b/src/platformsupport/kmsconvenience/CMakeLists.txt
@@ -6,22 +6,18 @@ qt_find_package(Libdrm) # special case
## KmsSupport Module:
#####################################################################
-add_qt_module(KmsSupport
+qt_add_module(KmsSupport
STATIC
INTERNAL_MODULE
SOURCES
qkmsdevice.cpp qkmsdevice_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::CorePrivate
- Qt::GuiPrivate
PUBLIC_LIBRARIES
Libdrm::Libdrm
- Qt::Core
- Qt::Gui
+ Qt::CorePrivate
+ Qt::GuiPrivate
)
#### Keys ignored in scope 1:.:.:kmsconvenience.pro:<TRUE>:
# MODULE = "kms_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index 06d1251a65..8cd7f9b368 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -176,6 +176,15 @@ static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode)
return true;
}
+static inline void assignPlane(QKmsOutput *output, QKmsPlane *plane)
+{
+ if (output->eglfs_plane)
+ output->eglfs_plane->activeCrtcId = 0;
+
+ plane->activeCrtcId = output->crtc_id;
+ output->eglfs_plane = plane;
+}
+
QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
drmModeConnectorPtr connector,
ScreenInfo *vinfo)
@@ -253,7 +262,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
// Get the current mode on the current crtc
drmModeModeInfo crtc_mode;
memset(&crtc_mode, 0, sizeof crtc_mode);
- if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->connector_id)) {
+ if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoder_id)) {
drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id);
drmModeFreeEncoder(encoder);
@@ -449,13 +458,16 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
#endif
QString planeListStr;
- for (const QKmsPlane &plane : qAsConst(m_planes)) {
+ for (QKmsPlane &plane : m_planes) {
if (plane.possibleCrtcs & (1 << output.crtc_index)) {
output.available_planes.append(plane);
planeListStr.append(QString::number(plane.id));
planeListStr.append(QLatin1Char(' '));
- if (plane.type == QKmsPlane::PrimaryPlane)
- output.eglfs_plane = (QKmsPlane*)&plane;
+
+ // Choose the first primary plane that is not already assigned to
+ // another screen's associated crtc.
+ if (!output.eglfs_plane && plane.type == QKmsPlane::PrimaryPlane && !plane.activeCrtcId)
+ assignPlane(&output, &plane);
}
}
qCDebug(qLcKmsDebug, "Output %s can use %d planes: %s",
@@ -477,9 +489,11 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
qCDebug(qLcKmsDebug, "Forcing plane index %d, plane id %u (belongs to crtc id %u)",
idx, plane->plane_id, plane->crtc_id);
- for (const QKmsPlane &kmsplane : qAsConst(m_planes)) {
- if (kmsplane.id == output.forced_plane_id)
- output.eglfs_plane = (QKmsPlane*)&kmsplane;
+ for (QKmsPlane &kmsplane : m_planes) {
+ if (kmsplane.id == output.forced_plane_id) {
+ assignPlane(&output, &kmsplane);
+ break;
+ }
}
drmModeFreePlane(plane);
@@ -490,8 +504,37 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
}
}
- if (output.eglfs_plane)
- qCDebug(qLcKmsDebug, "Output eglfs plane is: %d", output.eglfs_plane->id);
+ // A more useful version: allows specifying "crtc_id,plane_id:crtc_id,plane_id:..."
+ // in order to allow overriding the plane used for a given crtc.
+ if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_KMS_PLANES_FOR_CRTCS")) {
+ const QString val = qEnvironmentVariable("QT_QPA_EGLFS_KMS_PLANES_FOR_CRTCS");
+ qCDebug(qLcKmsDebug, "crtc_id:plane_id override list: %s", qPrintable(val));
+ const QStringList crtcPlanePairs = val.split(QLatin1Char(':'));
+ for (const QString &crtcPlanePair : crtcPlanePairs) {
+ const QStringList values = crtcPlanePair.split(QLatin1Char(','));
+ if (values.count() == 2 && uint(values[0].toInt()) == output.crtc_id) {
+ uint planeId = values[1].toInt();
+ for (QKmsPlane &kmsplane : m_planes) {
+ if (kmsplane.id == planeId) {
+ assignPlane(&output, &kmsplane);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (output.eglfs_plane) {
+ qCDebug(qLcKmsDebug, "Chose plane %u for output %s (crtc id %u) (may not be applicable)",
+ output.eglfs_plane->id, connectorName.constData(), output.crtc_id);
+ }
+
+#if QT_CONFIG(drm_atomic)
+ if (hasAtomicSupport() && !output.eglfs_plane) {
+ qCDebug(qLcKmsDebug, "No plane associated with output %s (crtc id %u) and atomic modesetting is enabled. This is bad.",
+ connectorName.constData(), output.crtc_id);
+ }
+#endif
m_crtc_allocator |= (1 << output.crtc_index);
@@ -538,10 +581,6 @@ QKmsDevice::QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
, m_path(path)
, m_dri_fd(-1)
, m_has_atomic_support(false)
-#if QT_CONFIG(drm_atomic)
- , m_atomic_request(nullptr)
- , m_previous_request(nullptr)
-#endif
, m_crtc_allocator(0)
{
if (m_path.isEmpty()) {
@@ -557,7 +596,7 @@ QKmsDevice::QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
QKmsDevice::~QKmsDevice()
{
#if QT_CONFIG(drm_atomic)
- atomicReset();
+ threadLocalAtomicReset();
#endif
}
@@ -834,7 +873,7 @@ void QKmsDevice::discoverPlanes()
plane.type = QKmsPlane::Type(value);
} else if (!strcmp(prop->name, "rotation")) {
plane.initialRotation = QKmsPlane::Rotations(int(value));
- plane.availableRotations = 0;
+ plane.availableRotations = { };
if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
for (int i = 0; i < prop->count_enums; ++i)
plane.availableRotations |= QKmsPlane::Rotation(1 << prop->enums[i].value);
@@ -897,39 +936,51 @@ bool QKmsDevice::hasAtomicSupport()
}
#if QT_CONFIG(drm_atomic)
-drmModeAtomicReq * QKmsDevice::atomic_request()
+drmModeAtomicReq *QKmsDevice::threadLocalAtomicRequest()
{
- if (!m_atomic_request && m_has_atomic_support)
- m_atomic_request = drmModeAtomicAlloc();
+ if (!m_has_atomic_support)
+ return nullptr;
+
+ AtomicReqs &a(m_atomicReqs.localData());
+ if (!a.request)
+ a.request = drmModeAtomicAlloc();
- return m_atomic_request;
+ return a.request;
}
-bool QKmsDevice::atomicCommit(void *user_data)
+bool QKmsDevice::threadLocalAtomicCommit(void *user_data)
{
- if (m_atomic_request) {
- int ret = drmModeAtomicCommit(m_dri_fd, m_atomic_request,
- DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET, user_data);
+ if (!m_has_atomic_support)
+ return false;
- if (ret) {
- qWarning("Failed to commit atomic request (code=%d)", ret);
- return false;
- }
+ AtomicReqs &a(m_atomicReqs.localData());
+ if (!a.request)
+ return false;
- m_previous_request = m_atomic_request;
- m_atomic_request = nullptr;
+ int ret = drmModeAtomicCommit(m_dri_fd, a.request,
+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET,
+ user_data);
- return true;
+ if (ret) {
+ qWarning("Failed to commit atomic request (code=%d)", ret);
+ return false;
}
- return false;
+ a.previous_request = a.request;
+ a.request = nullptr;
+
+ return true;
}
-void QKmsDevice::atomicReset()
+void QKmsDevice::threadLocalAtomicReset()
{
- if (m_previous_request) {
- drmModeAtomicFree(m_previous_request);
- m_previous_request = nullptr;
+ if (!m_has_atomic_support)
+ return;
+
+ AtomicReqs &a(m_atomicReqs.localData());
+ if (a.previous_request) {
+ drmModeAtomicFree(a.previous_request);
+ a.previous_request = nullptr;
}
}
#endif
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
index b1150e2875..55a590cfce 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h
+++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
@@ -57,6 +57,7 @@
#include <qpa/qplatformscreen.h>
#include <QtCore/QMap>
#include <QtCore/QVariant>
+#include <QtCore/QThreadStorage>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -179,6 +180,8 @@ struct QKmsPlane
uint32_t crtcheightPropertyId = 0;
uint32_t zposPropertyId = 0;
uint32_t blendOpPropertyId = 0;
+
+ uint32_t activeCrtcId = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QKmsPlane::Rotations)
@@ -239,10 +242,9 @@ public:
bool hasAtomicSupport();
#if QT_CONFIG(drm_atomic)
- bool atomicCommit(void *user_data);
- void atomicReset();
-
- drmModeAtomicReq *atomic_request();
+ drmModeAtomicReq *threadLocalAtomicRequest();
+ bool threadLocalAtomicCommit(void *user_data);
+ void threadLocalAtomicReset();
#endif
void createScreens();
@@ -282,8 +284,11 @@ protected:
bool m_has_atomic_support;
#if QT_CONFIG(drm_atomic)
- drmModeAtomicReq *m_atomic_request;
- drmModeAtomicReq *m_previous_request;
+ struct AtomicReqs {
+ drmModeAtomicReq *request = nullptr;
+ drmModeAtomicReq *previous_request = nullptr;
+ };
+ QThreadStorage<AtomicReqs> m_atomicReqs;
#endif
quint32 m_crtc_allocator;
diff --git a/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt b/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt
index c6f7aba91b..38d3d2831f 100644
--- a/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt
+++ b/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt
@@ -4,7 +4,7 @@
## LinuxAccessibilitySupport Module:
#####################################################################
-add_qt_module(LinuxAccessibilitySupport
+qt_add_module(LinuxAccessibilitySupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -27,20 +27,15 @@ add_qt_module(LinuxAccessibilitySupport
"-i" "struct_marshallers_p.h"
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::AccessibilitySupportPrivate
- Qt::CorePrivate
- Qt::GuiPrivate
PUBLIC_LIBRARIES
PkgConfig::ATSPI2_nolink
- Qt::AccessibilitySupport
- Qt::Core
+ Qt::AccessibilitySupportPrivate
+ Qt::CorePrivate
Qt::DBus
- Qt::Gui
+ Qt::GuiPrivate
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:linuxaccessibility.pro:<TRUE>:
# MODULE = "linuxaccessibility_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/linuxaccessibility/CMakeLists.txt b/src/platformsupport/linuxaccessibility/CMakeLists.txt
index 22681afa60..35bfdabf5f 100644
--- a/src/platformsupport/linuxaccessibility/CMakeLists.txt
+++ b/src/platformsupport/linuxaccessibility/CMakeLists.txt
@@ -6,7 +6,7 @@ qt_find_package(ATSPI2) # special case
## LinuxAccessibilitySupport Module:
#####################################################################
-add_qt_module(LinuxAccessibilitySupport
+qt_add_module(LinuxAccessibilitySupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -29,20 +29,15 @@ add_qt_module(LinuxAccessibilitySupport
"-i" "struct_marshallers_p.h"
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt::AccessibilitySupportPrivate
- Qt::CorePrivate
- Qt::GuiPrivate
PUBLIC_LIBRARIES
PkgConfig::ATSPI2_nolink
- Qt::AccessibilitySupport
- Qt::Core
+ Qt::AccessibilitySupportPrivate
+ Qt::CorePrivate
Qt::DBus
- Qt::Gui
+ Qt::GuiPrivate
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:linuxaccessibility.pro:<TRUE>:
# MODULE = "linuxaccessibility_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index 8a825f8284..012edc82e4 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -958,7 +958,7 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event)
textRemoved = textEvent->textRemoved();
changePosition = textEvent->changePosition();
cursorPosition = textEvent->cursorPosition();
- } else if (event->type() == QAccessible::TextInserted) {
+ } else if (event->type() == QAccessible::TextUpdated) {
QAccessibleTextUpdateEvent *textEvent = static_cast<QAccessibleTextUpdateEvent*>(event);
textInserted = textEvent->textInserted();
textRemoved = textEvent->textRemoved();
@@ -2230,7 +2230,7 @@ bool AtSpiAdaptor::valueInterface(QAccessibleInterface *interface, const QString
return false;
if (function == QLatin1String("SetCurrentValue")) {
- QDBusVariant v = message.arguments().at(2).value<QDBusVariant>();
+ QDBusVariant v = qvariant_cast<QDBusVariant>(message.arguments().at(2));
double value = v.variant().toDouble();
//Temporary fix
//See https://bugzilla.gnome.org/show_bug.cgi?id=652596
@@ -2250,7 +2250,7 @@ bool AtSpiAdaptor::valueInterface(QAccessibleInterface *interface, const QString
qCDebug(lcAccessibilityAtspi) << "WARNING: AtSpiAdaptor::valueInterface does not implement " << function << message.path();
return false;
}
- if (!value.canConvert(QVariant::Double)) {
+ if (!value.canConvert(QMetaType::Double)) {
qCDebug(lcAccessibilityAtspi) << "AtSpiAdaptor::valueInterface: Could not convert to double: " << function;
}
diff --git a/src/platformsupport/linuxofono/CMakeLists.txt b/src/platformsupport/linuxofono/CMakeLists.txt
new file mode 100644
index 0000000000..ba8bc97dd6
--- /dev/null
+++ b/src/platformsupport/linuxofono/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Generated from linuxofono.pro.
+
+#####################################################################
+## LinuxOfonoSupport Module:
+#####################################################################
+
+add_qt_module(LinuxOfonoSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qofonoservice_linux.cpp qofonoservice_linux_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::DBus
+)
+
+#### Keys ignored in scope 1:.:.:linuxofono.pro:<TRUE>:
+# MODULE = "linuxofono_support"
diff --git a/src/platformsupport/linuxofono/linuxofono.pro b/src/platformsupport/linuxofono/linuxofono.pro
new file mode 100644
index 0000000000..1bc5b10225
--- /dev/null
+++ b/src/platformsupport/linuxofono/linuxofono.pro
@@ -0,0 +1,15 @@
+TARGET = QtLinuxOfonoSupport
+MODULE = linuxofono_support
+
+QT = core dbus
+CONFIG += static internal_module
+
+DEFINES += QT_NO_CAST_FROM_ASCII
+
+HEADERS += \
+ qofonoservice_linux_p.h
+
+SOURCES += \
+ qofonoservice_linux.cpp
+
+load(qt_module)
diff --git a/src/platformsupport/linuxofono/qofonoservice_linux.cpp b/src/platformsupport/linuxofono/qofonoservice_linux.cpp
new file mode 100644
index 0000000000..792c703966
--- /dev/null
+++ b/src/platformsupport/linuxofono/qofonoservice_linux.cpp
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QObject>
+#include <QList>
+#include <QtDBus/QtDBus>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusError>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusPendingCallWatcher>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusPendingCall>
+
+#include "qofonoservice_linux_p.h"
+
+#ifndef QT_NO_DBUS
+
+QDBusArgument &operator<<(QDBusArgument &argument, const ObjectPathProperties &item)
+{
+ argument.beginStructure();
+ argument << item.path << item.properties;
+ argument.endStructure();
+ return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, ObjectPathProperties &item)
+{
+ argument.beginStructure();
+ argument >> item.path >> item.properties;
+ argument.endStructure();
+ return argument;
+}
+
+QT_BEGIN_NAMESPACE
+
+QOfonoManagerInterface::QOfonoManagerInterface( QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ QLatin1String(OFONO_MANAGER_PATH),
+ OFONO_MANAGER_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+ qDBusRegisterMetaType<ObjectPathProperties>();
+ qDBusRegisterMetaType<PathPropertiesList>();
+
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ QLatin1String(OFONO_MANAGER_PATH),
+ QLatin1String(OFONO_MANAGER_INTERFACE),
+ QLatin1String("ModemAdded"),
+ this,SLOT(modemAdded(QDBusObjectPath,QVariantMap)));
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ QLatin1String(OFONO_MANAGER_PATH),
+ QLatin1String(OFONO_MANAGER_INTERFACE),
+ QLatin1String("ModemRemoved"),
+ this,SLOT(modemRemoved(QDBusObjectPath)));
+}
+
+QOfonoManagerInterface::~QOfonoManagerInterface()
+{
+}
+
+QStringList QOfonoManagerInterface::getModems()
+{
+ if (modemList.isEmpty()) {
+ QDBusPendingReply<PathPropertiesList> reply = call(QDBus::Block, QLatin1String("GetModems"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ const auto modems = reply.value();
+ for (const ObjectPathProperties &modem : modems)
+ modemList << modem.path.path();
+ }
+ }
+
+ return modemList;
+}
+
+QString QOfonoManagerInterface::currentModem()
+{
+ const QStringList modems = getModems();
+ for (const QString &modem : modems) {
+ QOfonoModemInterface device(modem);
+ if (device.isPowered() && device.isOnline()
+ && device.interfaces().contains(QLatin1String("org.ofono.NetworkRegistration")))
+ return modem;
+ }
+ return QString();
+}
+
+void QOfonoManagerInterface::modemAdded(const QDBusObjectPath &path, const QVariantMap &/*var*/)
+{
+ if (!modemList.contains(path.path())) {
+ modemList << path.path();
+ Q_EMIT modemChanged();
+ }
+}
+
+void QOfonoManagerInterface::modemRemoved(const QDBusObjectPath &path)
+{
+ if (modemList.contains(path.path())) {
+ modemList.removeOne(path.path());
+ Q_EMIT modemChanged();
+ }
+}
+
+
+QOfonoModemInterface::QOfonoModemInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ dbusPathName,
+ OFONO_MODEM_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ path(),
+ QLatin1String(OFONO_MODEM_INTERFACE),
+ QLatin1String("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
+}
+
+QOfonoModemInterface::~QOfonoModemInterface()
+{
+}
+
+void QOfonoModemInterface::propertyChanged(const QString &name,const QDBusVariant &value)
+{
+ propertiesMap[name] = value.variant();
+}
+
+bool QOfonoModemInterface::isPowered()
+{
+ QVariant var = getProperty(QStringLiteral("Powered"));
+ return qdbus_cast<bool>(var);
+}
+
+bool QOfonoModemInterface::isOnline()
+{
+ QVariant var = getProperty(QStringLiteral("Online"));
+ return qdbus_cast<bool>(var);
+}
+
+QStringList QOfonoModemInterface::interfaces()
+{
+ const QVariant var = getProperty(QStringLiteral("Interfaces"));
+ return var.toStringList();
+}
+
+QVariantMap QOfonoModemInterface::getProperties()
+{
+ if (propertiesMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties"));
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ }
+ }
+ return propertiesMap;
+}
+
+QVariant QOfonoModemInterface::getProperty(const QString &property)
+{
+ QVariant var;
+ QVariantMap map = getProperties();
+ if (map.contains(property))
+ var = map.value(property);
+ return var;
+}
+
+
+QOfonoNetworkRegistrationInterface::QOfonoNetworkRegistrationInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ dbusPathName,
+ OFONO_NETWORK_REGISTRATION_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+}
+
+QOfonoNetworkRegistrationInterface::~QOfonoNetworkRegistrationInterface()
+{
+}
+
+QString QOfonoNetworkRegistrationInterface::getTechnology()
+{
+ QVariant var = getProperty(QStringLiteral("Technology"));
+ return qdbus_cast<QString>(var);
+}
+
+QVariant QOfonoNetworkRegistrationInterface::getProperty(const QString &property)
+{
+ QVariant var;
+ QVariantMap map = getProperties();
+ if (map.contains(property))
+ var = map.value(property);
+ return var;
+}
+
+QVariantMap QOfonoNetworkRegistrationInterface::getProperties()
+{
+ if (propertiesMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ }
+ }
+ return propertiesMap;
+}
+
+QOfonoDataConnectionManagerInterface::QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ dbusPathName,
+ OFONO_DATA_CONNECTION_MANAGER_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ path(),
+ QLatin1String(OFONO_MODEM_INTERFACE),
+ QLatin1String("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
+}
+
+QOfonoDataConnectionManagerInterface::~QOfonoDataConnectionManagerInterface()
+{
+}
+
+QStringList QOfonoDataConnectionManagerInterface::contexts()
+{
+ if (contextList.isEmpty()) {
+ QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ const auto contexts = reply.value();
+ for (const ObjectPathProperties &context : contexts)
+ contextList << context.path.path();
+ }
+ }
+ return contextList;
+}
+
+PathPropertiesList QOfonoDataConnectionManagerInterface::contextsWithProperties()
+{
+ if (contextListProperties.isEmpty()) {
+ QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ contextListProperties = reply.value();
+ }
+ }
+ return contextListProperties;
+}
+
+bool QOfonoDataConnectionManagerInterface::roamingAllowed()
+{
+ QVariant var = getProperty(QStringLiteral("RoamingAllowed"));
+ return qdbus_cast<bool>(var);
+}
+
+QString QOfonoDataConnectionManagerInterface::bearer()
+{
+ QVariant var = getProperty(QStringLiteral("Bearer"));
+ return qdbus_cast<QString>(var);
+}
+
+QVariant QOfonoDataConnectionManagerInterface::getProperty(const QString &property)
+{
+ return getProperties().value(property);
+}
+
+QVariantMap &QOfonoDataConnectionManagerInterface::getProperties()
+{
+ if (propertiesMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties"));
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ }
+ }
+ return propertiesMap;
+}
+
+void QOfonoDataConnectionManagerInterface::propertyChanged(const QString &name, const QDBusVariant &value)
+{
+ propertiesMap[name] = value.variant();
+ if (name == QLatin1String("RoamingAllowed"))
+ Q_EMIT roamingAllowedChanged(value.variant().toBool());
+}
+
+
+QOfonoConnectionContextInterface::QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ dbusPathName,
+ OFONO_CONNECTION_CONTEXT_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ path(),
+ QLatin1String(OFONO_MODEM_INTERFACE),
+ QLatin1String("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
+}
+
+QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface()
+{
+}
+
+QVariantMap QOfonoConnectionContextInterface::getProperties()
+{
+ if (propertiesMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties"));
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ }
+ }
+ return propertiesMap;
+}
+
+void QOfonoConnectionContextInterface::propertyChanged(const QString &name, const QDBusVariant &value)
+{
+ propertiesMap[name] = value.variant();
+}
+
+QVariant QOfonoConnectionContextInterface::getProperty(const QString &property)
+{
+ QVariant var;
+ QVariantMap map = getProperties();
+ if (map.contains(property))
+ var = map.value(property);
+ return var;
+}
+
+bool QOfonoConnectionContextInterface::active()
+{
+ QVariant var = getProperty(QStringLiteral("Active"));
+ return qdbus_cast<bool>(var);
+}
+
+QString QOfonoConnectionContextInterface::accessPointName()
+{
+ QVariant var = getProperty(QStringLiteral("AccessPointName"));
+ return qdbus_cast<QString>(var);
+}
+
+QString QOfonoConnectionContextInterface::name()
+{
+ QVariant var = getProperty(QStringLiteral("Name"));
+ return qdbus_cast<QString>(var);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DBUS
diff --git a/src/platformsupport/linuxofono/qofonoservice_linux_p.h b/src/platformsupport/linuxofono/qofonoservice_linux_p.h
new file mode 100644
index 0000000000..62df5d4fa7
--- /dev/null
+++ b/src/platformsupport/linuxofono/qofonoservice_linux_p.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOFONOSERVICE_H
+#define QOFONOSERVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtDBus/QtDBus>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusError>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+
+#include <QtDBus/QDBusPendingCallWatcher>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusContext>
+#include <QMap>
+
+#ifndef QT_NO_DBUS
+
+#define OFONO_SERVICE "org.ofono"
+#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
+#define OFONO_MANAGER_PATH "/"
+
+#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
+#define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration"
+#define OFONO_DATA_CONNECTION_MANAGER_INTERFACE "org.ofono.ConnectionManager"
+#define OFONO_CONNECTION_CONTEXT_INTERFACE "org.ofono.ConnectionContext"
+
+QT_BEGIN_NAMESPACE
+
+QT_END_NAMESPACE
+
+struct ObjectPathProperties
+{
+ QDBusObjectPath path;
+ QVariantMap properties;
+};
+QT_BEGIN_NAMESPACE
+Q_DECLARE_TYPEINFO(ObjectPathProperties, Q_MOVABLE_TYPE); // QDBusObjectPath is movable, but cannot be
+ // marked as such until Qt 6
+QT_END_NAMESPACE
+
+typedef QVector<ObjectPathProperties> PathPropertiesList;
+Q_DECLARE_METATYPE(ObjectPathProperties)
+Q_DECLARE_METATYPE (PathPropertiesList)
+
+QT_BEGIN_NAMESPACE
+
+class QOfonoManagerInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ QOfonoManagerInterface( QObject *parent = nullptr);
+ ~QOfonoManagerInterface();
+
+ QStringList getModems();
+ QString currentModem();
+signals:
+ void modemChanged();
+private:
+ QStringList modemList;
+private slots:
+ void modemAdded(const QDBusObjectPath &path, const QVariantMap &var);
+ void modemRemoved(const QDBusObjectPath &path);
+};
+
+class QOfonoModemInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ explicit QOfonoModemInterface(const QString &dbusModemPathName, QObject *parent = nullptr);
+ ~QOfonoModemInterface();
+
+ bool isPowered();
+ bool isOnline();
+ QStringList interfaces();
+private:
+ QVariantMap getProperties();
+ QVariantMap propertiesMap;
+ QVariant getProperty(const QString &);
+ void propertyChanged(const QString &, const QDBusVariant &value);
+};
+
+
+class QOfonoNetworkRegistrationInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ explicit QOfonoNetworkRegistrationInterface(const QString &dbusModemPathName, QObject *parent = nullptr);
+ ~QOfonoNetworkRegistrationInterface();
+
+ QString getTechnology();
+
+private:
+ QVariantMap getProperties();
+ QVariant getProperty(const QString &);
+ QVariantMap propertiesMap;
+Q_SIGNALS:
+ void propertyChanged(const QString &, const QDBusVariant &value);
+};
+
+class QOfonoDataConnectionManagerInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ explicit QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent = nullptr);
+ ~QOfonoDataConnectionManagerInterface();
+
+ QStringList contexts();
+ PathPropertiesList contextsWithProperties();
+ bool roamingAllowed();
+ QVariant getProperty(const QString &);
+ QString bearer();
+Q_SIGNALS:
+ void roamingAllowedChanged(bool);
+private:
+ QVariantMap &getProperties();
+ QVariantMap propertiesMap;
+ QStringList contextList;
+ PathPropertiesList contextListProperties;
+private Q_SLOTS:
+ void propertyChanged(const QString &, const QDBusVariant &value);
+};
+
+class QOfonoConnectionContextInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = nullptr);
+ ~QOfonoConnectionContextInterface();
+
+ QVariant getProperty(const QString &);
+ bool active();
+ QString accessPointName();
+ QString name();
+
+Q_SIGNALS:
+private:
+ QVariantMap getProperties();
+ QVariantMap propertiesMap;
+private slots:
+ void propertyChanged(const QString &, const QDBusVariant &value);
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DBUS
+
+#endif //QOFONOSERVICE_H
diff --git a/src/platformsupport/platformcompositor/CMakeLists.txt b/src/platformsupport/platformcompositor/CMakeLists.txt
index 0d3bc597c0..1ddc9e719d 100644
--- a/src/platformsupport/platformcompositor/CMakeLists.txt
+++ b/src/platformsupport/platformcompositor/CMakeLists.txt
@@ -4,22 +4,20 @@
## PlatformCompositorSupport Module:
#####################################################################
-add_qt_module(PlatformCompositorSupport
+qt_add_module(PlatformCompositorSupport
STATIC
INTERNAL_MODULE
SOURCES
qopenglcompositor.cpp qopenglcompositor_p.h
qopenglcompositorbackingstore.cpp qopenglcompositorbackingstore_p.h
+ qplatformbackingstoreopenglsupport.cpp qplatformbackingstoreopenglsupport.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
+ Qt::OpenGL
)
#### Keys ignored in scope 1:.:.:platformcompositor.pro:<TRUE>:
# MODULE = "platformcompositor_support"
-# _LOADED = "qt_module"
diff --git a/src/platformsupport/platformcompositor/platformcompositor.pro b/src/platformsupport/platformcompositor/platformcompositor.pro
index 81c31571d0..89386ab3ef 100644
--- a/src/platformsupport/platformcompositor/platformcompositor.pro
+++ b/src/platformsupport/platformcompositor/platformcompositor.pro
@@ -1,16 +1,18 @@
TARGET = QtPlatformCompositorSupport
MODULE = platformcompositor_support
-QT = core-private gui-private
+QT = core-private gui-private opengl
CONFIG += static internal_module
DEFINES += QT_NO_CAST_FROM_ASCII
SOURCES += \
+ qplatformbackingstoreopenglsupport.cpp \
qopenglcompositor.cpp \
qopenglcompositorbackingstore.cpp
HEADERS += \
+ qplatformbackingstoreopenglsupport.h \
qopenglcompositor_p.h \
qopenglcompositorbackingstore_p.h
diff --git a/src/platformsupport/platformcompositor/qopenglcompositor_p.h b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
index 41a3288240..c9414c82c6 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor_p.h
+++ b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/QTimer>
-#include <QtGui/QOpenGLTextureBlitter>
+#include <QtOpenGL/QOpenGLTextureBlitter>
#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE
diff --git a/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.cpp b/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.cpp
new file mode 100644
index 0000000000..ca50910114
--- /dev/null
+++ b/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.cpp
@@ -0,0 +1,455 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_OPENGL
+
+#include "qplatformbackingstoreopenglsupport.h"
+
+#include <QtGui/private/qwindow_p.h>
+
+#include <qpa/qplatformgraphicsbuffer.h>
+#include <qpa/qplatformgraphicsbufferhelper.h>
+
+#include <QtOpenGL/QOpenGLTextureBlitter>
+#include <QtGui/qopengl.h>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOffscreenSurface>
+
+#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
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
+#ifndef GL_FRAMEBUFFER_SRGB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE
+#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static inline QRect deviceRect(const QRect &rect, QWindow *window)
+{
+ QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
+ rect.size() * window->devicePixelRatio());
+ return deviceRect;
+}
+
+static inline QPoint deviceOffset(const QPoint &pt, QWindow *window)
+{
+ return pt * window->devicePixelRatio();
+}
+
+static QRegion deviceRegion(const QRegion &region, QWindow *window, const QPoint &offset)
+{
+ if (offset.isNull() && window->devicePixelRatio() <= 1)
+ return region;
+
+ QVector<QRect> rects;
+ rects.reserve(region.rectCount());
+ for (const QRect &rect : region)
+ rects.append(deviceRect(rect.translated(offset), window));
+
+ QRegion deviceRegion;
+ deviceRegion.setRects(rects.constData(), rects.count());
+ return deviceRegion;
+}
+
+static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
+{
+ return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
+ topLeftRect.width(), topLeftRect.height());
+}
+
+static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
+ QOpenGLTextureBlitter *blitter, const QPoint &offset, bool canUseSrgb)
+{
+ const QRect clipRect = textures->clipRect(idx);
+ if (clipRect.isEmpty())
+ return;
+
+ QRect rectInWindow = textures->geometry(idx);
+ // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
+ rectInWindow.translate(-offset);
+
+ const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
+ const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
+
+ const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window),
+ deviceWindowRect);
+
+ const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window),
+ deviceRect(rectInWindow, window).size(),
+ QOpenGLTextureBlitter::OriginBottomLeft);
+
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ const bool srgb = textures->flags(idx).testFlag(QPlatformTextureList::TextureIsSrgb);
+ if (srgb && canUseSrgb)
+ funcs->glEnable(GL_FRAMEBUFFER_SRGB);
+
+ blitter->blit(textures->textureId(idx), target, source);
+
+ if (srgb && canUseSrgb)
+ funcs->glDisable(GL_FRAMEBUFFER_SRGB);
+}
+
+QPlatformBackingStoreOpenGLSupport::~QPlatformBackingStoreOpenGLSupport() {
+ if (context) {
+ QOffscreenSurface offscreenSurface;
+ offscreenSurface.setFormat(context->format());
+ offscreenSurface.create();
+ context->makeCurrent(&offscreenSurface);
+ if (textureId)
+ context->functions()->glDeleteTextures(1, &textureId);
+ if (blitter)
+ blitter->destroy();
+ }
+ delete blitter;
+}
+
+void QPlatformBackingStoreOpenGLSupport::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset, QPlatformTextureList *textures, bool translucentBackground)
+{
+ if (!qt_window_private(window)->receivedExpose)
+ return;
+
+ if (!context) {
+ context.reset(new QOpenGLContext);
+ context->setFormat(window->requestedFormat());
+ context->setScreen(window->screen());
+ context->setShareContext(qt_window_private(window)->shareContext());
+ if (!context->create()) {
+ qCWarning(lcQpaBackingStore, "composeAndFlush: QOpenGLContext creation failed");
+ return;
+ }
+ }
+
+ bool current = context->makeCurrent(window);
+
+ if (!current && context->isValid()) {
+ delete blitter;
+ blitter = nullptr;
+ textureId = 0;
+ current = context->create() && context->makeCurrent(window);
+ }
+
+ if (!current) {
+ qCWarning(lcQpaBackingStore, "composeAndFlush: makeCurrent() failed");
+ return;
+ }
+
+ qCDebug(lcQpaBackingStore) << "Composing and flushing" << region << "of" << window
+ << "at offset" << offset << "with" << textures->count() << "texture(s) in" << textures;
+
+ QWindowPrivate::get(window)->lastComposeTime.start();
+
+ QOpenGLFunctions *funcs = context->functions();
+ funcs->glViewport(0, 0, qRound(window->width() * window->devicePixelRatio()), qRound(window->height() * window->devicePixelRatio()));
+ funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1);
+ funcs->glClear(GL_COLOR_BUFFER_BIT);
+
+ if (!blitter) {
+ blitter = new QOpenGLTextureBlitter;
+ blitter->create();
+ }
+
+ blitter->bind();
+
+ const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window);
+ const QPoint deviceWindowOffset = deviceOffset(offset, window);
+
+ bool canUseSrgb = false;
+ // If there are any sRGB textures in the list, check if the destination
+ // framebuffer is sRGB capable.
+ for (int i = 0; i < textures->count(); ++i) {
+ if (textures->flags(i).testFlag(QPlatformTextureList::TextureIsSrgb)) {
+ GLint cap = 0;
+ funcs->glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &cap);
+ if (cap)
+ canUseSrgb = true;
+ break;
+ }
+ }
+
+ // Textures for renderToTexture widgets.
+ for (int i = 0; i < textures->count(); ++i) {
+ if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
+ blitTextureForWidget(textures, i, window, deviceWindowRect, blitter, offset, canUseSrgb);
+ }
+
+ // Backingstore texture with the normal widgets.
+ GLuint textureId = 0;
+ QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft;
+ if (QPlatformGraphicsBuffer *graphicsBuffer = backingStore->graphicsBuffer()) {
+ if (graphicsBuffer->size() != textureSize) {
+ if (this->textureId)
+ funcs->glDeleteTextures(1, &this->textureId);
+ funcs->glGenTextures(1, &this->textureId);
+ funcs->glBindTexture(GL_TEXTURE_2D, this->textureId);
+ 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);
+ }
+ 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);
+ funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &needsSwizzle, &premultiplied)) {
+ textureSize = graphicsBuffer->size();
+ } else {
+ textureSize = QSize(0,0);
+ }
+
+ graphicsBuffer->unlock();
+ } else if (!region.isEmpty()){
+ funcs->glBindTexture(GL_TEXTURE_2D, this->textureId);
+ QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &needsSwizzle, &premultiplied);
+ graphicsBuffer->unlock();
+ }
+
+ if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
+ origin = QOpenGLTextureBlitter::OriginBottomLeft;
+ textureId = this->textureId;
+ } else {
+ QPlatformBackingStore::TextureFlags flags;
+ textureId = backingStore->toTexture(deviceRegion(region, window, offset), &textureSize, &flags);
+ needsSwizzle = (flags & QPlatformBackingStore::TextureSwizzle) != 0;
+ premultiplied = (flags & QPlatformBackingStore::TexturePremultiplied) != 0;
+ if (flags & QPlatformBackingStore::TextureFlip)
+ origin = QOpenGLTextureBlitter::OriginBottomLeft;
+ }
+
+ funcs->glEnable(GL_BLEND);
+ if (premultiplied)
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ else
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+
+ if (textureId) {
+ if (needsSwizzle)
+ blitter->setRedBlueSwizzle(true);
+ // The backingstore is for the entire tlw.
+ // In case of native children offset tells the position relative to the tlw.
+ const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(deviceWindowOffset), textureSize.height());
+ const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect,
+ textureSize,
+ origin);
+ blitter->blit(textureId, QMatrix4x4(), source);
+ if (needsSwizzle)
+ blitter->setRedBlueSwizzle(false);
+ }
+
+ // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
+ bool blendIsPremultiplied = premultiplied;
+ for (int i = 0; i < textures->count(); ++i) {
+ const QPlatformTextureList::Flags flags = textures->flags(i);
+ if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
+ if (!blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = true;
+ }
+ } else {
+ if (blendIsPremultiplied) {
+ funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ blendIsPremultiplied = false;
+ }
+ }
+ if (flags.testFlag(QPlatformTextureList::StacksOnTop))
+ blitTextureForWidget(textures, i, window, deviceWindowRect, blitter, offset, canUseSrgb);
+ }
+
+ funcs->glDisable(GL_BLEND);
+ blitter->release();
+
+ context->swapBuffers(window);
+}
+
+GLuint QPlatformBackingStoreOpenGLSupport::toTexture(const QRegion &dirtyRegion, QSize *textureSize, QPlatformBackingStore::TextureFlags *flags) const
+{
+ Q_ASSERT(textureSize);
+ Q_ASSERT(flags);
+
+ QImage image = backingStore->toImage();
+ QSize imageSize = image.size();
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLenum internalFormat = GL_RGBA;
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+
+ bool needsConversion = false;
+ *flags = { };
+ switch (image.format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ *flags |= QPlatformBackingStore::TexturePremultiplied;
+ Q_FALLTHROUGH();
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ *flags |= QPlatformBackingStore::TextureSwizzle;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ *flags |= QPlatformBackingStore::TexturePremultiplied;
+ Q_FALLTHROUGH();
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ *flags |= QPlatformBackingStore::TexturePremultiplied;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ internalFormat = GL_RGB10_A2;
+ *flags |= QPlatformBackingStore::TextureSwizzle | QPlatformBackingStore::TexturePremultiplied;
+ } else {
+ needsConversion = true;
+ }
+ break;
+ default:
+ needsConversion = true;
+ break;
+ }
+ if (imageSize.isEmpty()) {
+ *textureSize = imageSize;
+ return 0;
+ }
+
+ // Must rely on the input only, not d_ptr.
+ // With the default composeAndFlush() textureSize is &d_ptr->textureSize.
+ bool resized = *textureSize != imageSize;
+ if (dirtyRegion.isEmpty() && !resized)
+ return textureId;
+
+ *textureSize = imageSize;
+
+ if (needsConversion)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+
+ // The image provided by the backingstore may have a stride larger than width * 4, for
+ // instance on platforms that manually implement client-side decorations.
+ static const int bytesPerPixel = 4;
+ const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
+ const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
+
+ QOpenGLFunctions *funcs = ctx->functions();
+
+ if (hasUnpackRowLength) {
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
+ } else if (strideInPixels != image.width()) {
+ // No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
+ // hit with QtWayland which is rarely used in combination with a ES2.0-only GL
+ // implementation. Therefore, accept the performance hit and do a copy.
+ image = image.copy();
+ }
+
+ if (resized) {
+ if (textureId)
+ funcs->glDeleteTextures(1, &textureId);
+ funcs->glGenTextures(1, &textureId);
+ funcs->glBindTexture(GL_TEXTURE_2D, textureId);
+ 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);
+ }
+ 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);
+ funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType,
+ const_cast<uchar*>(image.constBits()));
+ } else {
+ funcs->glBindTexture(GL_TEXTURE_2D, textureId);
+ QRect imageRect = image.rect();
+ QRect rect = dirtyRegion.boundingRect() & imageRect;
+
+ if (hasUnpackRowLength) {
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
+ image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
+ } 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) {
+ rect.setX(0);
+ rect.setWidth(imageRect.width());
+ }
+
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+
+ if (rect.width() == imageRect.width()) {
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
+ image.constScanLine(rect.y()));
+ } else {
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
+ image.copy(rect).constBits());
+ }
+ }
+ }
+
+ if (hasUnpackRowLength)
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ return textureId;
+}
+
+#endif // QT_NO_OPENGL
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.h b/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.h
new file mode 100644
index 0000000000..5523b18f76
--- /dev/null
+++ b/src/platformsupport/platformcompositor/qplatformbackingstoreopenglsupport.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMBACKINGSTOREOPENGLSUPPORT_H
+#define QPLATFORMBACKINGSTOREOPENGLSUPPORT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
+#ifndef QT_NO_OPENGL
+
+#include <QtGui/qtguiglobal.h>
+#include <qpa/qplatformbackingstore.h>
+
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLTextureBlitter;
+class QOpenGLBackingStore;
+
+class QPlatformBackingStoreOpenGLSupport : public QPlatformBackingStoreOpenGLSupportBase
+{
+public:
+ explicit QPlatformBackingStoreOpenGLSupport(QPlatformBackingStore *backingStore) : backingStore(backingStore) {}
+ ~QPlatformBackingStoreOpenGLSupport() override;
+ void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, bool translucentBackground) override;
+ GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, QPlatformBackingStore::TextureFlags *flags) const override;
+
+private:
+ QPlatformBackingStore *backingStore = nullptr;
+ QScopedPointer<QOpenGLContext> context;
+ mutable GLuint textureId = 0;
+ mutable QSize textureSize;
+ mutable bool needsSwizzle = false;
+ mutable bool premultiplied = false;
+ QOpenGLTextureBlitter *blitter = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_OPENGL
+
+#endif // QPLATFORMBACKINGSTOREOPENGLSUPPORT_H
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 6d4f1b93bd..4b41b29c12 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -11,7 +11,7 @@ SUBDIRS = \
qtConfig(freetype)|darwin|win32: \
SUBDIRS += fontdatabases
-qtConfig(evdev)|qtConfig(tslib)|qtConfig(libinput)|qtConfig(integrityhid) {
+qtConfig(evdev)|qtConfig(tslib)|qtConfig(libinput)|qtConfig(integrityhid)|qtConfig(xkbcommon) {
SUBDIRS += input
input.depends += devicediscovery
}
@@ -45,3 +45,7 @@ darwin {
qtConfig(vulkan): \
SUBDIRS += vkconvenience
+
+!android:linux*:qtHaveModule(dbus) \
+ SUBDIRS += linuxofono
+
diff --git a/src/platformsupport/services/CMakeLists.txt b/src/platformsupport/services/CMakeLists.txt
index 59e10a84a4..602dd40305 100644
--- a/src/platformsupport/services/CMakeLists.txt
+++ b/src/platformsupport/services/CMakeLists.txt
@@ -4,31 +4,27 @@
## ServiceSupport Module:
#####################################################################
-add_qt_module(ServiceSupport
+qt_add_module(ServiceSupport
STATIC
INTERNAL_MODULE
SOURCES
genericunix/qgenericunixservices.cpp genericunix/qgenericunixservices_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:services.pro:<TRUE>:
# MODULE = "service_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(ServiceSupport CONDITION QT_FEATURE_dbus
+qt_extend_target(ServiceSupport CONDITION QT_FEATURE_dbus
PUBLIC_LIBRARIES
Qt::DBus
)
diff --git a/src/platformsupport/themes/CMakeLists.txt b/src/platformsupport/themes/CMakeLists.txt
index 0000a9092d..a7be78d0e0 100644
--- a/src/platformsupport/themes/CMakeLists.txt
+++ b/src/platformsupport/themes/CMakeLists.txt
@@ -4,34 +4,30 @@
## ThemeSupport Module:
#####################################################################
-add_qt_module(ThemeSupport
+qt_add_module(ThemeSupport
STATIC
INTERNAL_MODULE
SOURCES
qabstractfileiconengine.cpp qabstractfileiconengine_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
)
#### Keys ignored in scope 1:.:.:themes.pro:<TRUE>:
# MODULE = "theme_support"
-# _LOADED = "qt_module"
## Scopes:
#####################################################################
-extend_target(ThemeSupport CONDITION QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT)
+qt_extend_target(ThemeSupport CONDITION QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT)
SOURCES
genericunix/qgenericunixthemes.cpp genericunix/qgenericunixthemes_p.h
)
-extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT)
+qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT)
SOURCES
genericunix/dbusmenu/qdbusmenuadaptor.cpp genericunix/dbusmenu/qdbusmenuadaptor_p.h
genericunix/dbusmenu/qdbusmenubar.cpp genericunix/dbusmenu/qdbusmenubar_p.h
@@ -45,7 +41,7 @@ extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND (QT_FEATURE_xcb OR UNIX
Qt::DBus
)
-extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND QT_FEATURE_systemtrayicon AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT)
+qt_extend_target(ThemeSupport CONDITION QT_FEATURE_dbus AND QT_FEATURE_systemtrayicon AND (QT_FEATURE_xcb OR UNIX) AND (QT_FEATURE_xcb OR NOT APPLE_UIKIT)
SOURCES
genericunix/dbustray/qdbustrayicon.cpp genericunix/dbustray/qdbustrayicon_p.h
genericunix/dbustray/qdbustraytypes.cpp genericunix/dbustray/qdbustraytypes_p.h
diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp
index 82a13d2fa0..6fadea5d28 100644
--- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp
+++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp
@@ -48,7 +48,9 @@
#include <QDebug>
#include <QtEndian>
#include <QBuffer>
-#include <private/qkeysequence_p.h>
+#if QT_CONFIG(shortcut)
+# include <private/qkeysequence_p.h>
+#endif
#include <qpa/qplatformmenu.h>
#include "qdbusplatformmenu_p.h"
@@ -152,7 +154,7 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &i
while (!arg.atEnd()) {
QDBusVariant dbusVariant;
arg >> dbusVariant;
- QDBusArgument childArgument = dbusVariant.variant().value<QDBusArgument>();
+ QDBusArgument childArgument = qvariant_cast<QDBusArgument>(dbusVariant.variant());
QDBusMenuLayoutItem child;
childArgument >> child;
diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h
index 8a31f82fb0..aa0f303416 100644
--- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h
+++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h
@@ -96,7 +96,7 @@ public:
void setChecked(bool isChecked) override;
bool hasExclusiveGroup() const { return m_hasExclusiveGroup; }
void setHasExclusiveGroup(bool hasExclusiveGroup) override;
-#ifndef QT_NO_SHORTCUT
+#if QT_CONFIG(shortcut)
QKeySequence shortcut() const { return m_shortcut; }
void setShortcut(const QKeySequence& shortcut) override;
#endif
@@ -123,7 +123,9 @@ private:
bool m_hasExclusiveGroup : 1;
short /*unused*/ : 6;
short m_dbusID : 16;
+#if QT_CONFIG(shortcut)
QKeySequence m_shortcut;
+#endif
};
class QDBusPlatformMenu : public QPlatformMenu
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 70d5616075..36d9e4e065 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -517,7 +517,7 @@ QFont *QKdeThemePrivate::kdeFont(const QVariant &fontValue)
// causing recursion.
QString fontDescription;
QString fontFamily;
- if (fontValue.type() == QVariant::StringList) {
+ if (fontValue.userType() == QMetaType::QStringList) {
const QStringList list = fontValue.toStringList();
if (!list.isEmpty()) {
fontFamily = list.first();
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
index c0da9d8370..f6acf00f39 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
@@ -109,7 +109,7 @@ public:
QVariant themeHint(ThemeHint hint) const override;
QIcon fileIcon(const QFileInfo &fileInfo,
- QPlatformTheme::IconOptions iconOptions = nullptr) const override;
+ QPlatformTheme::IconOptions iconOptions = { }) const override;
const QPalette *palette(Palette type = SystemPalette) const override;
@@ -134,7 +134,7 @@ public:
QGnomeTheme();
QVariant themeHint(ThemeHint hint) const override;
QIcon fileIcon(const QFileInfo &fileInfo,
- QPlatformTheme::IconOptions = nullptr) const override;
+ QPlatformTheme::IconOptions = { }) const override;
const QFont *font(Font type) const override;
QString standardButtonText(int button) const override;
diff --git a/src/platformsupport/vkconvenience/.prev_CMakeLists.txt b/src/platformsupport/vkconvenience/.prev_CMakeLists.txt
index 4de17b99c0..6f17cfa306 100644
--- a/src/platformsupport/vkconvenience/.prev_CMakeLists.txt
+++ b/src/platformsupport/vkconvenience/.prev_CMakeLists.txt
@@ -4,7 +4,7 @@
## VulkanSupport Module:
#####################################################################
-add_qt_module(VulkanSupport
+qt_add_module(VulkanSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -12,16 +12,20 @@ add_qt_module(VulkanSupport
qvkconvenience.cpp qvkconvenience_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:vkconvenience.pro:<TRUE>:
# MODULE = "vulkan_support"
-# _LOADED = "qt_module"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(VulkanSupport CONDITION QT_FEATURE_opengl
+ PUBLIC_LIBRARIES
+ Qt::OpenGL
+)
diff --git a/src/platformsupport/vkconvenience/CMakeLists.txt b/src/platformsupport/vkconvenience/CMakeLists.txt
index ee7e1c560c..6ec2574375 100644
--- a/src/platformsupport/vkconvenience/CMakeLists.txt
+++ b/src/platformsupport/vkconvenience/CMakeLists.txt
@@ -6,7 +6,7 @@ qt_find_package(Vulkan) # special case
## VulkanSupport Module:
#####################################################################
-add_qt_module(VulkanSupport
+qt_add_module(VulkanSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -14,16 +14,20 @@ add_qt_module(VulkanSupport
qvkconvenience.cpp qvkconvenience_p.h
DEFINES
QT_NO_CAST_FROM_ASCII
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
PRECOMPILED_HEADER
"../../corelib/global/qt_pch.h"
)
#### Keys ignored in scope 1:.:.:vkconvenience.pro:<TRUE>:
# MODULE = "vulkan_support"
-# _LOADED = "qt_module"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(VulkanSupport CONDITION QT_FEATURE_opengl
+ PUBLIC_LIBRARIES
+ Qt::OpenGL
+)
diff --git a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
index 68340a3173..6f6ba58319 100644
--- a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
+++ b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
@@ -214,6 +214,22 @@ void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const
for (const QByteArray &ext : extraExts)
m_enabledExtensions.append(ext);
+ QByteArray envExts = qgetenv("QT_VULKAN_INSTANCE_EXTENSIONS");
+ if (!envExts.isEmpty()) {
+ QByteArrayList envExtList = envExts.split(';');
+ for (auto ext : m_enabledExtensions)
+ envExtList.removeAll(ext);
+ m_enabledExtensions.append(envExtList);
+ }
+
+ QByteArray envLayers = qgetenv("QT_VULKAN_INSTANCE_LAYERS");
+ if (!envLayers.isEmpty()) {
+ QByteArrayList envLayerList = envLayers.split(';');
+ for (auto ext : m_enabledLayers)
+ envLayerList.removeAll(ext);
+ m_enabledLayers.append(envLayerList);
+ }
+
// No clever stuff with QSet and friends: the order for layers matters
// and the user-provided order must be kept.
for (int i = 0; i < m_enabledLayers.count(); ++i) {
diff --git a/src/platformsupport/vkconvenience/qvkconvenience.cpp b/src/platformsupport/vkconvenience/qvkconvenience.cpp
index acde1d1bda..59de335333 100644
--- a/src/platformsupport/vkconvenience/qvkconvenience.cpp
+++ b/src/platformsupport/vkconvenience/qvkconvenience.cpp
@@ -39,7 +39,9 @@
#include "qvkconvenience_p.h"
-#include <QOpenGLTexture>
+#if QT_CONFIG(opengl)
+#include <QtOpenGL/QOpenGLTexture>
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/platformsupport/vkconvenience/vkconvenience.pro b/src/platformsupport/vkconvenience/vkconvenience.pro
index ee540024cf..f3ada5768a 100644
--- a/src/platformsupport/vkconvenience/vkconvenience.pro
+++ b/src/platformsupport/vkconvenience/vkconvenience.pro
@@ -2,6 +2,8 @@ TARGET = QtVulkanSupport
MODULE = vulkan_support
QT = core-private gui-private
+qtConfig(opengl): QT += opengl
+
CONFIG += static internal_module
DEFINES += QT_NO_CAST_FROM_ASCII
diff --git a/src/platformsupport/windowsuiautomation/CMakeLists.txt b/src/platformsupport/windowsuiautomation/CMakeLists.txt
index 2a182feaea..c610b97fd6 100644
--- a/src/platformsupport/windowsuiautomation/CMakeLists.txt
+++ b/src/platformsupport/windowsuiautomation/CMakeLists.txt
@@ -4,7 +4,7 @@
## WindowsUIAutomationSupport Module:
#####################################################################
-add_qt_module(WindowsUIAutomationSupport
+qt_add_module(WindowsUIAutomationSupport
STATIC
INTERNAL_MODULE
SOURCES
@@ -19,14 +19,10 @@ add_qt_module(WindowsUIAutomationSupport
uiapropertyids_p.h
uiaserverinterfaces_p.h
uiatypes_p.h
- LIBRARIES
+ PUBLIC_LIBRARIES
Qt::CorePrivate
Qt::GuiPrivate
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::Gui
)
#### Keys ignored in scope 1:.:.:windowsuiautomation.pro:<TRUE>:
# MODULE = "windowsuiautomation_support"
-# _LOADED = "qt_module"