Skip to content

Commit 5698e2b

Browse files
committed
Fix Android text bug (no text displaying)
1 parent ffdf8de commit 5698e2b

File tree

4 files changed

+79
-80
lines changed

4 files changed

+79
-80
lines changed

src/game.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4175,7 +4175,9 @@ inline void Game::limitFps(FpsControl *fps_timings, f32 *dtime)
41754175
fps_timings->last_time = time;
41764176
}
41774177

4178-
4178+
// Note: This will free (using delete[])! \p msg. If you want to use it later,
4179+
// pass a copy of it to this function
4180+
// Note: \p msg must be allocated using new (not malloc())
41794181
void Game::showOverlayMessage(const wchar_t *msg, float dtime,
41804182
int percent, bool draw_clouds)
41814183
{

src/gettext.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,31 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2323
#include "config.h" // for USE_GETTEXT
2424

2525
#if USE_GETTEXT
26-
#include <libintl.h>
26+
#include <libintl.h>
2727
#else
28-
#define gettext(String) String
28+
#define gettext(String) String
2929
#endif
3030

3131
#define _(String) gettext(String)
32-
#define gettext_noop(String) String
33-
#define N_(String) gettext_noop (String)
32+
#define gettext_noop(String) (String)
33+
#define N_(String) gettext_noop((String))
3434

3535
#ifdef _MSC_VER
36-
void init_gettext(const char *path, const std::string &configured_language, int argc, char** argv);
36+
void init_gettext(const char *path, const std::string &configured_language,
37+
int argc, char** argv);
3738
#else
3839
void init_gettext(const char *path, const std::string &configured_language);
3940
#endif
4041

41-
extern const wchar_t *narrow_to_wide_c(const char *mbs);
42-
extern std::wstring narrow_to_wide(const std::string &mbs);
42+
extern wchar_t *narrow_to_wide_c(const char *str);
4343

4444
// You must free the returned string!
45+
// The returned string is allocated using new
4546
inline const wchar_t *wgettext(const char *str)
4647
{
4748
return narrow_to_wide_c(gettext(str));
4849
}
4950

50-
// Gettext under MSVC needs this strange way. Just don't ask...
5151
inline std::wstring wstrgettext(const std::string &text)
5252
{
5353
const wchar_t *tmp = wgettext(text.c_str());

src/util/string.cpp

+63-68
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,45 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2222
#include "numeric.h"
2323
#include "log.h"
2424

25+
#include "sha1.h"
2526
#include "base64.h"
2627
#include "hex.h"
27-
#include "sha1.h"
2828
#include "../porting.h"
2929

3030
#include <algorithm>
3131
#include <sstream>
3232
#include <iomanip>
3333
#include <map>
3434

35+
static bool parseHexColorString(const std::string &value, video::SColor &color);
36+
static bool parseNamedColorString(const std::string &value, video::SColor &color);
37+
38+
39+
// You must free the returned string!
40+
// The returned string is allocated using new
41+
wchar_t *narrow_to_wide_c(const char *str)
42+
{
43+
wchar_t* nstr = 0;
3544
#if defined(_WIN32)
36-
#include <windows.h> // MultiByteToWideChar
45+
int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) str, -1, 0, 0);
46+
if (nResult == 0) {
47+
errorstream<<"gettext: MultiByteToWideChar returned null"<<std::endl;
48+
} else {
49+
nstr = new wchar_t[nResult];
50+
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) str, -1, (WCHAR *) nstr, nResult);
51+
}
52+
#else
53+
size_t len = strlen(str);
54+
nstr = new wchar_t[len+1];
55+
56+
std::wstring intermediate = narrow_to_wide(str);
57+
memset(nstr, 0, (len + 1) * sizeof(wchar_t));
58+
memcpy(nstr, intermediate.c_str(), len * sizeof(wchar_t));
3759
#endif
3860

39-
static bool parseHexColorString(const std::string &value, video::SColor &color);
40-
static bool parseNamedColorString(const std::string &value, video::SColor &color);
61+
return nstr;
62+
}
63+
4164

4265
#ifdef __ANDROID__
4366

@@ -63,84 +86,55 @@ int wctomb(char *s, wchar_t wc)
6386

6487
int mbtowc(wchar_t *pwc, const char *s, size_t n)
6588
{
66-
if (s == NULL || *s == '\0')
67-
return -1;
89+
std::wstring intermediate = narrow_to_wide(s);
6890

69-
const wchar_t *tmp = narrow_to_wide_c(s);
70-
bool success = tmp[0] != '\0';
91+
if (intermediate.length() > 0) {
92+
*pwc = intermediate[0];
93+
return 1;
94+
}
95+
else {
96+
return -1;
97+
}
98+
}
7199

