diff --git a/imgui.cpp b/imgui.cpp index 92e84da09c41..162d552722e5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1258,8 +1258,7 @@ ImGuiIO::ImGuiIO() // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message void ImGuiIO::AddInputCharacter(unsigned int c) { - if (c > 0 && c < (sizeof(ImWchar) == 2 ? 0x10000 : 0x110000)) - InputQueueCharacters.push_back((ImWchar)c); + InputQueueCharacters.push_back(c > 0 && c < IM_UNICODE_MAX_CODEPOINT ? (ImWchar)c : 0xFFFD); } // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so @@ -1268,22 +1267,22 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) { if ((c & 0xFC00) == 0xD800) // High surrogate, must save { - if (Surrogate != 0) + if (InputQueueSurrogate != 0) InputQueueCharacters.push_back(0xFFFD); - Surrogate = c; + InputQueueSurrogate = c; return; } ImWchar cp = c; - if (Surrogate != 0) + if (InputQueueSurrogate != 0) { if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate InputQueueCharacters.push_back(0xFFFD); - else if (sizeof(ImWchar) == 2) + else if (IM_UNICODE_MAX_CODEPOINT == 0x10000) // Codepoint will not fit in ImWchar cp = 0xFFFD; else - cp = ((ImWchar)(Surrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000; - Surrogate = 0; + cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000); + InputQueueSurrogate = 0; } InputQueueCharacters.push_back(cp); } @@ -1713,8 +1712,8 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* c += (*str++ & 0x3f); // utf-8 encodings of values used in surrogate pairs are invalid if ((c & 0xFFFFF800) == 0xD800) return 4; - // If ImWchar is 16bit, use replacement character U+FFFD instead - if (sizeof(ImWchar) == 2 && c >= 0x10000) c = 0xFFFD; + // If codepoint does not fit in ImWchar, use replacement character U+FFFD instead + if (c >= IM_UNICODE_MAX_CODEPOINT) c = 0xFFFD; *out_char = c; return 4; } diff --git a/imgui.h b/imgui.h index c2156cad00bc..3bb89b48b9e9 100644 --- a/imgui.h +++ b/imgui.h @@ -160,6 +160,8 @@ typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: f typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); +#define IM_UNICODE_MAX_CODEPOINT (sizeof(ImWchar) == 2 ? 0x10000 : 0x110000) + // Scalar data types typedef signed char ImS8; // 8-bit signed integer == char typedef unsigned char ImU8; // 8-bit unsigned integer @@ -1466,7 +1468,7 @@ struct ImGuiIO float KeysDownDurationPrev[512]; // Previous duration the key has been down float NavInputsDownDuration[ImGuiNavInput_COUNT]; float NavInputsDownDurationPrev[ImGuiNavInput_COUNT]; - ImWchar16 Surrogate; // For AddInputCharacterUTF16 + ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16 ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform back-end). Fill using AddInputCharacter() helper. IMGUI_API ImGuiIO(); @@ -2047,7 +2049,7 @@ struct ImFontGlyphRangesBuilder ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) ImFontGlyphRangesBuilder() { Clear(); } - inline void Clear() { int size_in_bytes = (sizeof(ImWchar) == 2 ? 0x10000 : 0x110000) / 8; UsedChars.resize(size_in_bytes / (int)sizeof(ImU32)); memset(UsedChars.Data, 0, (size_t)size_in_bytes); } + inline void Clear() { int size_in_bytes = IM_UNICODE_MAX_CODEPOINT / 8; UsedChars.resize(size_in_bytes / (int)sizeof(ImU32)); memset(UsedChars.Data, 0, (size_t)size_in_bytes); } inline bool GetBit(int n) const { int off = (n >> 5); ImU32 mask = 1u << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array inline void SetBit(int n) { int off = (n >> 5); ImU32 mask = 1u << (n & 31); UsedChars[off] |= mask; } // Set bit n in the array inline void AddChar(ImWchar c) { SetBit(c); } // Add character