diff options
author | Morten Johan Sørvig <morten.sorvig@nokia.com> | 2010-03-10 09:05:53 (GMT) |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@nokia.com> | 2010-03-10 09:05:53 (GMT) |
commit | a0ec41037fcbb686dfc5c4679261bffc5e358fdd (patch) | |
tree | fda0f01c3aebbfe6f4ab32c76f92702e537a5bca /src | |
parent | 3a1e96fc9d5844583138d183e95e127a034daf56 (diff) | |
parent | 12d63b05a942281e688d857d17c190564c77b698 (diff) | |
download | Qt-a0ec41037fcbb686dfc5c4679261bffc5e358fdd.zip Qt-a0ec41037fcbb686dfc5c4679261bffc5e358fdd.tar.gz Qt-a0ec41037fcbb686dfc5c4679261bffc5e358fdd.tar.bz2 |
Merge remote branch 'origin/4.7-cutoff' into 4.7
Diffstat (limited to 'src')
24 files changed, 864 insertions, 94 deletions
diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index 17f4d91..c572e08 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -31,7 +31,7 @@ unix { DEFINES += GNU_LIBICONV !mac:LIBS_PRIVATE *= -liconv - } else { + } else:!symbian { # no iconv, so we put all plugins in the library HEADERS += \ ../plugins/codecs/cn/qgb18030codec.h \ @@ -52,3 +52,4 @@ unix { ../plugins/codecs/jp/qfontjpcodec.cpp } } +symbian:LIBS += -lcharconv diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 4cc7912..a6f5c9e 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -54,6 +54,7 @@ static const struct { int mib; quint16 values[128]; } unicodevalues[QSimpleTextCodec::numSimpleCodecs] = { +#ifndef Q_OS_SYMBIAN // from RFC 1489, ftp://ftp.isi.edu/in-notes/rfc1489.txt { "KOI8-R", { "csKOI8R", 0 }, 2084, { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, @@ -288,6 +289,7 @@ static const struct { 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF} }, +#endif { "ISO-8859-16", { "iso-ir-226", "latin10", 0 }, 112, { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, @@ -309,7 +311,7 @@ static const struct { // next bits generated again from tables on the Unicode 3.0 CD. // $ for a in CP* ; do (awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a) | sort | sed -e 's/#UNDEF.*$/0xFFFD/' | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done - +#ifndef Q_OS_SYMBIAN { "IBM850", { "CP850", "csPC850Multilingual", 0 }, 2009, { 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, @@ -344,6 +346,7 @@ static const struct { 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} }, +#endif //Q_OS_SYMBIAN { "IBM866", { "CP866", "csIBM866", 0 }, 2086, { 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, @@ -362,6 +365,7 @@ static const struct { 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0} }, +#ifndef Q_OS_SYMBIAN { "windows-1250", { "CP1250", 0 }, 2250, { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021, 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, @@ -516,6 +520,7 @@ static const struct { 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF} }, +#endif { "Apple Roman", { "macintosh", "MacRoman", 0 }, -168, { 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, @@ -534,8 +539,6 @@ static const struct { 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7} }, - - // This one is based on the charmap file // /usr/share/i18n/charmaps/SAMI-WS2.gz, which is manually adapted // to this format by Boerre Gaup <boerre@subdimension.com> @@ -557,7 +560,7 @@ static const struct { 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} }, - +#ifndef Q_OS_SYMBIAN // this one is generated from the charmap file located in /usr/share/i18n/charmaps // on most Linux distributions. The thai character set tis620 is byte by byte equivalent // to iso8859-11, so we name it 8859-11 here, but recognise the name tis620 too. @@ -581,6 +584,7 @@ static const struct { 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD } }, +#endif /* Name: hp-roman8 [HP-PCL5,RFC1345,KXS2] MIBenum: 2004 diff --git a/src/corelib/codecs/qsimplecodec_p.h b/src/corelib/codecs/qsimplecodec_p.h index b53eb95..57503b2 100644 --- a/src/corelib/codecs/qsimplecodec_p.h +++ b/src/corelib/codecs/qsimplecodec_p.h @@ -64,7 +64,11 @@ template <typename T> class QAtomicPointer; class QSimpleTextCodec: public QTextCodec { public: +#ifdef Q_OS_SYMBIAN + enum { numSimpleCodecs = 5 }; +#else enum { numSimpleCodecs = 30 }; +#endif explicit QSimpleTextCodec(int); ~QSimpleTextCodec(); diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index ca5e658..4034218 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -64,6 +64,7 @@ #ifndef QT_NO_CODECS # include "qtsciicodec_p.h" # include "qisciicodec_p.h" +#ifndef Q_OS_SYMBIAN # if defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED) // no iconv(3) support, must build all codecs into the library # include "../../plugins/codecs/cn/qgb18030codec.h" @@ -77,6 +78,7 @@ # include "qfontlaocodec_p.h" # include "../../plugins/codecs/jp/qfontjpcodec.h" # endif +#endif // QT_NO_SYMBIAN #endif // QT_NO_CODECS #include "qlocale.h" #include "qmutex.h" @@ -93,6 +95,11 @@ # define QT_NO_SETLOCALE #endif +#ifdef Q_OS_SYMBIAN +#include "qtextcodec_symbian.cpp" +#endif + + // enabling this is not exception safe! // #define Q_DEBUG_TEXTCODEC @@ -537,6 +544,12 @@ static QTextCodec *checkForCodec(const QByteArray &name) { */ static void setupLocaleMapper() { +#ifdef Q_OS_SYMBIAN + localeMapper = QSymbianTextCodec::localeMapper; + if (localeMapper) + return; +#endif + #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) localeMapper = QTextCodec::codecForName("System"); #else @@ -680,6 +693,17 @@ static void setup() (void) createQTextCodecCleanup(); #ifndef QT_NO_CODECS + (void)new QTsciiCodec; + for (int i = 0; i < 9; ++i) + (void)new QIsciiCodec(i); + + for (int i = 0; i < QSimpleTextCodec::numSimpleCodecs; ++i) + (void)new QSimpleTextCodec(i); + +#ifdef Q_OS_SYMBIAN + localeMapper = QSymbianTextCodec::init(); +#endif + # if defined(Q_WS_X11) && !defined(QT_BOOTSTRAPPED) // no font codecs when bootstrapping (void)new QFontLaoCodec; @@ -696,12 +720,8 @@ static void setup() # endif // QT_NO_ICONV && !QT_BOOTSTRAPPED # endif // Q_WS_X11 - (void)new QTsciiCodec; - - for (int i = 0; i < 9; ++i) - (void)new QIsciiCodec(i); - +#ifndef Q_OS_SYMBIAN # if defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED) // no asian codecs when bootstrapping, sorry (void)new QGb18030Codec; @@ -715,6 +735,7 @@ static void setup() (void)new QBig5Codec; (void)new QBig5hkscsCodec; # endif // QT_NO_ICONV && !QT_BOOTSTRAPPED +#endif //Q_OS_SYMBIAN #endif // QT_NO_CODECS #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) @@ -727,17 +748,18 @@ static void setup() (void)new QUtf32Codec; (void)new QUtf32BECodec; (void)new QUtf32LECodec; +#ifndef Q_OS_SYMBIAN (void)new QLatin15Codec; +#endif (void)new QLatin1Codec; (void)new QUtf8Codec; - for (int i = 0; i < QSimpleTextCodec::numSimpleCodecs; ++i) - (void)new QSimpleTextCodec(i); - +#ifndef Q_OS_SYMBIAN #if defined(Q_OS_UNIX) && !defined(QT_NO_ICONV) && !defined(QT_BOOTSTRAPPED) // QIconvCodec depends on the UTF-16 codec, so it needs to be created last (void) new QIconvCodec(); #endif +#endif if (!localeMapper) setupLocaleMapper(); @@ -1124,6 +1146,9 @@ QList<int> QTextCodec::availableMibs() */ void QTextCodec::setCodecForLocale(QTextCodec *c) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif localeMapper = c; if (!localeMapper) setupLocaleMapper(); diff --git a/src/corelib/codecs/qtextcodec_symbian.cpp b/src/corelib/codecs/qtextcodec_symbian.cpp new file mode 100644 index 0000000..e4db9d7 --- /dev/null +++ b/src/corelib/codecs/qtextcodec_symbian.cpp @@ -0,0 +1,678 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtextcodec_p.h" + +#include <private/qcore_symbian_p.h> +#include <QThreadStorage> +#include <QScopedPointer> + +#include <charconv.h> + +struct QSymbianCodecInitData { + uint charsetId; + int mib; + const char *aliases; +}; + +/* This table contains the known Symbian codecs aliases. It is ordered by charsetId. + It is required as symbian does not provide have aliases. + */ +static const QSymbianCodecInitData codecsData[] = { + { /*268439485*/ KCharacterSetIdentifierShiftJis, 17, "Shift_JIS\0MS_Kanji\0csShiftJIS\0MS_KANJI\0SJIS\0" }, + { /*268439486*/ KCharacterSetIdentifierGb2312, 57, "GB2312\0csGB2312\0CN-GB\0EUC-CN\0" }, + { /*268439487*/ KCharacterSetIdentifierBig5, 2026, "Big5\0csBig5\0Big5-ETen\0CP950\0BIG-FIVE\0CN-BIG5\0" }, + { /*268440246*/ KCharacterSetIdentifierCodePage1252, 2252, "windows-1252\0Code Page 1252\0CP1252\0MS-ANSI\0" }, +// { /*268450576*/ KCharacterSetIdentifierIso88591, 4, "ISO-8859-1\0ISO_8859-1:1987\0iso-ir-100\0ISO_8859-1\0latin1\0l1\0IBM819\0CP819\0csISOLatin1\0ISO-IR-100\0ISO8859-1\0L1\0LATIN1\0CSISOLATIN1\0" }, + { /*268451531*/ KCharacterSetIdentifierGbk, 113, "GBK\0MS936\0windows-936\0CP936\0" }, + { /*268451866*/ KCharacterSetIdentifierGb12345, 0, "GB12345\0" }, + { /*268455110*/ KCharacterSetIdentifierAscii, 3, "US-ASCII\0ANSI_X3.4-1968\0iso-ir-6\0ANSI_X3.4-1986\0ISO_646.irv:1991\0ASCII\0ISO646-US\0us\0IBM367\0cp367\0csASCII\0ISO-IR-6\0ISO_646.IRV:1991\0"}, + { /*268456062*/ KCharacterSetIdentifierIso88592, 5, "ISO-8859-2\0ISO_8859-2:1987\0iso-ir-101\0latin2\0l2\0csISOLatin2\0" }, + { /*268456063*/ KCharacterSetIdentifierIso88594, 7, "ISO-8859-4\0ISO_8859-4:1988\0iso-ir-110\0latin4\0l4\0csISOLatin4\0" }, + { /*268456064*/ KCharacterSetIdentifierIso88595, 8, "ISO-8859-5\0ISO_8859-5:1988\0iso-ir-144\0cyrillic\0csISOLatinCyrillic\0" }, + { /*268456065*/ KCharacterSetIdentifierIso88597, 10, "ISO-8859-7\0ISO_8859-7:1987\0iso-ir-126\0ELOT_928\0ECMA-118\0greek\0greek8\0csISOLatinGreek\0" }, + { /*268456066*/ KCharacterSetIdentifierIso88599, 12, "ISO-8859-9\0ISO_8859-9:1989\0iso-ir-148\0latin5\0l5\0csISOLatin5\0" }, + { /*268456875*/ KCharacterSetIdentifierSms7Bit, 0, "SMS 7-bit\0" }, + { /*268458028*/ KCharacterSetIdentifierUtf7, 103, "UTF-7\0UNICODE-1-1-UTF-7\0CSUNICODE11UTF7\0" }, +// { /*268458029*/ KCharacterSetIdentifierUtf8, 106, "UTF-8\0" }, + { /*268458030*/ KCharacterSetIdentifierImapUtf7, 0, "IMAP UTF-7\0" }, + { /*268458031*/ KCharacterSetIdentifierJavaConformantUtf8, 0, "JAVA UTF-8\0" }, + { /*268458454*/ 268458454, 2250, "Windows-1250\0CP1250\0MS-EE\0" }, + { /*268458455*/ 268458455, 2251, "Windows-1251\0CP1251\0MS-CYRL\0" }, + { /*268458456*/ 268458456, 2253, "Windows-1253\0CP1253\0MS-GREEK\0" }, + { /*268458457*/ 268458457, 2254, "Windows-1254\0CP1254\0MS-TURK\0" }, + { /*268458458*/ 268458458, 2257, "Windows-1257\0CP1257\0WINBALTRIM\0" }, + { /*268460133*/ KCharacterSetIdentifierHz, 2085, "HZ-GB-2312\0HZ\0" }, + { /*268460134*/ KCharacterSetIdentifierJis, 16, "JIS_Encoding\0JIS\0" }, + { /*268460135*/ KCharacterSetIdentifierEucJpPacked, 18, "EUC-JP\0Extended_UNIX_Code_Packed_Format_for_Japanese\0csEUCPkdFmtJapanese\0EUCJP_PACKED\0" }, + { /*268461728*/ KCharacterSetIdentifierIso2022Jp, 39, "ISO-2022-JP\0csISO2022JP\0JIS7\0" }, + { /*268461731*/ KCharacterSetIdentifierIso2022Jp1, 0, "ISO2022JP1\0" }, + { /*268470824*/ KCharacterSetIdentifierIso88593, 6, "ISO-8859-3\0ISO_8859-3:1988\0iso-ir-109\0latin3\0l3\0csISOLatin3\0" }, + { /*268470825*/ KCharacterSetIdentifierIso88596, 9, "ISO-8859-6\0ISO_8859-6:1987\0iso-ir-127\0ECMA-114\0ASMO-708\0arabic\0ISO88596\0csISOLatinArabic\0ARABIC\0" }, + { /*268470826*/ KCharacterSetIdentifierIso88598, 11, "ISO-8859-8\0ISO_8859-8:1988\0iso-ir-138\0hebrew\0csISOLatinHebrew\0" }, + { /*268470827*/ KCharacterSetIdentifierIso885910, 13, "ISO-8859-10\0iso-ir-157\0l6\0ISO_8859-10:1992\0csISOLatin6\0latin6\0" }, + { /*268470828*/ KCharacterSetIdentifierIso885913, 109, "ISO-8859-13\0ISO885913\0ISO-IR-179\0ISO8859-13\0L7\0LATIN7\0CSISOLATIN7\0" }, + { /*268470829*/ KCharacterSetIdentifierIso885914, 110, "ISO-8859-14\0iso-ir-199\0ISO_8859-14:1998\0latin8\0iso-celtic\0l8\0" }, + { /*268470830*/ KCharacterSetIdentifierIso885915, 111, "ISO-8859-15\0latin-9\0ISO-IR-203\0" }, +// { /*270483374*/ KCharacterSetIdentifierUnicodeLittle, 1014, "UTF-16LE\0Little-Endian UNICODE\0" }, +// { /*270483538*/ KCharacterSetIdentifierUnicodeBig, 1013, "UTF-16BE\0Big-Endian UNICODE\0" }, + { /*270501191*/ 270501191, 2255, "Windows-1255\0CP1255\0MS-HEBR\0" }, + { /*270501192*/ 270501192, 2256, "Windows-1256\0CP1256\0MS-ARAB\0" }, + { /*270501193*/ 270501193, 2259, "TIS-620\0ISO-IR-166\0TIS620-0\0TIS620.2529-1\0TIS620.2533-0\0TIS620.2533-1\0" }, + { /*270501194*/ 270501194, 0, "windows-874\0CP874\0IBM874\0" }, + { /*270501325*/ 270501325, 0, "SmsStrict\0" }, + { /*270501521*/ 270501521, 0, "ShiftJisDirectmap\0" }, + { /*270501542*/ 270501542, 0, "EucJpDirectmap\0" }, + /* 270501691 (duplicate) Windows-1252 | windows-1252 |Windows-1252 |Code Page 1252 |CP1252 |MS-ANSI |WINDOWS-1252 |2252 */ + { /*270501729*/ 270501729, 2088, "KOI8-U\0" }, + { /*270501752*/ 270501752, 2084, "KOI8-R\0csKOI8R\0" }, + { /*270529682*/ 270529682, 1000, "ISO-10646-UCS-2\0UCS-2\0CSUNICODE\0" }, + { /*270562232*/ 270562232, 2258, "Windows-1258\0CP1258\0WINDOWS-1258\0" }, + { /*270586888*/ 270586888, 0, "J5\0" }, + { /*271011982*/ 271011982, 0, "ISCII\0" }, + { /*271066541*/ 271066541, 2009, "CP850\0IBM850\0""850\0csPC850Multilingual\0" }, + { /*271082493*/ 271082493, 0, "EXTENDED_SMS_7BIT\0" }, + { /*271082494*/ 271082494, 0, "gsm7_turkish_single\0" }, + { /*271082495*/ 271082495, 0, "turkish_locking_gsm7ext\0" }, + { /*271082496*/ 271082496, 0, "turkish_locking_single\0" }, + { /*536929574*/ 536929574, 38, "EUC-KR\0" }, + { /*536936703*/ 536936703, 0, "CP949\0" }, + { /*536936705*/ 536936705, 37, "ISO-2022-KR\0" }, + { /*536941517*/ 536941517, 36, "KS_C_5601-1987\0" } + }; + + +class QSymbianTextCodec : public QTextCodec +{ +public: + QString convertToUnicode(const char*, int, ConverterState*) const; + QByteArray convertFromUnicode(const QChar*, int, ConverterState*) const; + QList<QByteArray> aliases() const; + QByteArray name() const; + int mibEnum() const; + + explicit QSymbianTextCodec(uint charsetId, int staticIndex = -1) : m_charsetId(charsetId), m_staticIndex(staticIndex) { } + + static QSymbianTextCodec *init(); + static QSymbianTextCodec *localeMapper; +private: + static CCnvCharacterSetConverter *converter(); + static uint getLanguageDependentCharacterSet(); + uint m_charsetId; + int m_staticIndex; +}; + +QSymbianTextCodec *QSymbianTextCodec::localeMapper = 0; + +class QSymbianTextCodecWithName : public QSymbianTextCodec +{ +public: + QSymbianTextCodecWithName(uint charsetId, const QByteArray &name) + : QSymbianTextCodec(charsetId) , m_name(name) { } + QByteArray name() const { return m_name; } + QList<QByteArray> aliases() const { return QList<QByteArray>(); } +private: + QByteArray m_name; +}; + +Q_GLOBAL_STATIC(QThreadStorage<CCnvCharacterSetConverter *>,gs_converterStore); + +CCnvCharacterSetConverter *QSymbianTextCodec::converter() +{ + CCnvCharacterSetConverter *&conv = gs_converterStore()->localData(); + if (!conv) + QT_TRAP_THROWING(conv = CCnvCharacterSetConverter::NewL()) + return conv; +} + + +QByteArray QSymbianTextCodec::name() const +{ + if (m_staticIndex >= 0) + return QByteArray(codecsData[m_staticIndex].aliases); + QScopedPointer<HBufC8> buf; + QT_TRAP_THROWING(buf.reset(converter()->ConvertCharacterSetIdentifierToStandardNameL(m_charsetId, qt_s60GetRFs()))) + if (buf) + return QByteArray(reinterpret_cast<const char *>(buf->Ptr()), buf->Length()); + return QByteArray(); +} + +int QSymbianTextCodec::mibEnum() const +{ + if (m_staticIndex >= 0) + return codecsData[m_staticIndex].mib; + int mib; + QT_TRAP_THROWING(mib = converter()->ConvertCharacterSetIdentifierToMibEnumL(m_charsetId, qt_s60GetRFs())) + return mib; +} + +QList<QByteArray> QSymbianTextCodec::aliases() const +{ + QList<QByteArray> result; + if (m_staticIndex >= 0) { + const char *aliases = codecsData[m_staticIndex].aliases; + aliases += strlen(aliases) + 1; + while (*aliases) { + int len = strlen(aliases); + result += QByteArray(aliases, len); + aliases += len + 1; + } + } + return result; +} + + +QString QSymbianTextCodec::convertToUnicode(const char *str, int len, ConverterState *state) const +{ + uint charsetId = m_charsetId; + + // no support for utf7 with state + if (state && (charsetId == KCharacterSetIdentifierUtf7 || + charsetId == KCharacterSetIdentifierImapUtf7)) { + return QString(); + } + CCnvCharacterSetConverter *converter = QSymbianTextCodec::converter(); + if (!str) { + return QString(); + } + + //Search the character set array containing all of the character sets for which conversion is available + CCnvCharacterSetConverter::TAvailability av; + QT_TRAP_THROWING(av = converter->PrepareToConvertToOrFromL(charsetId, qt_s60GetRFs())) + if (av == CCnvCharacterSetConverter::ENotAvailable) { + return QString(); + } + + char *str2; + int len2; + QByteArray helperBA; + if (state && (state->remainingChars > 0)) { + // we should prepare the input string ourselves + // the real size + len2 = len + state->remainingChars; + helperBA.resize(len2); + str2 = helperBA.data(); + if (state->remainingChars > 3) { // doesn't happen usually + memcpy(str2, state->d, state->remainingChars); + qFree(state->d); + state->d = 0; + } else { + char charTbl[3]; + charTbl[0] = state->state_data[0]; + charTbl[1] = state->state_data[1]; + charTbl[2] = state->state_data[2]; + memcpy(str2, charTbl, state->remainingChars); + } + memcpy(str2+state->remainingChars, str, len); + } + else { + len2 = len; + str2 = const_cast<char*>(str); + } + + QString UnicodeText(len2, Qt::Uninitialized); + TPtrC8 remainderOfForeignText; + remainderOfForeignText.Set(reinterpret_cast<const unsigned char *>(str2), len2); + + int numberOfUnconvertibleCharacters = 0; + int indexOfFirstUnconvertibleCharacter; + + // Use null character as replacement, if it is asked + bool convertToNull = (state && (state->flags & QTextCodec::ConvertInvalidToNull)); + if (convertToNull) { + _LIT8(KReplacement, "\x00"); + QT_TRAP_THROWING(converter->SetReplacementForUnconvertibleUnicodeCharactersL(KReplacement)) + } + // use state->invalidChars for keeping symbian state + int sState = CCnvCharacterSetConverter::KStateDefault; + if (state && (state->invalidChars != CCnvCharacterSetConverter::KStateDefault)) { + sState = state->invalidChars; + } + //Convert text encoded in a non-Unicode character set into the Unicode character set (UCS-2). + int remainingChars = -1; + int initial_size=0; + while (1) { + TPtr16 UnicodePtr(reinterpret_cast<unsigned short *>(UnicodeText.data()+initial_size), UnicodeText.size()); + QT_TRAP_THROWING(remainingChars = converter->ConvertToUnicode(UnicodePtr, + remainderOfForeignText, + sState, + numberOfUnconvertibleCharacters, + indexOfFirstUnconvertibleCharacter)) + + initial_size += UnicodePtr.Length(); + // replace 0xFFFD with 0x0000 and only if state set to convert to it + if (numberOfUnconvertibleCharacters>0 && convertToNull) { + int len2 = UnicodePtr.Length(); + for (int i = indexOfFirstUnconvertibleCharacter; i < len2; i++) { + UnicodePtr[i] = 0x0000; + } + } + // success + if (remainingChars==KErrNone) { + break; + } + // if ConvertToUnicode could not consume the foreign text at all + // UTF-8: EErrorIllFormedInput = KErrCorrupt + // UCS-2: KErrNotFound + if (remainingChars == CCnvCharacterSetConverter::EErrorIllFormedInput || + remainingChars == KErrNotFound) { + remainingChars = remainderOfForeignText.Size(); + break; + } + else { + if (remainingChars < 0) { + return QString(); + } + } + // + UnicodeText.resize(UnicodeText.size() + remainingChars*2); + remainderOfForeignText.Set(reinterpret_cast<const unsigned char *>(str2+len2-remainingChars), remainingChars); + } + // save symbian state + if (state) { + state->invalidChars = sState; + } + + if (remainingChars > 0) { + if (!state) { + // No way to signal, if there is still remaining chars, for ex. UTF-8 still can have + // some characters hanging around. + return QString(); + } + const unsigned char *charPtr = remainderOfForeignText.Right(remainingChars).Ptr(); + if (remainingChars > 3) { // doesn't happen usually + state->d = (void*)qMalloc(remainingChars); + if (!state->d) + return QString(); + // copy characters there + memcpy(state->d, charPtr, remainingChars); + } + else { + // fallthru is correct + switch (remainingChars) { + case 3: + state->state_data[2] = charPtr[2]; + case 2: + state->state_data[1] = charPtr[1]; + case 1: + state->state_data[0] = charPtr[0]; + } + } + state->remainingChars = remainingChars; + } + else { + if (state) { + // If we continued from an earlier iteration + state->remainingChars = 0; + } + } + // check if any ORIGINAL headers should be left + if (initial_size > 0) { + if (!state || (state && !(state->flags & QTextCodec::IgnoreHeader))) { + // always skip headers on following state loops + if (state) { + state->flags |= QTextCodec::IgnoreHeader; + } + const TUint16 *ptr = reinterpret_cast<const TUint16 *>(UnicodeText.data()); + if (ptr[0] == QChar::ByteOrderMark || ptr[0] == QChar::ByteOrderSwapped) { + return UnicodeText.mid(1, initial_size - 1); + } + } + } + if (initial_size >= 0) { + UnicodeText.resize(initial_size); + return UnicodeText; + } + else { + return QString(); + } +} + + +QByteArray QSymbianTextCodec::convertFromUnicode(const QChar *str, int len, ConverterState *state) const +{ + uint charsetId = m_charsetId; + CCnvCharacterSetConverter *converter = QSymbianTextCodec::converter(); + if (!str) + return QByteArray(); + + if (len == 0) + return QByteArray(); + + // no support for utf7 with state + if (state && (charsetId == KCharacterSetIdentifierUtf7 || + charsetId == KCharacterSetIdentifierImapUtf7)) + return QByteArray(); + + //Get reference file session from backend + RFs &fileSession = qt_s60GetRFs(); + + //Search the character set array containing all of the character sets for which conversion is available + CCnvCharacterSetConverter::TAvailability av = CCnvCharacterSetConverter::ENotAvailable; + QT_TRAP_THROWING(av = converter->PrepareToConvertToOrFromL(charsetId, fileSession)) + if (av == CCnvCharacterSetConverter::ENotAvailable) + return QByteArray(); + + // Use null character as replacement, if it is asked + if (state && (state->flags & QTextCodec::ConvertInvalidToNull)) { + _LIT8(KReplacement, "\x00"); + QT_TRAP_THROWING(converter->SetReplacementForUnconvertibleUnicodeCharactersL(KReplacement)) + } + else { + _LIT8(KReplacement, "?"); + QT_TRAP_THROWING(converter->SetReplacementForUnconvertibleUnicodeCharactersL(KReplacement)) + } + QByteArray outputBuffer; + + // add header if no state (one run), or if no ignoreheader (from first state) + int bomofs = 0; + if (!state || (state && !(state->flags & QTextCodec::IgnoreHeader))) { + + QChar bom(QChar::ByteOrderMark); + + if (state) + state->flags |= QTextCodec::IgnoreHeader; // bom handling only on first state + + switch (charsetId) { + case KCharacterSetIdentifierUcs2: + outputBuffer.append(bom.row()); + outputBuffer.append(bom.cell()); + bomofs = 2; + break; + + case KCharacterSetIdentifierUtf8: // we don't add bom for UTF-8 + case KCharacterSetIdentifierJavaConformantUtf8: + /*outputBuffer.append("\xef\xbb\xbf"); + bomofs = 3; + */ + break; + + case KCharacterSetIdentifierUnicodeLittle: + outputBuffer.append(bom.cell()); + outputBuffer.append(bom.row()); + bomofs = 2; + break; + + case KCharacterSetIdentifierUnicodeBig: + outputBuffer.append(bom.row()); + outputBuffer.append(bom.cell()); + bomofs = 2; + break; + + default: + break; + } + } + + // len is 16bit chars, reserve 3 8bit chars for each input char + // jsz - it could be differentiated, to allocate less + outputBuffer.resize(len * 3 + bomofs); + + // loop for too short output buffer + int unconverted; + int numberOfUnconvertibleCharacters = len; + int indexOfFirstUnconvertibleCharacter; + int convertedSize; + int lastUnconverted = 0; + int initial_size=0; + int remainderToConvert = len; + while (1) { + TPtr8 outputPtr(reinterpret_cast<unsigned char *>(outputBuffer.data() + bomofs + initial_size), outputBuffer.size() - bomofs); + + TPtrC16 UnicodeText(reinterpret_cast<const unsigned short *>(str+len-remainderToConvert), remainderToConvert); + + //Convert text encoded in the Unicode character set (UCS-2) into other character sets + unconverted = -1; + QT_TRAP_THROWING( unconverted = converter->ConvertFromUnicode(outputPtr, + UnicodeText, + numberOfUnconvertibleCharacters, + indexOfFirstUnconvertibleCharacter)) + initial_size += outputPtr.Length(); + if (unconverted < 0) { + return QByteArray(); + } + + + if (unconverted == 0 ) { + convertedSize = initial_size; + break; + } + + // check what means unconverted > 0 + if (indexOfFirstUnconvertibleCharacter<0) { + // 8859-6 and 8859-8 break with certain input (string of \xc0 - \xd9 converted to unicode and back) + if (unconverted == lastUnconverted) { + return QByteArray(); + } + lastUnconverted = unconverted; + } + else { + // were some character not possible to convert + + } + remainderToConvert = unconverted; // len - indexOfFirstUnconvertibleCharacter; + // resize output buffer, use =op for the null check + outputBuffer.resize(outputBuffer.size() + remainderToConvert * 3 + bomofs); + }; + + // shorten output + outputBuffer.resize(convertedSize + bomofs); + + if (state) { + state->invalidChars = numberOfUnconvertibleCharacters; + + // check if any Symbian CONVERTED headers should be removed + if (state->flags & QTextCodec::IgnoreHeader && state->state_data[0] == 0) { + + state->state_data[0] = 0xff; // bom handling only on first state + + if (charsetId == KCharacterSetIdentifierUcs2 && outputBuffer.size() > 1) { + + QChar bom(QChar::ByteOrderMark); + if (outputBuffer.at(0) == bom.row() && outputBuffer.at(1) == bom.cell()) { + outputBuffer.remove(0, 2); + } else if (outputBuffer.at(0) == bom.cell() && outputBuffer.at(1) == bom.row()) { + outputBuffer.remove(0, 2); + } + + } else if ((charsetId == KCharacterSetIdentifierUtf8 || + charsetId == KCharacterSetIdentifierJavaConformantUtf8) && + outputBuffer.size() > 2) { + if (outputBuffer.at(0) == 0xef && outputBuffer.at(1) == 0xbb && outputBuffer.at(2) == 0xbf) { + outputBuffer.remove(0, 3); + } + + } else if (charsetId == KCharacterSetIdentifierUnicodeLittle && + outputBuffer.size() > 1) { + + QChar bom(QChar::ByteOrderMark); + if (outputBuffer.at(0) == bom.row() && outputBuffer.at(1) == bom.cell()) { + outputBuffer.remove(0, 2); + } + + } else if (charsetId == KCharacterSetIdentifierUnicodeBig && + outputBuffer.size() > 1) { + + QChar bom(QChar::ByteOrderSwapped); + if (outputBuffer.at(0) == bom.row() && outputBuffer.at(1) == bom.cell()) { + outputBuffer.remove(0, 2); + } + } + + } + } + + return outputBuffer; +} + + +uint QSymbianTextCodec::getLanguageDependentCharacterSet() +{ + TLanguage lang = User::Language(); + + uint langIndex = 0; + + switch (lang) { + case 14: //ELangTurkish + langIndex = KCharacterSetIdentifierIso88599; break; + case 16: //ELangRussian + langIndex = KCharacterSetIdentifierIso88595; break; + case 17: //ELangHungarian + langIndex = KCharacterSetIdentifierIso88592; break; + case 25: //ELangCzec + case 26: //ELangSlovak + case 27: //ELangPolish + case 28: //ELangSlovenian + langIndex = KCharacterSetIdentifierIso88592; break; + case 29: //ELangTaiwanChinese + case 30: //ELangHongKongChinese + langIndex = KCharacterSetIdentifierBig5; break; + case 31: //ELangPrcChinese + langIndex = KCharacterSetIdentifierGbk; break; + case 32: //ELangJapanese + langIndex = KCharacterSetIdentifierShiftJis; break; + case 33: //ELangThai + langIndex = 270501193 /*KCharacterSetIdentifierTis620*/; break; + case 37: //ELangArabic + langIndex = KCharacterSetIdentifierIso88596; break; + case 40: //ELangBelarussian + case 42: //ELangBulgarian + langIndex = KCharacterSetIdentifierIso88595; break; + case 45: //ELangCroatian + langIndex = KCharacterSetIdentifierIso88592; break; + case 49: //ELangEstonian + langIndex = KCharacterSetIdentifierIso88594; break; + case 54: //ELangGreek + case 55: //ELangCyprusGreek + langIndex = KCharacterSetIdentifierIso88597; break; + case 57: //ELangHebrew + langIndex = KCharacterSetIdentifierIso88598; break; + case 58: //ELangHindi + langIndex = 271011982/*KCharacterSetIdentifierIscii*/; break; + case 67: //ELangLatvian + case 68: //ELangLithuanian + langIndex = KCharacterSetIdentifierIso88594; break; + case 69: //ELangMacedonian + langIndex = KCharacterSetIdentifierIso88595; break; + case 78: //ELangRomanian + langIndex = KCharacterSetIdentifierIso88592; break; + case 79: //ELangSerbian + langIndex = KCharacterSetIdentifierIso88592; break; + case 91: //ELangCyprusTurkish + langIndex = KCharacterSetIdentifierIso88599; break; + case 93: //ELangUkrainian + langIndex = KCharacterSetIdentifierIso88595; break; + case 94: //ELangUrdu + langIndex = KCharacterSetIdentifierIso88596; break; + case 157: //ELangEnglish_Taiwan + case 158: //ELangEnglish_HongKong + langIndex = KCharacterSetIdentifierBig5; break; + case 159: //ELangEnglish_Prc + langIndex = KCharacterSetIdentifierGbk; break; + case 160: + langIndex = KCharacterSetIdentifierShiftJis; break; + case 161: //ELangEnglish_Thailand + langIndex = 270501193/*KCharacterSetIdentifierTis620*/; break; + } + + if (langIndex > 0) { + return langIndex; + } + return KCharacterSetIdentifierCodePage1252; +} + +/* Create the codecs that have aliases and return the locale mapper*/ +QSymbianTextCodec *QSymbianTextCodec::init() +{ + const uint localeMapperId = getLanguageDependentCharacterSet(); + QScopedPointer<CArrayFix<CCnvCharacterSetConverter::SCharacterSet> > array; + QT_TRAP_THROWING(array.reset(CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(qt_s60GetRFs()))) + CCnvCharacterSetConverter *converter = QSymbianTextCodec::converter(); + int count = array->Count(); + for (int i = 0; i < count; i++) { + int charsetId = array->At(i).Identifier(); + + // skip builtin Qt codecs + if (charsetId == KCharacterSetIdentifierUtf8 || charsetId == KCharacterSetIdentifierUnicodeLittle + || charsetId == KCharacterSetIdentifierUnicodeLittle || charsetId == KCharacterSetIdentifierUnicodeBig + || charsetId == KCharacterSetIdentifierIso88591 + || charsetId == 270501691 /* skip Windows-1252 duplicate*/) { + continue; + } + + int begin = 0; + int n = sizeof(codecsData) / sizeof(codecsData[0]); + int half; + + while (n > 0) { + half = n >> 1; + int middle = begin + half; + if (codecsData[middle].charsetId < charsetId) { + begin = middle + 1; + n -= half + 1; + } else { + n = half; + } + } + if (codecsData[begin].charsetId == charsetId) { + QSymbianTextCodec *c = new QSymbianTextCodec(charsetId, begin); + if (charsetId == localeMapperId) + localeMapper = c; + } else { + QScopedPointer<HBufC8> buf; + QT_TRAP_THROWING(buf.reset(converter->ConvertCharacterSetIdentifierToStandardNameL(charsetId, qt_s60GetRFs()))) + QByteArray name; + if (buf && buf->Length()) { + name = QByteArray(reinterpret_cast<const char *>(buf->Ptr()), buf->Length()); + } else { + TPtrC charSetName = array->At(i).NameIsFileName() ? TParsePtrC(array->At(i).Name()).Name() : array->At(i).Name(); + int len = charSetName.Length(); + QString str; + str.setUnicode(reinterpret_cast<const QChar*>(charSetName.Ptr()), len); + name = str.toLatin1(); + } + if (!name.isEmpty()) + new QSymbianTextCodecWithName(charsetId, name); + } + + } + return localeMapper; +} diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 9e79894..b1c403f 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -70,7 +70,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384; have reached the end of the data stream, with stdin. The reason for this is that as long as stdin doesn't give any input to the QTextStream, \c atEnd() will return true even if the stdin is open and waiting for more characters. - + Besides using QTextStream's constructors, you can also set the device or string QTextStream operates on by calling setDevice() or setString(). You can seek to a position by calling seek(), and @@ -1196,6 +1196,7 @@ bool QTextStream::seek(qint64 pos) resetCodecConverterStateHelper(&d->writeConverterState); delete d->readConverterSavedState; d->readConverterSavedState = 0; + d->writeConverterState.flags |= QTextCodec::IgnoreHeader; #endif return true; } diff --git a/src/declarative/graphicsitems/qdeclarativeparticles.cpp b/src/declarative/graphicsitems/qdeclarativeparticles.cpp index ec0bf6c..593c80a 100644 --- a/src/declarative/graphicsitems/qdeclarativeparticles.cpp +++ b/src/declarative/graphicsitems/qdeclarativeparticles.cpp @@ -1263,7 +1263,7 @@ void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphics const int myY = y() + parentItem()->y(); #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) - QVarLengthArray<QPainter::Fragment, 256> pixmapData; + QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData; #else QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData; #endif diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 1145235..78184a9 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -679,16 +679,20 @@ void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto d->defaultItemHeight = indexRowSizeHint(topLeft); bool sizeChanged = false; if (topViewIndex != -1) { - if (topLeft == bottomRight) { + if (topLeft.row() == bottomRight.row()) { int oldHeight = d->itemHeight(topViewIndex); d->invalidateHeightCache(topViewIndex); sizeChanged = (oldHeight != d->itemHeight(topViewIndex)); + if (topLeft.column() == 0) + d->viewItems[topViewIndex].hasChildren = d->hasVisibleChildren(topLeft); } else { int bottomViewIndex = d->viewIndex(bottomRight); for (int i = topViewIndex; i <= bottomViewIndex; ++i) { int oldHeight = d->itemHeight(i); d->invalidateHeightCache(i); sizeChanged |= (oldHeight != d->itemHeight(i)); + if (topLeft.column() == 0) + d->viewItems[i].hasChildren = d->hasVisibleChildren(d->viewItems.at(i).index); } } } diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index d76c709..a62f06b 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -1081,7 +1081,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, according to the \a margins structure. */ -typedef QVarLengthArray<QPainter::Fragment, 16> QPixmapFragmentsArray; +typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; /*! \since 4.6 @@ -1102,7 +1102,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) { - QPainter::Fragment d; + QPainter::PixmapFragment d; d.opacity = 1.0; d.rotation = 0.0; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 98762f0..1fd622d 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -970,8 +970,8 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con fill(path, brush); } -void QPaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, - const QPixmap &pixmap, QPainter::FragmentHints /*hints*/) +void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, + const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/) { qreal oldOpacity = state()->opacity; QTransform oldTransform = state()->matrix; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 2401b94..6c654bd 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -197,7 +197,8 @@ public: virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - virtual void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints); + virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QFlags<QPainter::PixmapFragmentHint> hints); virtual void updateState(const QPaintEngineState &state); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 066725e..a1ed8f5 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7994,10 +7994,11 @@ start_lengthVariant: for (int i = 0; i < textLayout.lineCount(); i++) { QTextLine line = textLayout.lineAt(i); + qreal advance = textLayout.engine()->lines[i].textAdvance.toReal(); if (tf & Qt::AlignRight) - xoff = r.width() - line.naturalTextWidth(); + xoff = r.width() - advance; else if (tf & Qt::AlignHCenter) - xoff = (r.width() - line.naturalTextWidth())/2; + xoff = (r.width() - advance)/2; line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff)); } @@ -8914,11 +8915,11 @@ QTransform QPainter::combinedTransform() const This function is potentially faster than multiple calls to drawPixmap(), since the backend can optimize state changes. - \sa QPainter::Fragment, QPainter::FragmentHint + \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint */ -void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount, - const QPixmap &pixmap, FragmentHints hints) +void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, + const QPixmap &pixmap, PixmapFragmentHints hints) { Q_D(QPainter); @@ -8959,7 +8960,7 @@ void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount, /*! \since 4.7 - \class QPainter::Fragment + \class QPainter::PixmapFragment \brief This class is used in conjunction with the QPainter::drawPixmapFragments() function to specify how a pixmap, or @@ -8980,73 +8981,73 @@ void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount, /*! \since 4.7 - This is a convenience function that returns a QPainter::Fragment that is + This is a convenience function that returns a QPainter::PixmapFragment that is initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a rotation, \a opacity parameters. */ -QPainter::Fragment QPainter::Fragment::create(const QPointF &pos, const QRectF &sourceRect, +QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect, qreal scaleX, qreal scaleY, qreal rotation, qreal opacity) { - Fragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(), - sourceRect.height(), scaleX, scaleY, rotation, opacity}; + PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(), + sourceRect.height(), scaleX, scaleY, rotation, opacity}; return fragment; } /*! - \variable QPainter::Fragment::x + \variable QPainter::PixmapFragment::x \brief the x coordinate of center point in the target rectangle. */ /*! - \variable QPainter::Fragment::y + \variable QPainter::PixmapFragment::y \brief the y coordinate of the center point in the target rectangle. */ /*! - \variable QPainter::Fragment::sourceLeft + \variable QPainter::PixmapFragment::sourceLeft \brief the left coordinate of the source rectangle. */ /*! - \variable QPainter::Fragment::sourceTop + \variable QPainter::PixmapFragment::sourceTop \brief the top coordinate of the source rectangle. */ /*! - \variable QPainter::Fragment::width + \variable QPainter::PixmapFragment::width \brief the width of the source rectangle and is used to calculate the width of the target rectangle. */ /*! - \variable QPainter::Fragment::height + \variable QPainter::PixmapFragment::height \brief the height of the source rectangle and is used to calculate the height of the target rectangle. */ /*! - \variable QPainter::Fragment::scaleX + \variable QPainter::PixmapFragment::scaleX \brief the horizontal scale of the target rectangle. */ /*! - \variable QPainter::Fragment::scaleY + \variable QPainter::PixmapFragment::scaleY \brief the vertical scale of the target rectangle. */ /*! - \variable QPainter::Fragment::rotation + \variable QPainter::PixmapFragment::rotation \brief the rotation of the target rectangle in degrees. The target rectangle is rotated after it has been scaled. */ /*! - \variable QPainter::Fragment::opacity + \variable QPainter::PixmapFragment::opacity \brief the opacity of the target rectangle, where 0.0 is fully transparent and 1.0 is fully opaque. @@ -9055,12 +9056,12 @@ QPainter::Fragment QPainter::Fragment::create(const QPointF &pos, const QRectF & /*! \since 4.7 - \enum QPainter::FragmentHint + \enum QPainter::PixmapFragmentHint \value OpaqueHint Indicates that the pixmap fragments to be drawn are opaque. Opaque fragments are potentially faster to draw. - \sa QPainter::drawPixmapFragments(), QPainter::Fragment + \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment */ void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation) diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index bcb0b50..443925b 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -99,7 +99,7 @@ public: Q_DECLARE_FLAGS(RenderHints, RenderHint) - class Fragment { + class PixmapFragment { public: qreal x; qreal y; @@ -111,16 +111,16 @@ public: qreal scaleY; qreal rotation; qreal opacity; - static Fragment Q_GUI_EXPORT create(const QPointF &pos, const QRectF &sourceRect, + static PixmapFragment Q_GUI_EXPORT create(const QPointF &pos, const QRectF &sourceRect, qreal scaleX = 1, qreal scaleY = 1, qreal rotation = 0, qreal opacity = 1); }; - enum FragmentHint { + enum PixmapFragmentHint { OpaqueHint = 0x01 }; - Q_DECLARE_FLAGS(FragmentHints, FragmentHint) + Q_DECLARE_FLAGS(PixmapFragmentHints, PixmapFragmentHint) QPainter(); explicit QPainter(QPaintDevice *); @@ -375,8 +375,8 @@ public: inline void drawPixmap(const QRect &r, const QPixmap &pm); inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm); - void drawPixmapFragments(const Fragment *fragments, int fragmentCount, - const QPixmap &pixmap, FragmentHints hints = 0); + void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, + const QPixmap &pixmap, PixmapFragmentHints hints = 0); void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags = Qt::AutoColor); diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index f36cbd2..5054b66 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -382,6 +382,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine QFixed y; QFixed width; QFixed textWidth; + QFixed textAdvance; int from; signed int length : 29; mutable uint justified : 1; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index af91603..cc6793d 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1875,6 +1875,7 @@ void QTextLine::layout_helper(int maxGlyphs) line.textWidth += lbh.softHyphenWidth; } + line.textAdvance = line.textWidth; line.textWidth += lbh.rightBearing; goto found; @@ -1885,6 +1886,7 @@ void QTextLine::layout_helper(int maxGlyphs) } LB_DEBUG("reached end of line"); lbh.checkFullOtherwiseExtend(line); + line.textAdvance = line.textWidth; line.textWidth += lbh.rightBearing; found: diff --git a/src/multimedia/effects/qsoundeffect.cpp b/src/multimedia/effects/qsoundeffect.cpp index a5cb20f..53cad8e 100644 --- a/src/multimedia/effects/qsoundeffect.cpp +++ b/src/multimedia/effects/qsoundeffect.cpp @@ -132,7 +132,7 @@ QSoundEffect::QSoundEffect(QObject *parent) : QSoundEffect::~QSoundEffect() { - delete d; + d->deleteLater(); } QUrl QSoundEffect::source() const diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.cpp b/src/multimedia/effects/qsoundeffect_pulse_p.cpp index c322722..e379259 100644 --- a/src/multimedia/effects/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/effects/qsoundeffect_pulse_p.cpp @@ -234,6 +234,7 @@ Q_GLOBAL_STATIC(PulseDaemon, daemon) QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), + m_retry(false), m_muted(false), m_playQueued(false), m_sampleLoaded(false), @@ -250,7 +251,7 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QSoundEffectPrivate::~QSoundEffectPrivate() { - delete m_reply; + m_reply->deleteLater(); unloadSample(); } @@ -310,6 +311,12 @@ void QSoundEffectPrivate::setMuted(bool muted) void QSoundEffectPrivate::play() { + if (m_retry) { + m_retry = false; + setSource(m_source); + return; + } + if (!m_sampleLoaded) { m_playQueued = true; return; @@ -338,6 +345,7 @@ void QSoundEffectPrivate::decoderReady() pa_stream_set_state_callback(stream, stream_state_callback, this); pa_stream_set_write_callback(stream, stream_write_callback, this); pa_stream_connect_upload(stream, (size_t)m_waveDecoder->size()); + m_pulseStream = stream; daemon()->unlock(); } @@ -377,6 +385,52 @@ void QSoundEffectPrivate::unloadSample() m_sampleLoaded = false; } +void QSoundEffectPrivate::uploadSample() +{ + daemon()->lock(); + + size_t bufferSize = qMin(pa_stream_writable_size(m_pulseStream), + size_t(m_waveDecoder->bytesAvailable())); + char buffer[bufferSize]; + + size_t len = 0; + while (len < (m_waveDecoder->size())) { + qint64 read = m_waveDecoder->read(buffer, qMin((int)bufferSize, + (int)(m_waveDecoder->size()-len))); + if (read > 0) { + if (pa_stream_write(m_pulseStream, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0) + len += size_t(read); + else + break; + } + } + + m_dataUploaded += len; + pa_stream_set_write_callback(m_pulseStream, NULL, NULL); + + if (m_waveDecoder->size() == m_dataUploaded) { + int err = pa_stream_finish_upload(m_pulseStream); + if(err != 0) { + qWarning("pa_stream_finish_upload() err=%d",err); + pa_stream_disconnect(m_pulseStream); + m_retry = true; + m_playQueued = false; + QMetaObject::invokeMethod(this, "play"); + daemon()->unlock(); + return; + } + m_duration = m_waveDecoder->duration(); + m_waveDecoder->deleteLater(); + m_stream->deleteLater(); + m_sampleLoaded = true; + if (m_playQueued) { + m_playQueued = false; + QMetaObject::invokeMethod(this, "play"); + } + } + daemon()->unlock(); +} + void QSoundEffectPrivate::playSample() { pa_volume_t volume = PA_VOLUME_NORM; @@ -412,36 +466,7 @@ void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, voi QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); - size_t bufferSize = qMin(pa_stream_writable_size(s), - size_t(self->m_waveDecoder->bytesAvailable())); - char buffer[bufferSize]; - - size_t len = 0; - while (len < length) { - qint64 read = self->m_waveDecoder->read(buffer, qMin(bufferSize, length -len)); - if (read > 0) { - if (pa_stream_write(s, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0) - len += size_t(read); - else - break; - } - } - self->m_dataUploaded += len; - - if (self->m_waveDecoder->size() == self->m_dataUploaded) { - pa_stream_finish_upload(s); - - self->m_duration = self->m_waveDecoder->duration(); - - self->m_waveDecoder->deleteLater(); - self->m_stream->deleteLater(); - - self->m_sampleLoaded = true; - if (self->m_playQueued) { - self->m_playQueued = false; - QMetaObject::invokeMethod(self, "play"); - } - } + QMetaObject::invokeMethod(self, "uploadSample", Qt::QueuedConnection); } void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.h b/src/multimedia/effects/qsoundeffect_pulse_p.h index 3aed018..aff729c 100644 --- a/src/multimedia/effects/qsoundeffect_pulse_p.h +++ b/src/multimedia/effects/qsoundeffect_pulse_p.h @@ -97,6 +97,7 @@ private Q_SLOTS: void decoderReady(); void decoderError(); void checkPlayTime(); + void uploadSample(); private: void loadSample(); @@ -109,6 +110,9 @@ private: static void stream_state_callback(pa_stream *s, void *userdata); static void play_callback(pa_context *c, int success, void *userdata); + pa_stream *m_pulseStream; + + bool m_retry; bool m_muted; bool m_playQueued; bool m_sampleLoaded; diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp index 43ba22f..36c36dd 100644 --- a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp +++ b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp @@ -67,8 +67,6 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): m_player(0) { m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency); - connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged())); - connect(m_player, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged())); connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(stateChanged(QMediaPlayer::State))); } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8eb72b0..2b5f2f4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1641,7 +1641,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp s->matrix = old; } -void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints) +void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints) { Q_D(QGL2PaintEngineEx); // Use fallback for extended composition modes. @@ -1655,9 +1656,9 @@ void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::Fragment *fragments, } -void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::Fragment *fragments, +void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QPainter::FragmentHints hints) + QPainter::PixmapFragmentHints hints) { GLfloat dx = 1.0f / pixmap.size().width(); GLfloat dy = 1.0f / pixmap.size().height(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 5d3608b..ed8fbbc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -125,7 +125,8 @@ public: virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints); + virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor); virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); @@ -196,7 +197,8 @@ public: void fill(const QVectorPath &path); void stroke(const QVectorPath &path, const QPen &pen); void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); - void drawPixmapFragments(const QPainter::Fragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::FragmentHints hints); + void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem, bool includeMatrixInCache); diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 4df894a..2c850c9 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -3041,8 +3041,8 @@ void QVGPaintEngine::drawTiledPixmap // (i.e. no opacity), no rotation or scaling, and drawing the full // pixmap rather than parts of the pixmap. Even having just one of // these conditions will improve performance. -void QVGPaintEngine::drawPixmapFragments(const QPainter::Fragment *drawingData, int dataCount, - const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints) +void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, + const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints) { #if !defined(QT_SHIVAVG) Q_D(QVGPaintEngine); diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h index 1203af5..1e7e26c 100644 --- a/src/openvg/qpaintengine_vg_p.h +++ b/src/openvg/qpaintengine_vg_p.h @@ -137,7 +137,8 @@ public: void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); - void drawPixmapFragments(const QPainter::Fragment *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QPainter::FragmentHint> hints); + void drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, const QPixmap &pixmap, + QFlags<QPainter::PixmapFragmentHint> hints); void drawTextItem(const QPointF &p, const QTextItem &textItem); void drawStaticTextItem(QStaticTextItem *staticTextItem); diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp index 952a6a3..b6522ad 100644 --- a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp @@ -111,8 +111,6 @@ void QNativeWifiEngine::scanComplete() { QMutexLocker locker(&mutex); - QStringList previous = accessPointConfigurations.keys(); - // enumerate interfaces WLAN_INTERFACE_INFO_LIST *interfaceList; DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList); @@ -120,9 +118,15 @@ void QNativeWifiEngine::scanComplete() #ifdef BEARER_MANAGEMENT_DEBUG qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); #endif + + locker.unlock(); + emit updateCompleted(); + return; } + QStringList previous = accessPointConfigurations.keys(); + for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i]; @@ -458,18 +462,31 @@ void QNativeWifiEngine::requestUpdate() #ifdef BEARER_MANAGEMENT_DEBUG qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result); #endif + + locker.unlock(); + emit updateCompleted(); + return; } + bool requested = false; for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) { result = local_WlanScan(handle, &interfaceList->InterfaceInfo[i].InterfaceGuid, 0, 0, 0); + if (result != ERROR_SUCCESS) { #ifdef BEARER_MANAGEMENT_DEBUG - if (result != ERROR_SUCCESS) qDebug("%s: WlanScan failed with error %ld\n", __FUNCTION__, result); #endif + } else { + requested = true; + } } local_WlanFreeMemory(interfaceList); + + if (!requested) { + locker.unlock(); + emit updateCompleted(); + } } QNetworkSession::State QNativeWifiEngine::sessionStateForId(const QString &id) |