72-
if (success)
73-
*pwc = tmp[0];
100+
std::wstring narrow_to_wide(const std::string &mbs) {
101+
size_t wcl = mbs.size();
74102

75-
delete tmp;
103+
std::wstring retval = L"";
76104

77-
return success ? 1 : -1;
78-
}
105+
for (unsigned int i = 0; i < wcl; i++) {
106+
if (((unsigned char) mbs[i] >31) &&
107+
((unsigned char) mbs[i] < 127)) {
79108

80-
// You must free the returned string!
81-
const wchar_t *narrow_to_wide_c(const char *mbs)
82-
{
83-
size_t mbl = strlen(mbs);
84-
wchar_t *wcs = new wchar_t[mbl + 1];
85-
86-
size_t i, dest_i = 0;
87-
for (i = 0; i < mbl; i++) {
88-
if (((unsigned char) mbs[i] > 31) &&
89-
((unsigned char) mbs[i] < 127)) {
90-
wcs[dest_i++] = wide_chars[(unsigned char) mbs[i] - 32];
109+
retval += wide_chars[(unsigned char) mbs[i] -32];
91110
}
92111
//handle newline
93112
else if (mbs[i] == '\n') {
94-
wcs[dest_i++] = L'\n';
113+
retval += L'\n';
95114
}
96115
}
97-
wcs[dest_i] = '\0';
98-
99-
return wcs;
100-
}
101116

102-
#else
103-
104-
// You must free the returned string!
105-
const wchar_t *narrow_to_wide_c(const char *mbs)
106-
{
107-
wchar_t *wcs = NULL;
108-
#if defined(_WIN32)
109-
int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, 0, 0);
110-
if (nResult == 0) {
111-
errorstream << "gettext: MultiByteToWideChar returned null" << std::endl;
112-
} else {
113-
wcs = new wchar_t[nResult];
114-
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, nResult);
115-
}
116-
#else
117-
size_t wcl = mbstowcs(NULL, mbs, 0);
118-
if (wcl == (size_t) -1)
119-
return NULL;
120-
wcs = new wchar_t[wcl + 1];
121-
size_t l = mbstowcs(wcs, mbs, wcl);
122-
assert(l != (size_t) -1); // Should never happen if the last call worked
123-
wcs[l] = '\0';
124-
#endif
125-
126-
return wcs;
117+
return retval;
127118
}
128119

129-
#endif
120+
#else // not Android
130121

131-
std::wstring narrow_to_wide(const std::string& mbs)
122+
std::wstring narrow_to_wide(const std::string &mbs)
132123
{
133124
size_t wcl = mbs.size();
134125
Buffer<wchar_t> wcs(wcl + 1);
135-
size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
136-
if (l == (size_t)(-1))
126+
size_t len = mbstowcs(*wcs, mbs.c_str(), wcl);
127+
if (len == (size_t)(-1))
137128
return L"<invalid multibyte string>";
138-
wcs[l] = 0;
129+
wcs[len] = 0;
139130
return *wcs;
140131
}
141132

133+
#endif
134+
142135
#ifdef __ANDROID__
143-
std::string wide_to_narrow(const std::wstring& wcs) {
136+
137+
std::string wide_to_narrow(const std::wstring &wcs) {
144138
size_t mbl = wcs.size()*4;
145139

146140
std::string retval = "";
@@ -165,17 +159,18 @@ std::string wide_to_narrow(const std::wstring& wcs) {
165159

166160
return retval;
167161
}
168-
#else
169-
std::string wide_to_narrow(const std::wstring& wcs)
162+
163+
#else // not Android
164+
165+
std::string wide_to_narrow(const std::wstring &wcs)
170166
{
171-
size_t mbl = wcs.size()*4;
167+
size_t mbl = wcs.size() * 4;
172168
SharedBuffer<char> mbs(mbl+1);
173-
size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
174-
if(l == (size_t)(-1)) {
169+
size_t len = wcstombs(*mbs, wcs.c_str(), mbl);
170+
if (len == (size_t)(-1))
175171
return "Character conversion failed!";
176-
}
177172
else
178-
mbs[l] = 0;
173+
mbs[len] = 0;
179174
return *mbs;
180175
}
181176

@@ -188,7 +183,7 @@ std::string wide_to_narrow(const std::wstring& wcs)
188183
// compatibility with password-less players).
189184
std::string translatePassword(std::string playername, std::wstring password)
190185
{
191-
if(password.length() == 0)
186+
if (password.length() == 0)
192187
return "";
193188

194189
std::string slt = playername + wide_to_narrow(password);

src/util/string.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ struct FlagDesc {
3636
u32 flag;
3737
};
3838

39+
3940
// You must free the returned string!
40-
const wchar_t *narrow_to_wide_c(const char *mbs);
41+
// The returned string is allocated using new
42+
wchar_t *narrow_to_wide_c(const char *str);
4143

42-
std::wstring narrow_to_wide(const std::string& mbs);
43-
std::string wide_to_narrow(const std::wstring& wcs);
44+
std::wstring narrow_to_wide(const std::string &mbs);
45+
std::string wide_to_narrow(const std::wstring &wcs);
4446
std::string translatePassword(std::string playername, std::wstring password);
4547
std::string urlencode(std::string str);
4648
std::string urldecode(std::string str);

0 commit comments

Comments
 (0)