Несоответствие кодовой точки между Java и C
Итак, у меня есть некоторые проблемы со следующим символом –
в порту Игуи в Котлин
Покопавшись весь день в кодировках и кодировках, я пришел к единственной надежде: полагаться на кодовые точки Юникода.
Этот символ на JVM
"–"[0].toInt() // same as codePointAt()
возвращает кодовую точку u2013
На C я не уверен, но так как это делается:
const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const
{
if (c >= IndexLookup.Size)
return FallbackGlyph;
const ImWchar i = IndexLookup.Data[c];
if (i == (ImWchar)-1)
return FallbackGlyph;
return &Glyphs.Data[i];
}
куда
typedef unsigned short ImWchar
а также
ImVector<ImWchar> IndexLookup; // Sparse. Index glyphs by Unicode code-point.
Итак, делая это
char* a = "–";
int b = a[0];
возвращает кодовую точку u0096
Насколько я читаю, это выглядит как закончилось 127
(0x7F
) мы находимся на территории "Расширенной Ascii", что плохо, потому что кажется, что есть разные версии / интерпретации этого.
Например, эта таблица кодирования не соответствует моей кодовой точке, но кодировка Cp1252 соответствует, поэтому я склонен думать, что это то, что на самом деле используется на C.
В таблице внизу только что упомянутой ссылки вы можете увидеть, что 150
(десятичное число из правого столбца с указанным номером) действительно соответствует 2013
(hex, я нахожу это немного бессвязным, но в любом случае).
Чтобы решить эту проблему, я попытался преобразовать мой String
s на Kotlin с той же кодировкой (игнорируя на данный момент, конечно, это зависит от платформы), так что для каждого c: Char
"$c".toByteArray(Charset.forName("Cp1252"))[0].toUnsignedInt
Это работает, но нарушает рендеринг для иностранных шрифтов, таких как китайский, японский и т. Д.
Итак, мой вопрос: почему разница между u2013
на JVM и u0096
на C?
Какой правильный способ справиться с этим?
1 ответ
В тот момент, когда я решил эту проблему в Windows, я вставил эту функцию перед извлечением кодовой точки char. Это в основном переназначает все те символы, которые отличаются от ISO-8859-1. Вы можете видеть их в этой таблице, они все с этой светло-серой рамкой.
internal fun Char.remapCodepointIfProblematic(): Int {
val i = toInt()
return when (Platform.get()) {
/* https://en.wikipedia.org/wiki/Windows-1252#Character_set
* manually remap the difference from ISO-8859-1 */
Platform.WINDOWS -> when (i) {
// 8_128
0x20AC -> 128 // €
0x201A -> 130 // ‚
0x0192 -> 131 // ƒ
0x201E -> 132 // „
0x2026 -> 133 // …
0x2020 -> 134 // †
0x2021 -> 135 // ‡
0x02C6 -> 136 // ˆ
0x2030 -> 137 // ‰
0x0160 -> 138 // Š
0x2039 -> 139 // ‹
0x0152 -> 140 // Œ
0x017D -> 142 // Ž
// 9_144
0x2018 -> 145 // ‘
0x2019 -> 146 // ’
0x201C -> 147 // “
0x201D -> 148 // ”
0x2022 -> 149 // •
0x2013 -> 150 // –
0x2014 -> 151 // —
0x02DC -> 152 // ˜
0x2122 -> 153 // ™
0x0161 -> 154 // š
0x203A -> 155 // ›
0x0153 -> 156 // œ
0x017E -> 158 // ž
0x0178 -> 159 // Ÿ
else -> i
}
else -> i // TODO
}
}