@ -1094,8 +1094,33 @@ 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 < = IM_UNICODE_CODEPOINT_MAX )
InputQueueCharacters . push_back ( ( ImWchar ) c ) ;
InputQueueCharacters . push_back ( c > 0 & & c < = IM_UNICODE_CODEPOINT_MAX ? ( ImWchar ) c : IM_UNICODE_CODEPOINT_INVALID ) ;
}
// UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so
// we should save the high surrogate.
void ImGuiIO : : AddInputCharacterUTF16 ( ImWchar16 c )
{
if ( ( c & 0xFC00 ) = = 0xD800 ) // High surrogate, must save
{
if ( InputQueueSurrogate ! = 0 )
InputQueueCharacters . push_back ( 0xFFFD ) ;
InputQueueSurrogate = c ;
return ;
}
ImWchar cp = c ;
if ( InputQueueSurrogate ! = 0 )
{
if ( ( c & 0xFC00 ) ! = 0xDC00 ) // Invalid low surrogate
InputQueueCharacters . push_back ( IM_UNICODE_CODEPOINT_INVALID ) ;
else if ( IM_UNICODE_CODEPOINT_MAX = = ( 0xFFFF ) ) // Codepoint will not fit in ImWchar (extra parenthesis around 0xFFFF somehow fixes -Wunreachable-code with Clang)
cp = IM_UNICODE_CODEPOINT_INVALID ;
else
cp = ( ImWchar ) ( ( ( InputQueueSurrogate - 0xD800 ) < < 10 ) + ( c - 0xDC00 ) + 0x10000 ) ;
InputQueueSurrogate = 0 ;
}
InputQueueCharacters . push_back ( cp ) ;
}
void ImGuiIO : : AddInputCharactersUTF8 ( const char * utf8_chars )
@ -1104,7 +1129,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
{
unsigned int c = 0 ;
utf8_chars + = ImTextCharFromUtf8 ( & c , utf8_chars , NULL ) ;
if ( c > 0 & & c < = IM_UNICODE_CODEPOINT_MAX )
if ( c > 0 )
InputQueueCharacters . push_back ( ( ImWchar ) c ) ;
}
}
@ -1484,17 +1509,30 @@ ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
// Default file functions
# ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
# if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# ifndef __MINGW32__
# include <Windows.h>
# else
# include <windows.h>
# endif
# endif
ImFileHandle ImFileOpen ( const char * filename , const char * mode )
{
# if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
const int filename_wsize = ImTextCountCharsFromUtf8 ( filename , NULL ) + 1 ;
const int mode_wsize = ImTextCountCharsFromUtf8 ( mode , NULL ) + 1 ;
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
const int filename_wsize = : : MultiByteToWideChar ( CP_UTF8 , 0 , filename , - 1 , NULL , 0 ) ;
const int mode_wsize = : : MultiByteToWideChar ( CP_UTF8 , 0 , mode , - 1 , NULL , 0 ) ;
ImVector < ImWchar > buf ;
buf . resize ( filename_wsize + mode_wsize ) ;
ImTextStrFromUtf8 ( & buf [ 0 ] , filename_wsize , filename , NULL ) ;
ImTextStrFromUtf8 ( & buf [ filename_wsize ] , mode_wsize , mode , NULL ) ;
return _wfopen ( ( wchar_t * ) & buf [ 0 ] , ( wchar_t * ) & buf [ filename_wsize ] ) ;
: : MultiByteToWideChar ( CP_UTF8 , 0 , filename , - 1 , ( wchar_t * ) & buf [ 0 ] , filename_wsize ) ;
: : MultiByteToWideChar ( CP_UTF8 , 0 , mode , - 1 , ( wchar_t * ) & buf [ filename_wsize ] , mode_wsize ) ;
return _wfopen ( ( const wchar_t * ) & buf [ 0 ] , ( const wchar_t * ) & buf [ filename_wsize ] ) ;
# else
return fopen ( filename , mode ) ;
# endif
@ -1606,6 +1644,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 codepoint does not fit in ImWchar, use replacement character U+FFFD instead
if ( c > IM_UNICODE_CODEPOINT_MAX ) c = IM_UNICODE_CODEPOINT_INVALID ;
* out_char = c ;
return 4 ;
}
@ -1623,8 +1663,7 @@ int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const cha
in_text + = ImTextCharFromUtf8 ( & c , in_text , in_text_end ) ;
if ( c = = 0 )
break ;
if ( c < = IM_UNICODE_CODEPOINT_MAX ) // FIXME: Losing characters that don't fit in 2 bytes
* buf_out + + = ( ImWchar ) c ;
* buf_out + + = ( ImWchar ) c ;
}
* buf_out = 0 ;
if ( in_text_remaining )
@ -1641,8 +1680,7 @@ int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end)
in_text + = ImTextCharFromUtf8 ( & c , in_text , in_text_end ) ;
if ( c = = 0 )
break ;
if ( c < = IM_UNICODE_CODEPOINT_MAX )
char_count + + ;
char_count + + ;
}
return char_count ;
}
@ -1662,11 +1700,15 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
buf [ 1 ] = ( char ) ( 0x80 + ( c & 0x3f ) ) ;
return 2 ;
}
if ( c >= 0xdc00 & & c < 0xe 000)
if ( c < 0x10 000)
{
return 0 ;
if ( buf_size < 3 ) return 0 ;
buf [ 0 ] = ( char ) ( 0xe0 + ( c > > 12 ) ) ;
buf [ 1 ] = ( char ) ( 0x80 + ( ( c > > 6 ) & 0x3f ) ) ;
buf [ 2 ] = ( char ) ( 0x80 + ( ( c ) & 0x3f ) ) ;
return 3 ;
}
if ( c > = 0xd800 & & c < 0xdc00 )
if ( c <= 0x10FFFF )
{
if ( buf_size < 4 ) return 0 ;
buf [ 0 ] = ( char ) ( 0xf0 + ( c > > 18 ) ) ;
@ -1675,14 +1717,8 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
buf [ 3 ] = ( char ) ( 0x80 + ( ( c ) & 0x3f ) ) ;
return 4 ;
}
//else if (c < 0x10000)
{
if ( buf_size < 3 ) return 0 ;
buf [ 0 ] = ( char ) ( 0xe0 + ( c > > 12 ) ) ;
buf [ 1 ] = ( char ) ( 0x80 + ( ( c > > 6 ) & 0x3f ) ) ;
buf [ 2 ] = ( char ) ( 0x80 + ( ( c ) & 0x3f ) ) ;
return 3 ;
}
// Invalid code point, the max unicode is 0x10FFFF
return 0 ;
}
// Not optimal but we very rarely use this function.
@ -1696,8 +1732,8 @@ static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
{
if ( c < 0x80 ) return 1 ;
if ( c < 0x800 ) return 2 ;
if ( c >= 0xdc00 & & c < 0xe000 ) return 0 ;
if ( c >= 0xd800 & & c < 0xdc00 ) return 4 ;
if ( c < 0x10000 ) return 3 ;
if ( c <= 0x10FFFF ) return 4 ;
return 3 ;
}
@ -9748,6 +9784,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
# else
# include <windows.h>
# endif
# include <stringapiset.h>
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) // UWP doesn't have Win32 functions
# define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
# define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
@ -9760,6 +9797,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
# ifdef _MSC_VER
# pragma comment(lib, "user32")
# pragma comment(lib, "kernel32")
# endif
// Win32 clipboard implementation
@ -9775,11 +9813,11 @@ static const char* GetClipboardTextFn_DefaultImpl(void*)
: : CloseClipboard ( ) ;
return NULL ;
}
if ( ImWchar * wbuf_global = ( ImWchar * ) : : GlobalLock ( wbuf_handle ) )
if ( const WCHAR * wbuf_global = ( const WCHAR * ) : : GlobalLock ( wbuf_handle ) )
{
int buf_len = ImTextCountUtf8BytesFromStr ( wbuf_global , NULL ) + 1 ;
int buf_len = : : WideCharToMultiByte ( CP_UTF8 , 0 , wbuf_global , - 1 , NULL , 0 , NULL , NULL ) ;
buf_local . resize ( buf_len ) ;
ImTextStrToUtf8 ( buf_local . Data , buf_len , wbuf_global , NULL ) ;
: : WideCharToMultiByte ( CP_UTF8 , 0 , wbuf_global , - 1 , buf_local . Data , buf_len , NULL , NULL ) ;
}
: : GlobalUnlock ( wbuf_handle ) ;
: : CloseClipboard ( ) ;
@ -9790,15 +9828,15 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
{
if ( ! : : OpenClipboard ( NULL ) )
return ;
const int wbuf_length = ImTextCountCharsFromUtf8 ( text , NULL ) + 1 ;
HGLOBAL wbuf_handle = : : GlobalAlloc ( GMEM_MOVEABLE , ( SIZE_T ) wbuf_length * sizeof ( ImWchar ) ) ;
const int wbuf_length = : : MultiByteToWideChar ( CP_UTF8 , 0 , text , - 1 , NULL , 0 ) ;
HGLOBAL wbuf_handle = : : GlobalAlloc ( GMEM_MOVEABLE , ( SIZE_T ) wbuf_length * sizeof ( WCHAR ) ) ;
if ( wbuf_handle = = NULL )
{
: : CloseClipboard ( ) ;
return ;
}
ImWchar* wbuf_global = ( ImWchar * ) : : GlobalLock ( wbuf_handle ) ;
ImTextStrFromUtf8 ( wbuf_global , wbuf_length , text , NULL ) ;
WCHAR* wbuf_global = ( WCHAR * ) : : GlobalLock ( wbuf_handle ) ;
: : MultiByteToWideChar ( CP_UTF8 , 0 , text , - 1 , wbuf_global , wbuf_length ) ;
: : GlobalUnlock ( wbuf_handle ) ;
: : EmptyClipboard ( ) ;
if ( : : SetClipboardData ( CF_UNICODETEXT , wbuf_handle ) = = NULL )