Получить кодовые точки Unicode> U+FFFF из QChar

У меня есть приложение, которое должно работать со всеми видами символов и в какой-то момент отображать информацию о них. Я использую Qt и присущую ему поддержку Юникода в QChar, QString и т. Д.

Теперь мне нужна кодовая точка QChar, чтобы искать некоторые данные в http://unicode.org/Public/UNIDATA/UnicodeData.txt, но метод QChar unicode() возвращает только ushort (unsigned short), который обычно это число от 0 до 65535 (или 0xFFFF). Есть символы с кодами> 0xFFFF, так как мне их получить? Есть ли какая-то хитрость, которую я пропускаю или в настоящее время она не поддерживается Qt/QChar?

3 ответа

Решение

Каждый QChar является значением UTF-16, а не полной кодовой точкой Unicode. Следовательно, символы не-BMP состоят из двух QChar суррогатные пары.

Решение, по-видимому, заключается в коде, который задокументирован, но не встречается в Интернете. Вы можете получить значение utf-8 в десятичной форме. Затем вы подаете заявку, чтобы определить, является ли один QChar достаточно большим. В этом случае это не так. Затем вам нужно создать два QChar's.

uint32_t cp = 155222; // a 4-byte Japanese character 
QString str;
if(Qchar::requiresSurrogate(cp))
{
    QChar charArray[2];
    charArray[0] = QChar::highSurrogate(cp);
    charArray[1] = QChar::lowSurrogate(cp);
    str =  QString(charArray, 2);
}

Результирующая строка QString будет содержать правильную информацию для отображения вашего дополнительного символа utf-8.

Символы Юникода за пределами U+FFFF в Qt

QChar сам поддерживает только символы Unicode до U+FFFF,

QString поддерживает символы Unicode за U+FFFF объединяя два QChar (то есть используя кодировку UTF-16). Тем не менее, API QString не очень вам помогает, если вам нужно обрабатывать символы за пределами U+FFFF, Как пример, экземпляр QString, который содержит один символ Unicode U+131F6 вернет размер 2, а не 1.

Я открыл QTBUG-18868 об этой проблеме еще в 2011 году, но после более чем трехлетнего (!) Обсуждения он был окончательно закрыт как "выходящий за рамки" без какого-либо решения.

Решение

Однако вы можете скачать и использовать эти классы-обёртки строк Unicode Qt, которые были прикреплены к отчёту об ошибке Qt. По лицензии LGPL.

Эта загрузка содержит классы обертки QUtfString, QUtfChar, QUtfRegExp а также QUtfStringList которые дополняют существующие классы Qt и позволяют вам делать такие вещи:

QUtfString str;
str.append(0x1307C);            // Some Unicode character beyond U+FFFF

Q_ASSERT(str.size() == 1);
Q_ASSERT(str[0] == 0x1307C);

str += 'a';

Q_ASSERT(str.size() == 2);
Q_ASSERT(str[1] == 'a');
Q_ASSERT(str.indexOf('a') == 1);

Для получения дополнительной информации о реализации, использовании и сложности времени выполнения см. Документацию по API, включенную в загрузку.

Другие вопросы по тегам