Fix bug 3759 for qt < 4.2

* src/support/qstring_helpers.cpp
	(toqstr): Use iconv for surrogate pairs
	(qstring_to_ucs4): ditto

	* src/support/qstring_helpers.h
	(qchar_to_ucs4): Remove obsolete comment, the doxygen doc is more
	accurate


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18622 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2007-06-01 09:39:19 +00:00
parent 7364821cf6
commit 1d64673c22
2 changed files with 34 additions and 10 deletions

View File

@ -12,6 +12,7 @@
#include <config.h> #include <config.h>
#include "qstring_helpers.h" #include "qstring_helpers.h"
#include "unicode.h"
#include <QVector> #include <QVector>
@ -24,12 +25,25 @@ using std::string;
// We use QString::fromUcs4 in Qt 4.2 and higher // We use QString::fromUcs4 in Qt 4.2 and higher
QString const toqstr(docstring const & str) QString const toqstr(docstring const & str)
{ {
// This does not properly convert surrogate pairs
QString s; QString s;
int i = static_cast<int>(str.size()); int i = static_cast<int>(str.size());
s.resize(i); s.resize(i);
for (; --i >= 0;) for (; --i >= 0;) {
s[i] = ucs4_to_qchar(str[i]); char_type const c = str[i];
if (is_utf16(c))
// Use a simple cast in the common case for speed
// reasons
s[i] = static_cast<unsigned short>(c);
else {
// A simple cast is not possible, so we need to use
// the full blown conversion.
std::vector<unsigned short> const utf16 =
ucs4_to_utf16(str.data(), str.size());
// Enable the compiler to do NRVO
s = QString::fromUtf16(&utf16[0], utf16.size());
break;
}
}
return s; return s;
} }
#endif #endif
@ -41,11 +55,25 @@ docstring const qstring_to_ucs4(QString const & qstr)
QVector<uint> const ucs4 = qstr.toUcs4(); QVector<uint> const ucs4 = qstr.toUcs4();
return docstring(ucs4.begin(), ucs4.end()); return docstring(ucs4.begin(), ucs4.end());
#else #else
// This does not properly convert surrogate pairs
int const ls = qstr.size(); int const ls = qstr.size();
docstring ucs4; docstring ucs4;
for (int i = 0; i < ls; ++i) for (int i = 0; i < ls; ++i) {
ucs4 += qchar_to_ucs4(qstr[i].unicode()); char_type const c = static_cast<char_type>(qstr[i].unicode());
if (is_utf16(c))
// Use a simple cast in the common case for speed
// reasons
ucs4 += c;
else {
// A simple cast is not possible, so we need to use
// the full blown conversion.
std::vector<char_type> const v = utf16_to_ucs4(
reinterpret_cast<unsigned short const *>(qstr.utf16()),
qstr.size());
// Enable the compiler to do NRVO
ucs4 = docstring(v.begin(), v.end());
break;
}
}
return ucs4; return ucs4;
#endif #endif
} }

View File

@ -76,10 +76,6 @@ inline char_type const qchar_to_ucs4(QChar const & qchar)
*/ */
inline QChar const ucs4_to_qchar(char_type const ucs4) inline QChar const ucs4_to_qchar(char_type const ucs4)
{ {
// FIXME: The following cast is not a real conversion but it work
// for the ucs2 subrange of unicode. Instead of an assertion we should
// return some special characters that indicates that its display is
// not supported.
BOOST_ASSERT(is_utf16(ucs4)); BOOST_ASSERT(is_utf16(ucs4));
return QChar(static_cast<unsigned short>(ucs4)); return QChar(static_cast<unsigned short>(ucs4));
} }