Skip to content

Commit e27c4da

Browse files
committed
Proper UTF-8 <--> current system codepage conversion
1 parent c4d4dd1 commit e27c4da

File tree

4 files changed

+35
-18
lines changed

4 files changed

+35
-18
lines changed

src/xrCore/Text/MbHelpers.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "stdafx.h"
22
#include "MbHelpers.h"
3+
#include <codecvt>
4+
5+
// XXX: use c++11 functions and kill that DUMP_CONVERSION!!!11
36

47
#define BITS1_MASK 0x80 // 10000000b
58
#define BITS2_MASK 0xC0 // 11000000b
@@ -127,3 +130,21 @@ u16 mbhMulti2Wide(wchar_t* WideStr, wchar_t* WidePos, u16 WideStrSize, const cha
127130
WideStr[0] = dpos;
128131
return dpos;
129132
}
133+
134+
xr_string StringFromUTF8(const char* in, const std::locale& locale /*= std::locale("")*/)
135+
{
136+
using wcvt = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
137+
auto wstr = wcvt{}.from_bytes(in);
138+
xr_string result(wstr.size(), '\0');
139+
std::use_facet<std::ctype<wchar_t>>(locale).narrow(wstr.data(), wstr.data() + wstr.size(), '?', &result[0]);
140+
return result;
141+
}
142+
143+
xr_string StringToUTF8(const char* in, const std::locale& locale /*= std::locale("")*/)
144+
{
145+
using wcvt = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
146+
std::wstring wstr(xr_strlen(in), L'\0');
147+
std::use_facet<std::ctype<wchar_t>>(locale).widen(in, in + xr_strlen(in), &wstr[0]);
148+
std::string result = wcvt{}.to_bytes(wstr.data(), wstr.data() + wstr.size());
149+
return result.data();
150+
}

src/xrCore/Text/MbHelpers.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#pragma once
22
#include "xrCore/xrCore.h"
33

4+
// XXX: rename this file to StringConversion.hpp
5+
// XXX: use c++11 functions
6+
47
#define MAX_MB_CHARS 4096
58

69
XRCORE_API u16 mbhMulti2Wide(wchar_t* WideStr, wchar_t* WidePos, u16 WideStrSize, const char* MultiStr);
@@ -27,3 +30,6 @@ IC bool IsAlphaCharacter(wchar_t wc)
2730
((wc >= 0x0061) && (wc <= 0x007A)) || ((wc >= 0xFF10) && (wc <= 0xFF19)) ||
2831
((wc >= 0xFF21) && (wc <= 0xFF3A)) || ((wc >= 0xFF41) && (wc <= 0xFF5A)));
2932
}
33+
34+
XRCORE_API xr_string StringFromUTF8(const char* string, const std::locale& locale = std::locale(""));
35+
XRCORE_API xr_string StringToUTF8(const char* string, const std::locale& locale = std::locale(""));

src/xrEngine/edit_actions.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "edit_actions.h"
1010
#include "line_edit_control.h"
1111
#include "xr_input.h"
12-
#include <codecvt>
12+
#include "xrCore/Text/MbHelpers.h"
1313

1414
namespace text_editor
1515
{
@@ -55,17 +55,6 @@ void type_pair::init(int dik, char c, char c_shift, bool b_translate)
5555
m_char_shift = c_shift;
5656
}
5757

58-
xr_string utf8_to_string(const char* utf8str, const std::locale& loc)
59-
{
60-
// UTF-8 to wstring
61-
std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;
62-
std::wstring wstr = wconv.from_bytes(utf8str);
63-
// wstring to string
64-
std::vector<char> buf(wstr.size());
65-
std::use_facet<std::ctype<wchar_t>>(loc).narrow(wstr.data(), wstr.data() + wstr.size(), '?', buf.data());
66-
return xr_string(buf.data(), buf.size());
67-
}
68-
6958
void type_pair::on_key_press(line_edit_control* const control)
7059
{
7160
char c = 0;
@@ -82,7 +71,7 @@ void type_pair::on_key_press(line_edit_control* const control)
8271
case SDL_TEXTINPUT:
8372
{
8473
const std::locale locale("");
85-
auto str = utf8_to_string(event.text.text, locale);
74+
auto str = StringFromUTF8(event.text.text, locale);
8675

8776
if (std::isalpha(str[0], locale) || str[0] == char(-1)) // "я" = -1
8877
{

src/xrEngine/xr_input.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "Include/editor/ide.hpp"
77
#include "GameFont.h"
88
#include "PerformanceAlert.hpp"
9+
#include "xrCore/Text/MbHelpers.h"
910

1011
#ifndef _EDITOR
1112
#include "xr_input_xinput.h"
@@ -196,14 +197,14 @@ pcstr KeyToMouseButtonName(const int dik)
196197

197198
bool CInput::get_dik_name(int dik, LPSTR dest_str, int dest_sz)
198199
{
199-
pcstr keyname;
200-
200+
xr_string keyname;
201+
201202
if (dik < SDL_NUM_SCANCODES)
202-
keyname = SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)dik));
203+
keyname = StringFromUTF8(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)dik)));
203204
else
204205
keyname = KeyToMouseButtonName(dik);
205206

206-
if (0 == strlen(keyname))
207+
if (keyname.empty())
207208
{
208209
if (dik == SDL_SCANCODE_UNKNOWN)
209210
keyname = "Unknown";
@@ -214,7 +215,7 @@ bool CInput::get_dik_name(int dik, LPSTR dest_str, int dest_sz)
214215
}
215216
}
216217

217-
xr_strcpy(dest_str, dest_sz, keyname);
218+
xr_strcpy(dest_str, dest_sz, keyname.c_str());
218219
return true;
219220
}
220221

0 commit comments

Comments
 (0)