summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/CMakeLists.txt49
-rw-r--r--src/platformsupport/accessibility/CMakeLists.txt20
-rw-r--r--src/platformsupport/clipboard/CMakeLists.txt29
-rw-r--r--src/platformsupport/devicediscovery/CMakeLists.txt40
-rw-r--r--src/platformsupport/edid/CMakeLists.txt21
-rw-r--r--src/platformsupport/eglconvenience/.prev_CMakeLists.txt50
-rw-r--r--src/platformsupport/eglconvenience/CMakeLists.txt53
-rw-r--r--src/platformsupport/eventdispatchers/.prev_CMakeLists.txt42
-rw-r--r--src/platformsupport/eventdispatchers/CMakeLists.txt44
-rw-r--r--src/platformsupport/fbconvenience/CMakeLists.txt26
-rw-r--r--src/platformsupport/fontdatabases/.prev_CMakeLists.txt136
-rw-r--r--src/platformsupport/fontdatabases/CMakeLists.txt139
-rw-r--r--src/platformsupport/fontdatabases/fake.cpp0
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp31
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp77
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h19
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp19
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h4
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm29
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h4
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp478
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase_p.h96
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp937
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp4
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h42
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp988
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h136
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp51
-rw-r--r--src/platformsupport/fontdatabases/windows/windows.pri10
-rw-r--r--src/platformsupport/glxconvenience/.prev_CMakeLists.txt21
-rw-r--r--src/platformsupport/glxconvenience/CMakeLists.txt23
-rw-r--r--src/platformsupport/graphics/CMakeLists.txt20
-rw-r--r--src/platformsupport/input/.prev_CMakeLists.txt102
-rw-r--r--src/platformsupport/input/CMakeLists.txt107
-rw-r--r--src/platformsupport/input/libinput/qlibinputtouch.cpp1
-rw-r--r--src/platformsupport/input/xkbcommon/CMakeLists.txt32
-rw-r--r--src/platformsupport/kmsconvenience/.prev_CMakeLists.txt21
-rw-r--r--src/platformsupport/kmsconvenience/CMakeLists.txt23
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp2
-rw-r--r--src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt41
-rw-r--r--src/platformsupport/linuxaccessibility/CMakeLists.txt43
-rw-r--r--src/platformsupport/linuxaccessibility/constant_mappings_p.h2
-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.txt23
-rw-r--r--src/platformsupport/platformcompositor/platformcompositor.pro4
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor.cpp2
-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.pro4
-rw-r--r--src/platformsupport/services/CMakeLists.txt30
-rw-r--r--src/platformsupport/themes/CMakeLists.txt54
-rw-r--r--src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp4
-rw-r--r--src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h4
-rw-r--r--src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h1
-rw-r--r--src/platformsupport/vkconvenience/.prev_CMakeLists.txt31
-rw-r--r--src/platformsupport/vkconvenience/CMakeLists.txt33
-rw-r--r--src/platformsupport/vkconvenience/qvkconvenience.cpp4
-rw-r--r--src/platformsupport/vkconvenience/vkconvenience.pro2
-rw-r--r--src/platformsupport/windowsuiautomation/CMakeLists.txt28
64 files changed, 4392 insertions, 1016 deletions
diff --git a/src/platformsupport/CMakeLists.txt b/src/platformsupport/CMakeLists.txt
new file mode 100644
index 0000000000..fc980f3707
--- /dev/null
+++ b/src/platformsupport/CMakeLists.txt
@@ -0,0 +1,49 @@
+# Generated from platformsupport.pro.
+
+add_subdirectory(edid)
+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()
+if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib)
+ add_subdirectory(input)
+endif()
+if(QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT))
+ add_subdirectory(services)
+endif()
+if(QT_FEATURE_opengl)
+ add_subdirectory(platformcompositor)
+endif()
+if(QT_FEATURE_egl)
+ add_subdirectory(eglconvenience)
+endif()
+if(QT_FEATURE_opengl AND QT_FEATURE_xlib AND NOT QT_FEATURE_opengles2)
+ add_subdirectory(glxconvenience)
+endif()
+if(QT_FEATURE_kms)
+ add_subdirectory(kmsconvenience)
+endif()
+if(QT_FEATURE_accessibility)
+ add_subdirectory(accessibility)
+endif()
+if(QT_FEATURE_accessibility AND QT_FEATURE_accessibility_atspi_bridge)
+ add_subdirectory(linuxaccessibility)
+endif()
+if(QT_FEATURE_accessibility AND WIN32 AND NOT WINRT)
+ add_subdirectory(windowsuiautomation)
+endif()
+if(APPLE)
+ add_subdirectory(clipboard)
+ add_subdirectory(graphics)
+endif()
+if(QT_FEATURE_vulkan)
+ add_subdirectory(vkconvenience)
+endif()
diff --git a/src/platformsupport/accessibility/CMakeLists.txt b/src/platformsupport/accessibility/CMakeLists.txt
new file mode 100644
index 0000000000..4757b123af
--- /dev/null
+++ b/src/platformsupport/accessibility/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Generated from accessibility.pro.
+
+#####################################################################
+## AccessibilitySupport Module:
+#####################################################################
+
+qt_add_module(AccessibilitySupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qaccessiblebridgeutils.cpp qaccessiblebridgeutils_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:accessibility.pro:<TRUE>:
+# MODULE = "accessibility_support"
diff --git a/src/platformsupport/clipboard/CMakeLists.txt b/src/platformsupport/clipboard/CMakeLists.txt
new file mode 100644
index 0000000000..52022903aa
--- /dev/null
+++ b/src/platformsupport/clipboard/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Generated from clipboard.pro.
+
+#####################################################################
+## ClipboardSupport Module:
+#####################################################################
+
+qt_add_module(ClipboardSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qmacmime.mm qmacmime_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ ${FWImageIO}
+ Qt::CorePrivate
+ Qt::Gui
+)
+
+#### Keys ignored in scope 1:.:.:clipboard.pro:<TRUE>:
+# MODULE = "clipboard_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(ClipboardSupport CONDITION APPLE_OSX
+ LIBRARIES
+ ${FWAppKit}
+)
diff --git a/src/platformsupport/devicediscovery/CMakeLists.txt b/src/platformsupport/devicediscovery/CMakeLists.txt
new file mode 100644
index 0000000000..8ecabb4a1b
--- /dev/null
+++ b/src/platformsupport/devicediscovery/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Generated from devicediscovery.pro.
+
+#####################################################################
+## DeviceDiscoverySupport Module:
+#####################################################################
+
+qt_add_module(DeviceDiscoverySupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qdevicediscovery_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+)
+
+#### Keys ignored in scope 1:.:.:devicediscovery.pro:<TRUE>:
+# MODULE = "devicediscovery_support"
+# QT_FOR_CONFIG = "gui-private"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_libudev
+ SOURCES
+ qdevicediscovery_udev.cpp qdevicediscovery_udev_p.h
+ LIBRARIES
+ PkgConfig::Libudev
+)
+
+qt_extend_target(DeviceDiscoverySupport CONDITION QT_FEATURE_evdev AND NOT QT_FEATURE_libudev
+ SOURCES
+ qdevicediscovery_static.cpp qdevicediscovery_static_p.h
+)
+
+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
new file mode 100644
index 0000000000..aaea30448e
--- /dev/null
+++ b/src/platformsupport/edid/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Generated from edid.pro.
+
+#####################################################################
+## EdidSupport Module:
+#####################################################################
+
+qt_add_module(EdidSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qedidparser.cpp qedidparser_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:edid.pro:<TRUE>:
+# MODULE = "edid_support"
diff --git a/src/platformsupport/eglconvenience/.prev_CMakeLists.txt b/src/platformsupport/eglconvenience/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..c00cc30d62
--- /dev/null
+++ b/src/platformsupport/eglconvenience/.prev_CMakeLists.txt
@@ -0,0 +1,50 @@
+# Generated from eglconvenience.pro.
+
+#####################################################################
+## EglSupport Module:
+#####################################################################
+
+qt_add_module(EglSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qeglconvenience.cpp qeglconvenience_p.h
+ qeglstreamconvenience.cpp qeglstreamconvenience_p.h
+ qt_egl_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:eglconvenience.pro:<TRUE>:
+# MODULE = "egl_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(EglSupport CONDITION QT_FEATURE_opengl
+ SOURCES
+ qeglpbuffer.cpp qeglpbuffer_p.h
+ qeglplatformcontext.cpp qeglplatformcontext_p.h
+)
+
+qt_extend_target(EglSupport CONDITION QT_FEATURE_egl_x11
+ SOURCES
+ qxlibeglintegration.cpp qxlibeglintegration_p.h
+ LIBRARIES
+ X11::X11
+)
+
+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/CMakeLists.txt b/src/platformsupport/eglconvenience/CMakeLists.txt
new file mode 100644
index 0000000000..1858dc7e90
--- /dev/null
+++ b/src/platformsupport/eglconvenience/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Generated from eglconvenience.pro.
+
+#####################################################################
+## EglSupport Module:
+#####################################################################
+
+qt_find_package(EGL) # special case
+
+qt_add_module(EglSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qeglconvenience.cpp qeglconvenience_p.h
+ qeglstreamconvenience.cpp qeglstreamconvenience_p.h
+ qt_egl_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ EGL::EGL # special case
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:eglconvenience.pro:<TRUE>:
+# MODULE = "egl_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(EglSupport CONDITION QT_FEATURE_opengl
+ SOURCES
+ qeglpbuffer.cpp qeglpbuffer_p.h
+ qeglplatformcontext.cpp qeglplatformcontext_p.h
+)
+
+qt_extend_target(EglSupport CONDITION QT_FEATURE_egl_x11
+ SOURCES
+ qxlibeglintegration.cpp qxlibeglintegration_p.h
+ LIBRARIES
+ X11::X11
+)
+
+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/eventdispatchers/.prev_CMakeLists.txt b/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..2e25d6cfd6
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/.prev_CMakeLists.txt
@@ -0,0 +1,42 @@
+# Generated from eventdispatchers.pro.
+
+#####################################################################
+## EventDispatcherSupport Module:
+#####################################################################
+
+qt_add_module(EventDispatcherSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:eventdispatchers.pro:<TRUE>:
+# MODULE = "eventdispatcher_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(EventDispatcherSupport CONDITION UNIX
+ SOURCES
+ qgenericunixeventdispatcher.cpp qgenericunixeventdispatcher_p.h
+ qunixeventdispatcher.cpp
+ qunixeventdispatcher_qpa_p.h
+)
+
+qt_extend_target(EventDispatcherSupport CONDITION WIN32
+ SOURCES
+ qwindowsguieventdispatcher.cpp qwindowsguieventdispatcher_p.h
+)
+
+qt_extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
+ SOURCES
+ qeventdispatcher_glib.cpp qeventdispatcher_glib_p.h
+ LIBRARIES
+ GLIB2::GLIB2
+)
diff --git a/src/platformsupport/eventdispatchers/CMakeLists.txt b/src/platformsupport/eventdispatchers/CMakeLists.txt
new file mode 100644
index 0000000000..72b873423b
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Generated from eventdispatchers.pro.
+
+qt_find_package(GLIB2) # special case
+
+#####################################################################
+## EventDispatcherSupport Module:
+#####################################################################
+
+qt_add_module(EventDispatcherSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:eventdispatchers.pro:<TRUE>:
+# MODULE = "eventdispatcher_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(EventDispatcherSupport CONDITION UNIX
+ SOURCES
+ qgenericunixeventdispatcher.cpp qgenericunixeventdispatcher_p.h
+ qunixeventdispatcher.cpp
+ qunixeventdispatcher_qpa_p.h
+)
+
+qt_extend_target(EventDispatcherSupport CONDITION WIN32
+ SOURCES
+ qwindowsguieventdispatcher.cpp qwindowsguieventdispatcher_p.h
+)
+
+qt_extend_target(EventDispatcherSupport CONDITION QT_FEATURE_glib
+ SOURCES
+ qeventdispatcher_glib.cpp qeventdispatcher_glib_p.h
+ LIBRARIES
+ GLIB2::GLIB2
+)
diff --git a/src/platformsupport/fbconvenience/CMakeLists.txt b/src/platformsupport/fbconvenience/CMakeLists.txt
new file mode 100644
index 0000000000..804b2c15ec
--- /dev/null
+++ b/src/platformsupport/fbconvenience/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Generated from fbconvenience.pro.
+
+#####################################################################
+## FbSupport Module:
+#####################################################################
+
+qt_add_module(FbSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qfbbackingstore.cpp qfbbackingstore_p.h
+ qfbcursor.cpp qfbcursor_p.h
+ qfbscreen.cpp qfbscreen_p.h
+ qfbvthandler.cpp qfbvthandler_p.h
+ qfbwindow.cpp qfbwindow_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:fbconvenience.pro:<TRUE>:
+# MODULE = "fb_support"
diff --git a/src/platformsupport/fontdatabases/.prev_CMakeLists.txt b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..56cf076bd9
--- /dev/null
+++ b/src/platformsupport/fontdatabases/.prev_CMakeLists.txt
@@ -0,0 +1,136 @@
+# Generated from fontdatabases.pro.
+
+#####################################################################
+## FontDatabaseSupport Module:
+#####################################################################
+
+qt_add_module(FontDatabaseSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:fontdatabases.pro:<TRUE>:
+# MODULE = "fontdatabase_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE
+ SOURCES
+ mac/qcoretextfontdatabase.mm mac/qcoretextfontdatabase_p.h
+ mac/qfontengine_coretext.mm mac/qfontengine_coretext_p.h
+ LIBRARIES
+ ${FWCoreFoundation}
+ ${FWCoreGraphics}
+ ${FWCoreText}
+ ${FWFoundation}
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX
+ LIBRARIES
+ ${FWAppKit}
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
+ LIBRARIES
+ ${FWUIKit}
+)
+
+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
+ LIBRARIES
+ WrapFreetype::WrapFreetype
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION UNIX
+ SOURCES
+ genericunix/qgenericunixfontdatabase_p.h
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
+ SOURCES
+ fontconfig/qfontconfigdatabase.cpp fontconfig/qfontconfigdatabase_p.h
+ fontconfig/qfontenginemultifontconfig.cpp fontconfig/qfontenginemultifontconfig_p.h
+ LIBRARIES
+ Fontconfig::Fontconfig
+)
+
+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
+ advapi32
+ gdi32
+ ole32
+ user32
+ PUBLIC_LIBRARIES
+ Qt::GuiPrivate
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
+ SOURCES
+ windows/qwindowsfontdatabase_ft.cpp windows/qwindowsfontdatabase_ft_p.h
+)
+
+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
+)
+
+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
+)
+
+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
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
+ DEFINES
+ QT_NO_DIRECTWRITE
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
+ LIBRARIES
+ uuid
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WINRT
+ SOURCES
+ winrt/qwinrtfontdatabase.cpp winrt/qwinrtfontdatabase_p.h
+ DEFINES
+ __WRL_NO_DEFAULT_LIB__
+ LIBRARIES
+ dwrite_1
+ ws2_32
+ PUBLIC_LIBRARIES
+ Qt::GuiPrivate
+)
diff --git a/src/platformsupport/fontdatabases/CMakeLists.txt b/src/platformsupport/fontdatabases/CMakeLists.txt
new file mode 100644
index 0000000000..b613d6cf6a
--- /dev/null
+++ b/src/platformsupport/fontdatabases/CMakeLists.txt
@@ -0,0 +1,139 @@
+# Generated from fontdatabases.pro.
+
+qt_find_package(WrapFreetype PROVIDED_TARGETS WrapFreetype::WrapFreetype) # special case
+qt_find_package(Fontconfig) # special case
+
+#####################################################################
+## FontDatabaseSupport Module:
+#####################################################################
+
+qt_add_module(FontDatabaseSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:fontdatabases.pro:<TRUE>:
+# MODULE = "fontdatabase_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE
+ SOURCES
+ mac/qcoretextfontdatabase.mm mac/qcoretextfontdatabase_p.h
+ mac/qfontengine_coretext.mm mac/qfontengine_coretext_p.h
+ LIBRARIES
+ ${FWCoreFoundation}
+ ${FWCoreGraphics}
+ ${FWCoreText}
+ ${FWFoundation}
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE_OSX
+ LIBRARIES
+ ${FWAppKit}
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION APPLE AND NOT APPLE_OSX
+ LIBRARIES
+ ${FWUIKit}
+)
+
+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
+ LIBRARIES
+ WrapFreetype::WrapFreetype
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION UNIX
+ SOURCES
+ genericunix/qgenericunixfontdatabase_p.h
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_fontconfig
+ SOURCES
+ fontconfig/qfontconfigdatabase.cpp fontconfig/qfontconfigdatabase_p.h
+ fontconfig/qfontenginemultifontconfig.cpp fontconfig/qfontenginemultifontconfig_p.h
+ LIBRARIES
+ Fontconfig::Fontconfig
+)
+
+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
+ advapi32
+ gdi32
+ ole32
+ user32
+ PUBLIC_LIBRARIES
+ Qt::GuiPrivate
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION QT_FEATURE_freetype AND WIN32 AND NOT WINRT
+ SOURCES
+ windows/qwindowsfontdatabase_ft.cpp windows/qwindowsfontdatabase_ft_p.h
+)
+
+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
+)
+
+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
+)
+
+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
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND NOT WINRT AND (NOT QT_FEATURE_direct2d OR NOT QT_FEATURE_directwrite)
+ DEFINES
+ QT_NO_DIRECTWRITE
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WIN32 AND mingw AND NOT WINRT
+ LIBRARIES
+ uuid
+)
+
+qt_extend_target(FontDatabaseSupport CONDITION WINRT
+ SOURCES
+ winrt/qwinrtfontdatabase.cpp winrt/qwinrtfontdatabase_p.h
+ DEFINES
+ __WRL_NO_DEFAULT_LIB__
+ LIBRARIES
+ dwrite_1
+ ws2_32
+ PUBLIC_LIBRARIES
+ Qt::GuiPrivate
+)
diff --git a/src/platformsupport/fontdatabases/fake.cpp b/src/platformsupport/fontdatabases/fake.cpp
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fake.cpp
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index af49ad6407..49bcbf7e78 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -392,7 +392,7 @@ static inline bool requiresOpenType(int writingSystem)
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
-static void populateFromPattern(FcPattern *pattern)
+static void populateFromPattern(FcPattern *pattern, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr)
{
QString familyName;
QString familyNameLang;
@@ -502,6 +502,18 @@ static void populateFromPattern(FcPattern *pattern)
// Note: stretch should really be an int but registerFont incorrectly uses an enum
QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
+
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.familyName = familyName;
+ properties.styleName = styleName;
+ properties.weight = weight;
+ properties.style = style;
+ properties.stretch = stretch;
+
+ applicationFont->properties.append(properties);
+ }
+
QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
@@ -523,6 +535,16 @@ static void populateFromPattern(FcPattern *pattern)
altFamilyNameLang = familyNameLang;
if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.familyName = altFamilyName;
+ properties.styleName = altStyleName;
+ properties.weight = weight;
+ properties.style = style;
+ properties.stretch = stretch;
+
+ applicationFont->properties.append(properties);
+ }
FontFile *altFontFile = new FontFile(*fontFile);
QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
} else {
@@ -827,10 +849,13 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
#endif
}
-QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
QStringList families;
+ if (applicationFont != nullptr)
+ applicationFont->properties.clear();
+
FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication);
if (!set) {
FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent");
@@ -855,7 +880,7 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
}
- populateFromPattern(pattern);
+ populateFromPattern(pattern, applicationFont);
FcFontSetAdd(set, pattern);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index a7257c2f98..78e2a4f988 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -67,7 +67,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) 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;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
QString resolveFontFamilyAlias(const QString &family) const override;
QFont defaultFont() const override;
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 7e83bcad07..d38fa299f9 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1358,50 +1358,65 @@ 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 nullptr;
-
- // 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 = nullptr;
-
- 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;
- }
+ // 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);
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/freetype/qfreetypefontdatabase.cpp b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp
index 25c10fbd3c..1ec42ac36a 100644
--- a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp
@@ -98,9 +98,9 @@ QFontEngine *QFreeTypeFontDatabase::fontEngine(const QByteArray &fontData, qreal
return QFontEngineFT::create(fontData, pixelSize, hintingPreference);
}
-QStringList QFreeTypeFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+QStringList QFreeTypeFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
- return QFreeTypeFontDatabase::addTTFile(fontData, fileName.toLocal8Bit());
+ return QFreeTypeFontDatabase::addTTFile(fontData, fileName.toLocal8Bit(), applicationFont);
}
void QFreeTypeFontDatabase::releaseHandle(void *handle)
@@ -111,7 +111,7 @@ void QFreeTypeFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype();
-QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
+QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
FT_Library library = qt_getFreetype();
@@ -199,9 +199,20 @@ QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const Q
fontFile->indexValue = index;
QFont::Stretch stretch = QFont::Unstretched;
+ QString styleName = QString::fromLatin1(face->style_name);
- registerFont(family,QString::fromLatin1(face->style_name),QString(),weight,style,stretch,true,true,0,fixedPitch,writingSystems,fontFile);
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.familyName = family;
+ properties.styleName = styleName;
+ properties.weight = weight;
+ properties.stretch = stretch;
+ properties.style = style;
+ applicationFont->properties.append(properties);
+ }
+
+ registerFont(family, styleName, QString(), weight, style, stretch, true, true, 0, fixedPitch, writingSystems, fontFile);
families.append(family);
FT_Done_Face(face);
diff --git a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h
index 0b2956b16e..75e799df3f 100644
--- a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h
@@ -69,10 +69,10 @@ public:
void populateFontDatabase() override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override;
- static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
+ static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr);
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 894919a1c8..546dd65b17 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -268,17 +268,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
Q_UNREACHABLE();
Q_ASSERT(length >= 86);
}
- quint32 unicodeRange[4] = {
- qFromBigEndian<quint32>(os2Table.data() + 42),
- qFromBigEndian<quint32>(os2Table.data() + 46),
- qFromBigEndian<quint32>(os2Table.data() + 50),
- qFromBigEndian<quint32>(os2Table.data() + 54)
- };
- quint32 codePageRange[2] = {
- qFromBigEndian<quint32>(os2Table.data() + 78),
- qFromBigEndian<quint32>(os2Table.data() + 82)
- };
- fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ fd->writingSystems = QPlatformFontDatabase::writingSystemsFromOS2Table(reinterpret_cast<const char *>(os2Table.data()), length);
}
}
@@ -332,7 +322,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
}
}
-void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName)
+void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
FontDescription fd;
getFontDescription(font, &fd);
@@ -342,6 +332,17 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, con
// fonts if a font family does not have any fonts available on the system.
QString family = !familyName.isNull() ? familyName : static_cast<QString>(fd.familyName);
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.familyName = family;
+ properties.styleName = fd.styleName;
+ properties.weight = fd.weight;
+ properties.stretch = fd.stretch;
+ properties.style = fd.style;
+
+ applicationFont->properties.append(properties);
+ }
+
CFRetain(font);
QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */,
@@ -580,7 +581,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
return fallbackList;
}
-QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
QCFType<CFArrayRef> fonts;
@@ -607,7 +608,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
const int numFonts = CFArrayGetCount(fonts);
for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
- populateFromDescriptor(fontDescriptor);
+ populateFromDescriptor(fontDescriptor, QString(), applicationFont);
QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
families.append(QString::fromCFString(familyName));
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index eebb3eb964..63419f75a9 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -76,7 +76,7 @@ public:
void invalidate() 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;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override;
bool isPrivateFontFamily(const QString &family) const override;
QFont defaultFont() const override;
@@ -91,7 +91,7 @@ protected:
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
private:
- void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
+ void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString(), QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr);
static CFArrayRef fallbacksForFamily(const QString &family);
mutable QString defaultFontName;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp
new file mode 100644
index 0000000000..d2fb909dea
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsdirectwritefontdatabase.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** 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 "qwindowsfontdatabase_p.h"
+
+#include <QtCore/qendian.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstringbuilder.h>
+#include <QtCore/qvarlengtharray.h>
+
+#include <dwrite_3.h>
+#include <d2d1.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_USE_DIRECTWRITE3
+
+// Defined in gui/text/qfontdatabase.cpp
+Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script);
+
+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;
+
+ {
+ 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))) {
+ QSupportedWritingSystems writingSystems;
+
+ const void *tableData = nullptr;
+ UINT32 tableSize;
+ void *tableContext = nullptr;
+ BOOL exists;
+ HRESULT hr = face->TryGetFontTable(qbswap<quint32>(MAKE_TAG('O','S','/','2')),
+ &tableData,
+ &tableSize,
+ &tableContext,
+ &exists);
+ if (SUCCEEDED(hr) && exists) {
+ writingSystems = QPlatformFontDatabase::writingSystemsFromOS2Table(reinterpret_cast<const char *>(tableData), tableSize);
+ } else { // Fall back to checking first character of each Unicode range in font (may include too many writing systems)
+ quint32 rangeCount;
+ hr = font1->GetUnicodeRanges(0, nullptr, &rangeCount);
+
+ if (rangeCount > 0) {
+ QVarLengthArray<DWRITE_UNICODE_RANGE, QChar::ScriptCount> ranges(rangeCount);
+
+ hr = font1->GetUnicodeRanges(rangeCount, ranges.data(), &rangeCount);
+ if (SUCCEEDED(hr)) {
+ for (uint i = 0; i < rangeCount; ++i) {
+ QChar::Script script = QChar::script(ranges.at(i).first);
+
+ QFontDatabase::WritingSystem writingSystem = qt_writing_system_for_script(script);
+
+ if (writingSystem > QFontDatabase::Any && writingSystem < QFontDatabase::WritingSystemsCount)
+ writingSystems.setSupported(writingSystem);
+ }
+ } else {
+ const QString errorString = qt_error_string(int(hr));
+ qCWarning(lcQpaFonts) << "Failed to get unicode ranges for font" << englishLocaleFamilyName << englishLocaleStyleName << ":" << errorString;
+ }
+ }
+ }
+
+ if (!englishLocaleStyleName.isEmpty() || defaultLocaleStyleName.isEmpty()) {
+ qCDebug(lcQpaFonts) << "Font" << englishLocaleFamilyName << englishLocaleStyleName << "supports writing systems:" << writingSystems;
+
+ 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
+{
+ QStringList result;
+ result.append(familyForStyleHint(styleHint));
+ result.append(extraTryFontsForFamily(family));
+ result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script));
+
+ qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
+ << script << result;
+ return result;
+}
+
+QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
+{
+ 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()) {
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.style = style;
+ properties.weight = weight;
+ properties.familyName = englishLocaleFamilyName;
+ properties.styleName = englishLocaleStyleName;
+ applicationFont->properties.append(properties);
+ }
+
+ ret.append(englishLocaleFamilyName);
+ QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
+ face->AddRef();
+ }
+
+ if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.style = style;
+ properties.weight = weight;
+ properties.familyName = englishLocaleFamilyName;
+ properties.styleName = englishLocaleStyleName;
+ applicationFont->properties.append(properties);
+ }
+
+ 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..f46c57e6a5
--- /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, QFontDatabasePrivate::ApplicationFont *font = nullptr) 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 36a94724c1..635d2af0ab 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
@@ -1239,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)
@@ -1262,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;
}
}
@@ -1278,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;
}
@@ -1332,7 +799,7 @@ QT_WARNING_POP
fontEngine = QWindowsFontDatabase::createEngine(request, QString(),
defaultVerticalDPI(),
- sharedFontData());
+ data());
if (fontEngine) {
if (request.family != fontEngine->fontDef.family) {
@@ -1371,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;
}
@@ -1552,7 +949,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
}
}
-QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{
WinApplicationFont font;
font.fileName = fileName;
@@ -1595,6 +992,16 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
HFONT hfont = CreateFontIndirect(&lf);
HGDIOBJ oldobj = SelectObject(hdc, hfont);
+ if (applicationFont != nullptr) {
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.style = values.isItalic ? QFont::StyleItalic : QFont::StyleNormal;
+ properties.weight = QPlatformFontDatabase::weightFromInteger(values.weight);
+ properties.familyName = familyName;
+ properties.styleName = styleName;
+
+ applicationFont->properties.append(properties);
+ }
+
TEXTMETRIC textMetrics;
GetTextMetrics(hdc, &textMetrics);
@@ -1613,7 +1020,9 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
QByteArray data = f.readAll();
f.close();
- getFamiliesAndSignatures(data, &families, nullptr, nullptr);
+
+ getFamiliesAndSignatures(data, &families, nullptr, applicationFont != nullptr ? &fontValues : nullptr);
+
if (families.isEmpty())
return QStringList();
@@ -1626,6 +1035,20 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
for (int j = 0; j < families.count(); ++j) {
const QString familyName = families.at(j).name;
familyNames << familyName;
+
+ if (applicationFont != nullptr) {
+ const QString &styleName = families.at(j).style;
+ const QFontValues &values = fontValues.at(j);
+
+ QFontDatabasePrivate::ApplicationFont::Properties properties;
+ properties.style = values.isItalic ? QFont::StyleItalic : QFont::StyleNormal;
+ properties.weight = QPlatformFontDatabase::weightFromInteger(values.weight);
+ properties.familyName = familyName;
+ properties.styleName = styleName;
+
+ applicationFont->properties.append(properties);
+ }
+
populateFamily(familyName);
}
}
@@ -1683,234 +1106,12 @@ 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[] = {
- "Arial",
- "MS UI Gothic",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *jp_tryFonts [] = {
- "MS UI Gothic",
- "Arial",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_CN_tryFonts [] = {
- "SimSun",
- "Arial",
- "PMingLiU",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_TW_tryFonts [] = {
- "PMingLiU",
- "Arial",
- "SimSun",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *kr_tryFonts[] = {
- "Gulim",
- "Arial",
- "PMingLiU",
- "SimSun",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-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;
- QFontDatabase db;
- if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) {
- if (!tryFonts) {
- LANGID lid = GetUserDefaultLangID();
- switch (lid&0xff) {
- case LANG_CHINESE: // Chinese
- if ( lid == 0x0804 || lid == 0x1004) // China mainland and Singapore
- tryFonts = ch_CN_tryFonts;
- else
- tryFonts = ch_TW_tryFonts; // Taiwan, Hong Kong and Macau
- break;
- case LANG_JAPANESE:
- tryFonts = jp_tryFonts;
- break;
- case LANG_KOREAN:
- tryFonts = kr_tryFonts;
- break;
- default:
- tryFonts = other_tryFonts;
- break;
- }
- }
- QFontDatabase db;
- const QStringList families = db.families();
- const char **tf = tryFonts;
- while (tf && *tf) {
- // QTBUG-31689, family might be an English alias for a localized font name.
- const QString family = QString::fromLatin1(*tf);
- if (families.contains(family) || db.hasFamily(family))
- result << family;
- ++tf;
- }
- }
- result.append(QStringLiteral("Segoe UI Emoji"));
- result.append(QStringLiteral("Segoe UI Symbol"));
- return result;
-}
-
-QString QWindowsFontDatabase::familyForStyleHint(QFont::StyleHint styleHint)
-{
- switch (styleHint) {
- case QFont::Times:
- return QStringLiteral("Times New Roman");
- case QFont::Courier:
- return QStringLiteral("Courier New");
- case QFont::Monospace:
- return QStringLiteral("Courier New");
- case QFont::Cursive:
- return QStringLiteral("Comic Sans MS");
- case QFont::Fantasy:
- return QStringLiteral("Impact");
- case QFont::Decorative:
- return QStringLiteral("Old English");
- case QFont::Helvetica:
- return QStringLiteral("Arial");
- case QFont::System:
- default:
- break;
- }
- return QStringLiteral("MS Shell Dlg 2");
-}
-
QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
QStringList result;
- result.append(QWindowsFontDatabase::familyForStyleHint(styleHint));
+ result.append(familyForStyleHint(styleHint));
result.append(m_eudcFonts);
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+ result.append(extraTryFontsForFamily(family));
result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script));
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
@@ -1947,7 +1148,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) {
@@ -2023,62 +1224,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 5c2742d295..b355001254 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
@@ -422,8 +422,8 @@ QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qrea
QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
QStringList result;
- result.append(QWindowsFontDatabase::familyForStyleHint(styleHint));
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+ result.append(QWindowsFontDatabaseBase::familyForStyleHint(styleHint));
+ result.append(QWindowsFontDatabaseBase::extraTryFontsForFamily(family));
result.append(QFreeTypeFontDatabase::fallbacksForFamily(family, style, styleHint, script));
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
index f132e69d4d..38ddb178bd 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:
@@ -103,7 +80,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) 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;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override;
QString fontDir() const override;
@@ -113,22 +90,11 @@ 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..e6dee54d84
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase.cpp
@@ -0,0 +1,988 @@
+/****************************************************************************
+**
+** 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;
+}
+
+QString QWindowsFontDatabaseBase::familyForStyleHint(QFont::StyleHint styleHint)
+{
+ switch (styleHint) {
+ case QFont::Times:
+ return QStringLiteral("Times New Roman");
+ case QFont::Courier:
+ return QStringLiteral("Courier New");
+ case QFont::Monospace:
+ return QStringLiteral("Courier New");
+ case QFont::Cursive:
+ return QStringLiteral("Comic Sans MS");
+ case QFont::Fantasy:
+ return QStringLiteral("Impact");
+ case QFont::Decorative:
+ return QStringLiteral("Old English");
+ case QFont::Helvetica:
+ return QStringLiteral("Arial");
+ case QFont::System:
+ default:
+ break;
+ }
+ return QStringLiteral("MS Shell Dlg 2");
+}
+
+// Creation functions
+
+static const char *other_tryFonts[] = {
+ "Arial",
+ "MS UI Gothic",
+ "Gulim",
+ "SimSun",
+ "PMingLiU",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *jp_tryFonts [] = {
+ "MS UI Gothic",
+ "Arial",
+ "Gulim",
+ "SimSun",
+ "PMingLiU",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *ch_CN_tryFonts [] = {
+ "SimSun",
+ "Arial",
+ "PMingLiU",
+ "Gulim",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *ch_TW_tryFonts [] = {
+ "PMingLiU",
+ "Arial",
+ "SimSun",
+ "Gulim",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *kr_tryFonts[] = {
+ "Gulim",
+ "Arial",
+ "PMingLiU",
+ "SimSun",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char **tryFonts = nullptr;
+
+QStringList QWindowsFontDatabaseBase::extraTryFontsForFamily(const QString &family)
+{
+ QStringList result;
+ QFontDatabase db;
+ if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) {
+ if (!tryFonts) {
+ LANGID lid = GetUserDefaultLangID();
+ switch (lid&0xff) {
+ case LANG_CHINESE: // Chinese
+ if ( lid == 0x0804 || lid == 0x1004) // China mainland and Singapore
+ tryFonts = ch_CN_tryFonts;
+ else
+ tryFonts = ch_TW_tryFonts; // Taiwan, Hong Kong and Macau
+ break;
+ case LANG_JAPANESE:
+ tryFonts = jp_tryFonts;
+ break;
+ case LANG_KOREAN:
+ tryFonts = kr_tryFonts;
+ break;
+ default:
+ tryFonts = other_tryFonts;
+ break;
+ }
+ }
+ QFontDatabase db;
+ const QStringList families = db.families();
+ const char **tf = tryFonts;
+ while (tf && *tf) {
+ // QTBUG-31689, family might be an English alias for a localized font name.
+ const QString family = QString::fromLatin1(*tf);
+ if (families.contains(family) || db.hasFamily(family))
+ result << family;
+ ++tf;
+ }
+ }
+ result.append(QStringLiteral("Segoe UI Emoji"));
+ result.append(QStringLiteral("Segoe UI Symbol"));
+ return result;
+}
+
+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..5b9db5dede
--- /dev/null
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabasebase_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** 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);
+
+ static QString familyForStyleHint(QFont::StyleHint styleHint);
+ static QStringList extraTryFontsForFamily(const QString &family);
+
+ 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 ecf6049504..4e6b22ce94 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -188,6 +188,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)
@@ -210,13 +222,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,
@@ -481,9 +490,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)
@@ -716,6 +738,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(
@@ -723,7 +747,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
margin, margin,
&glyphAnalysis
);
@@ -753,7 +777,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
0.0f,
&glyphRun,
NULL,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
NULL,
0,
&enumerator);
@@ -784,7 +808,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
0.0, 0.0,
&colorGlyphsAnalysis
);
@@ -1024,6 +1048,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
DWRITE_RENDERING_MODE renderMode =
hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
+ DWRITE_MEASURING_MODE measureMode = renderModeToMeasureMode(renderMode);
const int margin = glyphMargin(QFontEngine::Format_A32);
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
@@ -1032,7 +1057,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
1.0f,
&transform,
renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
+ measureMode,
margin, margin,
&glyphAnalysis
);
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
new file mode 100644
index 0000000000..d3d2c87910
--- /dev/null
+++ b/src/platformsupport/glxconvenience/.prev_CMakeLists.txt
@@ -0,0 +1,21 @@
+# Generated from glxconvenience.pro.
+
+#####################################################################
+## GlxSupport Module:
+#####################################################################
+
+qt_add_module(GlxSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qglxconvenience.cpp qglxconvenience_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ X11::X11
+)
+
+#### Keys ignored in scope 1:.:.:glxconvenience.pro:<TRUE>:
+# MODULE = "glx_support"
diff --git a/src/platformsupport/glxconvenience/CMakeLists.txt b/src/platformsupport/glxconvenience/CMakeLists.txt
new file mode 100644
index 0000000000..00d2e6c754
--- /dev/null
+++ b/src/platformsupport/glxconvenience/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from glxconvenience.pro.
+
+qt_find_package(X11) # special case
+
+#####################################################################
+## GlxSupport Module:
+#####################################################################
+
+qt_add_module(GlxSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qglxconvenience.cpp qglxconvenience_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ X11::X11
+)
+
+#### Keys ignored in scope 1:.:.:glxconvenience.pro:<TRUE>:
+# MODULE = "glx_support"
diff --git a/src/platformsupport/graphics/CMakeLists.txt b/src/platformsupport/graphics/CMakeLists.txt
new file mode 100644
index 0000000000..e9f0245dbe
--- /dev/null
+++ b/src/platformsupport/graphics/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Generated from graphics.pro.
+
+#####################################################################
+## GraphicsSupport Module:
+#####################################################################
+
+qt_add_module(GraphicsSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qrasterbackingstore.cpp qrasterbackingstore_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:graphics.pro:<TRUE>:
+# MODULE = "graphics_support"
diff --git a/src/platformsupport/input/.prev_CMakeLists.txt b/src/platformsupport/input/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..f8c05e9f97
--- /dev/null
+++ b/src/platformsupport/input/.prev_CMakeLists.txt
@@ -0,0 +1,102 @@
+# Generated from input.pro.
+
+#####################################################################
+## InputSupport Module:
+#####################################################################
+
+qt_add_module(InputSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::DeviceDiscoverySupportPrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 3:.:.:input-support.pro:<TRUE>:
+# MODULE = "input_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev
+ SOURCES
+ evdevkeyboard/qevdevkeyboard_defaultmap_p.h
+ evdevkeyboard/qevdevkeyboardhandler.cpp evdevkeyboard/qevdevkeyboardhandler_p.h
+ evdevkeyboard/qevdevkeyboardmanager.cpp evdevkeyboard/qevdevkeyboardmanager_p.h
+ evdevmouse/qevdevmousehandler.cpp evdevmouse/qevdevmousehandler_p.h
+ evdevmouse/qevdevmousemanager.cpp evdevmouse/qevdevmousemanager_p.h
+ evdevtouch/qevdevtouchhandler.cpp evdevtouch/qevdevtouchhandler_p.h
+ evdevtouch/qevdevtouchmanager.cpp evdevtouch/qevdevtouchmanager_p.h
+ INCLUDE_DIRECTORIES
+ evdevtouch/../shared
+)
+
+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
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
+ LIBRARIES
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
+ LIBRARIES
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
+ LIBRARIES
+ PkgConfig::Mtdev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_tslib
+ SOURCES
+ tslib/qtslib.cpp tslib/qtslib_p.h
+ PUBLIC_LIBRARIES
+ PkgConfig::Tslib
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput
+ SOURCES
+ libinput/qlibinputhandler.cpp libinput/qlibinputhandler_p.h
+ libinput/qlibinputkeyboard.cpp libinput/qlibinputkeyboard_p.h
+ libinput/qlibinputpointer.cpp libinput/qlibinputpointer_p.h
+ libinput/qlibinputtouch.cpp libinput/qlibinputtouch_p.h
+ INCLUDE_DIRECTORIES
+ libinput/../shared
+ LIBRARIES
+ Libinput::Libinput
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
+ LIBRARIES
+ XKB::XKB
+ PUBLIC_LIBRARIES
+ Qt::XkbCommonSupportPrivate
+)
+
+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
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
+ SOURCES
+ integrityhid/qintegrityhidmanager.cpp integrityhid/qintegrityhidmanager.h
+ LIBRARIES
+ integrityhid
+)
+if(QT_FEATURE_xkbcommon)
+ add_subdirectory(xkbcommon)
+endif()
diff --git a/src/platformsupport/input/CMakeLists.txt b/src/platformsupport/input/CMakeLists.txt
new file mode 100644
index 0000000000..7ab93df062
--- /dev/null
+++ b/src/platformsupport/input/CMakeLists.txt
@@ -0,0 +1,107 @@
+# Generated from input.pro.
+
+qt_find_package(Libinput) # special case
+qt_find_package(XKB) # special case
+qt_find_package(Tslib) # special case
+qt_find_package(Mtdev) # special case
+
+#####################################################################
+## InputSupport Module:
+#####################################################################
+
+qt_add_module(InputSupport
+ STATIC
+ INTERNAL_MODULE
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::DeviceDiscoverySupportPrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 3:.:.:input-support.pro:<TRUE>:
+# MODULE = "input_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev
+ SOURCES
+ evdevkeyboard/qevdevkeyboard_defaultmap_p.h
+ evdevkeyboard/qevdevkeyboardhandler.cpp evdevkeyboard/qevdevkeyboardhandler_p.h
+ evdevkeyboard/qevdevkeyboardmanager.cpp evdevkeyboard/qevdevkeyboardmanager_p.h
+ evdevmouse/qevdevmousehandler.cpp evdevmouse/qevdevmousehandler_p.h
+ evdevmouse/qevdevmousemanager.cpp evdevmouse/qevdevmousemanager_p.h
+ evdevtouch/qevdevtouchhandler.cpp evdevtouch/qevdevtouchhandler_p.h
+ evdevtouch/qevdevtouchmanager.cpp evdevtouch/qevdevtouchmanager_p.h
+ INCLUDE_DIRECTORIES
+ evdevtouch/../shared
+)
+
+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
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev AND QT_FEATURE_tabletevent
+ LIBRARIES
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_libudev
+ LIBRARIES
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_evdev AND QT_FEATURE_mtdev
+ LIBRARIES
+ PkgConfig::Mtdev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_tslib
+ SOURCES
+ tslib/qtslib.cpp tslib/qtslib_p.h
+ PUBLIC_LIBRARIES
+ PkgConfig::Tslib
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput
+ SOURCES
+ libinput/qlibinputhandler.cpp libinput/qlibinputhandler_p.h
+ libinput/qlibinputkeyboard.cpp libinput/qlibinputkeyboard_p.h
+ libinput/qlibinputpointer.cpp libinput/qlibinputpointer_p.h
+ libinput/qlibinputtouch.cpp libinput/qlibinputtouch_p.h
+ INCLUDE_DIRECTORIES
+ libinput/../shared
+ LIBRARIES
+ Libinput::Libinput
+ PkgConfig::Libudev
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_libinput AND QT_FEATURE_xkbcommon
+ LIBRARIES
+ XKB::XKB
+ PUBLIC_LIBRARIES
+ Qt::XkbCommonSupportPrivate
+)
+
+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
+)
+
+qt_extend_target(InputSupport CONDITION QT_FEATURE_integrityhid
+ SOURCES
+ integrityhid/qintegrityhidmanager.cpp integrityhid/qintegrityhidmanager.h
+ LIBRARIES
+ integrityhid
+)
+if(QT_FEATURE_xkbcommon)
+ add_subdirectory(xkbcommon)
+endif()
diff --git a/src/platformsupport/input/libinput/qlibinputtouch.cpp b/src/platformsupport/input/libinput/qlibinputtouch.cpp
index 446218e4b3..f00df6b674 100644
--- a/src/platformsupport/input/libinput/qlibinputtouch.cpp
+++ b/src/platformsupport/input/libinput/qlibinputtouch.cpp
@@ -42,6 +42,7 @@
#include <libinput.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <QtGui/QTouchDevice>
#include <QtGui/private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/platformsupport/input/xkbcommon/CMakeLists.txt b/src/platformsupport/input/xkbcommon/CMakeLists.txt
new file mode 100644
index 0000000000..86d132d912
--- /dev/null
+++ b/src/platformsupport/input/xkbcommon/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Generated from xkbcommon.pro.
+
+#####################################################################
+## XkbCommonSupport Module:
+#####################################################################
+
+qt_add_module(XkbCommonSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qxkbcommon.cpp qxkbcommon_p.h
+ qxkbcommon_3rdparty.cpp
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ XKB::XKB
+ PRECOMPILED_HEADER
+ "../../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:xkbcommon.pro:<TRUE>:
+# MODULE = "xkbcommon_support"
+
+## Scopes:
+#####################################################################
+
+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
new file mode 100644
index 0000000000..5b0fd00566
--- /dev/null
+++ b/src/platformsupport/kmsconvenience/.prev_CMakeLists.txt
@@ -0,0 +1,21 @@
+# Generated from kmsconvenience.pro.
+
+#####################################################################
+## KmsSupport Module:
+#####################################################################
+
+qt_add_module(KmsSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qkmsdevice.cpp qkmsdevice_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Libdrm::Libdrm
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:kmsconvenience.pro:<TRUE>:
+# MODULE = "kms_support"
diff --git a/src/platformsupport/kmsconvenience/CMakeLists.txt b/src/platformsupport/kmsconvenience/CMakeLists.txt
new file mode 100644
index 0000000000..8001ee27de
--- /dev/null
+++ b/src/platformsupport/kmsconvenience/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from kmsconvenience.pro.
+
+qt_find_package(Libdrm) # special case
+
+#####################################################################
+## KmsSupport Module:
+#####################################################################
+
+qt_add_module(KmsSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qkmsdevice.cpp qkmsdevice_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Libdrm::Libdrm
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:kmsconvenience.pro:<TRUE>:
+# MODULE = "kms_support"
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index 18f7b5e23b..8cd7f9b368 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -396,7 +396,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
drmFormat = DRM_FORMAT_XRGB8888;
drmFormatExplicit = false;
}
- qCDebug(qLcKmsDebug) << "Format is" << hex << drmFormat << dec << "requested_by_user =" << drmFormatExplicit
+ qCDebug(qLcKmsDebug) << "Format is" << Qt::hex << drmFormat << Qt::dec << "requested_by_user =" << drmFormatExplicit
<< "for output" << connectorName;
const QString cloneSource = userConnectorConfig.value(QStringLiteral("clones")).toString();
diff --git a/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt b/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..38d3d2831f
--- /dev/null
+++ b/src/platformsupport/linuxaccessibility/.prev_CMakeLists.txt
@@ -0,0 +1,41 @@
+# Generated from linuxaccessibility.pro.
+
+#####################################################################
+## LinuxAccessibilitySupport Module:
+#####################################################################
+
+qt_add_module(LinuxAccessibilitySupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ application.cpp application_p.h
+ atspiadaptor.cpp atspiadaptor_p.h
+ bridge.cpp bridge_p.h
+ cache.cpp cache_p.h
+ constant_mappings.cpp constant_mappings_p.h
+ dbusconnection.cpp dbusconnection_p.h
+ struct_marshallers.cpp struct_marshallers_p.h
+ DBUS_ADAPTOR_SOURCES
+ dbusxml/Cache.xml
+ dbusxml/DeviceEventController.xml
+ DBUS_ADAPTOR_FLAGS
+ "-i" "struct_marshallers_p.h"
+ DBUS_INTERFACE_SOURCES
+ dbusxml/Bus.xml
+ dbusxml/Socket.xml
+ DBUS_INTERFACE_FLAGS
+ "-i" "struct_marshallers_p.h"
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ PkgConfig::ATSPI2_nolink
+ Qt::AccessibilitySupportPrivate
+ Qt::CorePrivate
+ Qt::DBus
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:linuxaccessibility.pro:<TRUE>:
+# MODULE = "linuxaccessibility_support"
diff --git a/src/platformsupport/linuxaccessibility/CMakeLists.txt b/src/platformsupport/linuxaccessibility/CMakeLists.txt
new file mode 100644
index 0000000000..35bfdabf5f
--- /dev/null
+++ b/src/platformsupport/linuxaccessibility/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Generated from linuxaccessibility.pro.
+
+qt_find_package(ATSPI2) # special case
+
+#####################################################################
+## LinuxAccessibilitySupport Module:
+#####################################################################
+
+qt_add_module(LinuxAccessibilitySupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ application.cpp application_p.h
+ atspiadaptor.cpp atspiadaptor_p.h
+ bridge.cpp bridge_p.h
+ cache.cpp cache_p.h
+ constant_mappings.cpp constant_mappings_p.h
+ dbusconnection.cpp dbusconnection_p.h
+ struct_marshallers.cpp struct_marshallers_p.h
+ DBUS_ADAPTOR_SOURCES
+ dbusxml/Cache.xml
+ dbusxml/DeviceEventController.xml
+ DBUS_ADAPTOR_FLAGS
+ "-i" "struct_marshallers_p.h"
+ DBUS_INTERFACE_SOURCES
+ dbusxml/Bus.xml
+ dbusxml/Socket.xml
+ DBUS_INTERFACE_FLAGS
+ "-i" "struct_marshallers_p.h"
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ PkgConfig::ATSPI2_nolink
+ Qt::AccessibilitySupportPrivate
+ Qt::CorePrivate
+ Qt::DBus
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:linuxaccessibility.pro:<TRUE>:
+# MODULE = "linuxaccessibility_support"
diff --git a/src/platformsupport/linuxaccessibility/constant_mappings_p.h b/src/platformsupport/linuxaccessibility/constant_mappings_p.h
index 4da818c8c1..1d4dd833e1 100644
--- a/src/platformsupport/linuxaccessibility/constant_mappings_p.h
+++ b/src/platformsupport/linuxaccessibility/constant_mappings_p.h
@@ -118,7 +118,7 @@ struct RoleNames {
QString localizedName() const {return m_localizedName;}
private:
- AtspiRole m_spiRole;
+ AtspiRole m_spiRole = ATSPI_ROLE_INVALID;
QString m_name;
QString m_localizedName;
};
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
new file mode 100644
index 0000000000..1ddc9e719d
--- /dev/null
+++ b/src/platformsupport/platformcompositor/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Generated from platformcompositor.pro.
+
+#####################################################################
+## PlatformCompositorSupport Module:
+#####################################################################
+
+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
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ Qt::OpenGL
+)
+
+#### Keys ignored in scope 1:.:.:platformcompositor.pro:<TRUE>:
+# MODULE = "platformcompositor_support"
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.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
index 635bf0107f..abfaca3f9c 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
@@ -37,8 +37,8 @@
**
****************************************************************************/
+#include <QtOpenGL/QOpenGLFramebufferObject>
#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QWindow>
#include <qpa/qplatformbackingstore.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..511d85a400
--- /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 qsizetype 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 877665ff06..4b41b29c12 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -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
new file mode 100644
index 0000000000..602dd40305
--- /dev/null
+++ b/src/platformsupport/services/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Generated from services.pro.
+
+#####################################################################
+## ServiceSupport Module:
+#####################################################################
+
+qt_add_module(ServiceSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ genericunix/qgenericunixservices.cpp genericunix/qgenericunixservices_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:services.pro:<TRUE>:
+# MODULE = "service_support"
+
+## Scopes:
+#####################################################################
+
+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
new file mode 100644
index 0000000000..a7be78d0e0
--- /dev/null
+++ b/src/platformsupport/themes/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Generated from themes.pro.
+
+#####################################################################
+## ThemeSupport Module:
+#####################################################################
+
+qt_add_module(ThemeSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qabstractfileiconengine.cpp qabstractfileiconengine_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:themes.pro:<TRUE>:
+# MODULE = "theme_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(ThemeSupport CONDITION QT_FEATURE_xcb OR (UNIX AND NOT APPLE_UIKIT)
+ SOURCES
+ genericunix/qgenericunixthemes.cpp genericunix/qgenericunixthemes_p.h
+)
+
+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
+ genericunix/dbusmenu/qdbusmenuconnection.cpp genericunix/dbusmenu/qdbusmenuconnection_p.h
+ genericunix/dbusmenu/qdbusmenuregistrarproxy.cpp genericunix/dbusmenu/qdbusmenuregistrarproxy_p.h
+ genericunix/dbusmenu/qdbusmenutypes.cpp genericunix/dbusmenu/qdbusmenutypes_p.h
+ genericunix/dbusmenu/qdbusplatformmenu.cpp genericunix/dbusmenu/qdbusplatformmenu_p.h
+ INCLUDE_DIRECTORIES
+ genericunix/dbusmenu
+ LIBRARIES
+ Qt::DBus
+)
+
+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
+ genericunix/dbustray/qstatusnotifieritemadaptor.cpp genericunix/dbustray/qstatusnotifieritemadaptor_p.h
+ genericunix/dbustray/qxdgnotificationproxy.cpp genericunix/dbustray/qxdgnotificationproxy_p.h
+ INCLUDE_DIRECTORIES
+ genericunix/dbustray
+ LIBRARIES
+ Qt::DBus
+)
diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenutypes.cpp
index ccf2180dc5..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"
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/dbustray/qdbustrayicon_p.h b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h
index 7034a7edb4..edc115742c 100644
--- a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h
+++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon_p.h
@@ -83,6 +83,7 @@ class QDBusTrayIcon: public QPlatformSystemTrayIcon
Q_PROPERTY(QString attentionIconName READ attentionIconName NOTIFY attention)
Q_PROPERTY(QIcon attentionIcon READ attentionIcon NOTIFY attention)
Q_PROPERTY(QDBusPlatformMenu *menu READ menu NOTIFY menuChanged)
+ Q_MOC_INCLUDE("qdbusplatformmenu_p.h")
public:
QDBusTrayIcon();
diff --git a/src/platformsupport/vkconvenience/.prev_CMakeLists.txt b/src/platformsupport/vkconvenience/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..6f17cfa306
--- /dev/null
+++ b/src/platformsupport/vkconvenience/.prev_CMakeLists.txt
@@ -0,0 +1,31 @@
+# Generated from vkconvenience.pro.
+
+#####################################################################
+## VulkanSupport Module:
+#####################################################################
+
+qt_add_module(VulkanSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qbasicvulkanplatforminstance.cpp qbasicvulkanplatforminstance_p.h
+ qvkconvenience.cpp qvkconvenience_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:vkconvenience.pro:<TRUE>:
+# MODULE = "vulkan_support"
+
+## 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
new file mode 100644
index 0000000000..6ec2574375
--- /dev/null
+++ b/src/platformsupport/vkconvenience/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Generated from vkconvenience.pro.
+
+qt_find_package(Vulkan) # special case
+
+#####################################################################
+## VulkanSupport Module:
+#####################################################################
+
+qt_add_module(VulkanSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qbasicvulkanplatforminstance.cpp qbasicvulkanplatforminstance_p.h
+ qvkconvenience.cpp qvkconvenience_p.h
+ DEFINES
+ QT_NO_CAST_FROM_ASCII
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+ PRECOMPILED_HEADER
+ "../../corelib/global/qt_pch.h"
+)
+
+#### Keys ignored in scope 1:.:.:vkconvenience.pro:<TRUE>:
+# MODULE = "vulkan_support"
+
+## Scopes:
+#####################################################################
+
+qt_extend_target(VulkanSupport CONDITION QT_FEATURE_opengl
+ PUBLIC_LIBRARIES
+ Qt::OpenGL
+)
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
new file mode 100644
index 0000000000..c610b97fd6
--- /dev/null
+++ b/src/platformsupport/windowsuiautomation/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Generated from windowsuiautomation.pro.
+
+#####################################################################
+## WindowsUIAutomationSupport Module:
+#####################################################################
+
+qt_add_module(WindowsUIAutomationSupport
+ STATIC
+ INTERNAL_MODULE
+ SOURCES
+ qwindowsuiawrapper.cpp qwindowsuiawrapper_p.h
+ uiaattributeids_p.h
+ uiaclientinterfaces_p.h
+ uiacontroltypeids_p.h
+ uiaerrorids_p.h
+ uiaeventids_p.h
+ uiageneralids_p.h
+ uiapatternids_p.h
+ uiapropertyids_p.h
+ uiaserverinterfaces_p.h
+ uiatypes_p.h
+ PUBLIC_LIBRARIES
+ Qt::CorePrivate
+ Qt::GuiPrivate
+)
+
+#### Keys ignored in scope 1:.:.:windowsuiautomation.pro:<TRUE>:
+# MODULE = "windowsuiautomation_support"