Use ICU from Windows SDK for codec support (QStringConverter)
Windows has shipped a (limited) subset of ICU for quite a while: https://learn.microsoft.com/en-us/windows/win32/intl/international-components-for-unicode--icu- The C API for this subset uses non-standard names for headers and lib though, and is therefore not picked up by the ICU configure logic in CMake. This patch adds a separate configure test that enables the use of this ICU API, specifically for text codec support in QStringConverter. If a 'proper' ICU is enabled by the user, this still takes precedence. Also, note that MinGW-w64 misses the respective Windows API, and will therefore still use the old fallback. [ChangeLog][QtCore][Text] Qt on Windows now uses the ICU API of the Windows SDK for text codec support (if available and no 'full' ICU is configured). This greatly enhances the list of supported text codecs available. Fixes: QTBUG-132056 Change-Id: Id02ae9f8cf56dee8c34795c0e60d2113f319bfd9 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
71246cbdc6
commit
92b5980a7e
@ -871,6 +871,11 @@ qt_internal_extend_target(Core CONDITION WIN32
|
|||||||
text/qlocale_win.cpp
|
text/qlocale_win.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
qt_internal_extend_target(Core CONDITION QT_FEATURE_winsdkicu
|
||||||
|
LIBRARIES
|
||||||
|
icu
|
||||||
|
)
|
||||||
|
|
||||||
qt_internal_extend_target(Core CONDITION WASM
|
qt_internal_extend_target(Core CONDITION WASM
|
||||||
SOURCES
|
SOURCES
|
||||||
text/qlocale_wasm.cpp
|
text/qlocale_wasm.cpp
|
||||||
|
@ -515,6 +515,21 @@ renameat2(AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_NOREPLACE | RENAME_WHITEO
|
|||||||
}
|
}
|
||||||
")
|
")
|
||||||
|
|
||||||
|
qt_config_compile_test(winsdkicu
|
||||||
|
LABEL "Windows SDK: ICU"
|
||||||
|
LIBRARIES icu
|
||||||
|
CODE
|
||||||
|
"#include <icu.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
/* BEGIN TEST: */
|
||||||
|
/* END TEST: */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
)
|
||||||
|
|
||||||
# cpp_winrt
|
# cpp_winrt
|
||||||
qt_config_compile_test(cpp_winrt
|
qt_config_compile_test(cpp_winrt
|
||||||
LABEL "cpp/winrt"
|
LABEL "cpp/winrt"
|
||||||
@ -666,6 +681,12 @@ qt_feature("icu" PRIVATE
|
|||||||
AUTODETECT NOT WIN32
|
AUTODETECT NOT WIN32
|
||||||
CONDITION ICU_FOUND
|
CONDITION ICU_FOUND
|
||||||
)
|
)
|
||||||
|
qt_feature("winsdkicu" PRIVATE
|
||||||
|
LABEL "ICU (Windows SDK)"
|
||||||
|
AUTODETECT WIN32
|
||||||
|
CONDITION TEST_winsdkicu
|
||||||
|
DISABLE QT_FEATURE_icu
|
||||||
|
)
|
||||||
qt_feature("inotify" PUBLIC PRIVATE
|
qt_feature("inotify" PUBLIC PRIVATE
|
||||||
LABEL "inotify"
|
LABEL "inotify"
|
||||||
CONDITION TEST_inotify OR TEST_fsnotify
|
CONDITION TEST_inotify OR TEST_fsnotify
|
||||||
|
@ -94,5 +94,6 @@
|
|||||||
#define QT_NO_TRANSLATION
|
#define QT_NO_TRANSLATION
|
||||||
#define QT_FEATURE_translation -1
|
#define QT_FEATURE_translation -1
|
||||||
#define QT_NO_VARIANT -1
|
#define QT_NO_VARIANT -1
|
||||||
|
#define QT_FEATURE_winsdkicu -1
|
||||||
|
|
||||||
#endif // QT_BOOTSTRAPPED
|
#endif // QT_BOOTSTRAPPED
|
||||||
|
@ -19,7 +19,11 @@
|
|||||||
#include <unicode/ucnv_cb.h>
|
#include <unicode/ucnv_cb.h>
|
||||||
#include <unicode/ucnv_err.h>
|
#include <unicode/ucnv_err.h>
|
||||||
#include <unicode/ustring.h>
|
#include <unicode/ustring.h>
|
||||||
#endif
|
#define QT_USE_ICU_CODECS
|
||||||
|
#elif QT_CONFIG(winsdkicu)
|
||||||
|
#include <icu.h>
|
||||||
|
#define QT_USE_ICU_CODECS
|
||||||
|
#endif // QT_CONFIG(icu) || QT_CONFIG(winsdkicu)
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
@ -1836,7 +1840,7 @@ void QStringConverter::State::clear() noexcept
|
|||||||
void QStringConverter::State::reset() noexcept
|
void QStringConverter::State::reset() noexcept
|
||||||
{
|
{
|
||||||
if (flags & Flag::UsesIcu) {
|
if (flags & Flag::UsesIcu) {
|
||||||
#if QT_CONFIG(icu)
|
#if defined(QT_USE_ICU_CODECS)
|
||||||
UConverter *converter = static_cast<UConverter *>(d[0]);
|
UConverter *converter = static_cast<UConverter *>(d[0]);
|
||||||
if (converter)
|
if (converter)
|
||||||
ucnv_reset(converter);
|
ucnv_reset(converter);
|
||||||
@ -2152,7 +2156,7 @@ static bool nameMatch(const char *a, QAnyStringView b)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if defined(QT_USE_ICU_CODECS)
|
||||||
// only derives from QStringConverter to get access to protected types
|
// only derives from QStringConverter to get access to protected types
|
||||||
struct QStringConverterICU : QStringConverter
|
struct QStringConverterICU : QStringConverter
|
||||||
{
|
{
|
||||||
@ -2418,7 +2422,7 @@ QStringConverter::QStringConverter(QAnyStringView name, Flags f)
|
|||||||
auto e = encodingForName(name);
|
auto e = encodingForName(name);
|
||||||
if (e)
|
if (e)
|
||||||
iface = encodingInterfaces + int(*e);
|
iface = encodingInterfaces + int(*e);
|
||||||
#if QT_CONFIG(icu)
|
#if defined(QT_USE_ICU_CODECS)
|
||||||
else
|
else
|
||||||
iface = QStringConverterICU::make_icu_converter(&state, name);
|
iface = QStringConverterICU::make_icu_converter(&state, name);
|
||||||
#endif
|
#endif
|
||||||
@ -2430,7 +2434,7 @@ const char *QStringConverter::name() const noexcept
|
|||||||
if (!iface)
|
if (!iface)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (state.flags & QStringConverter::Flag::UsesIcu) {
|
if (state.flags & QStringConverter::Flag::UsesIcu) {
|
||||||
#if QT_CONFIG(icu)
|
#if defined(QT_USE_ICU_CODECS)
|
||||||
return static_cast<const char*>(state.d[1]);
|
return static_cast<const char*>(state.d[1]);
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -2610,7 +2614,7 @@ std::optional<QStringConverter::Encoding> QStringConverter::encodingForHtml(QByt
|
|||||||
|
|
||||||
static qsizetype availableCodecCount()
|
static qsizetype availableCodecCount()
|
||||||
{
|
{
|
||||||
#if !QT_CONFIG(icu)
|
#if !defined(QT_USE_ICU_CODECS)
|
||||||
return QStringConverter::Encoding::LastEncoding;
|
return QStringConverter::Encoding::LastEncoding;
|
||||||
#else
|
#else
|
||||||
/* icu contains also the names of what Qt provides
|
/* icu contains also the names of what Qt provides
|
||||||
@ -2637,7 +2641,7 @@ QStringList QStringConverter::availableCodecs()
|
|||||||
{
|
{
|
||||||
auto availableCodec = [](qsizetype index) -> QString
|
auto availableCodec = [](qsizetype index) -> QString
|
||||||
{
|
{
|
||||||
#if !QT_CONFIG(icu)
|
#if !defined(QT_USE_ICU_CODECS)
|
||||||
return QString::fromLatin1(encodingInterfaces[index].name);
|
return QString::fromLatin1(encodingInterfaces[index].name);
|
||||||
#else
|
#else
|
||||||
if (index == 0) // "Locale", not provided by icu
|
if (index == 0) // "Locale", not provided by icu
|
||||||
|
@ -151,7 +151,7 @@ private slots:
|
|||||||
|
|
||||||
void convertL1U16();
|
void convertL1U16();
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if QT_CONFIG(icu) || QT_CONFIG(winsdkicu)
|
||||||
void roundtripIcu_data();
|
void roundtripIcu_data();
|
||||||
void roundtripIcu();
|
void roundtripIcu();
|
||||||
void icuInvalidCharacter_data();
|
void icuInvalidCharacter_data();
|
||||||
@ -501,7 +501,7 @@ void tst_QStringConverter::convertL1U8()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(icu)
|
#if QT_CONFIG(icu) || QT_CONFIG(winsdkicu)
|
||||||
|
|
||||||
void tst_QStringConverter::roundtripIcu_data()
|
void tst_QStringConverter::roundtripIcu_data()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user