From 657bd51bf20b292a3af22954155c02ae6a0da98f Mon Sep 17 00:00:00 2001 From: invertego Date: Mon, 15 Apr 2024 14:25:43 -0700 Subject: osd/strconv.cpp: Handle UTF-8 Windows code page internally in osd_uchar_from_osdchar. (#12131) --- src/osd/strconv.cpp | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/osd/strconv.cpp b/src/osd/strconv.cpp index 737cb9fc1dc..83fb8eaecae 100644 --- a/src/osd/strconv.cpp +++ b/src/osd/strconv.cpp @@ -5,15 +5,19 @@ // strconv.cpp - Win32 string conversion // //============================================================ -#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) -#include -#endif + +#include "strconv.h" + +#include "unicode.h" + #include #include -// MAMEOS headers -#include "strconv.h" -#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) + +#if defined(_WIN32) + +#include + namespace osd::text { @@ -254,20 +258,22 @@ std::string from_wstring(const WCHAR *s) int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count) { - // FIXME: Does not handle charsets that use variable lengths encodings such - // as example GB18030 or UTF-8. - // FIXME: Assumes all characters can be converted into a single wchar_t - // which may not always be the case such as with surrogate pairs. - - WCHAR wch; + // handle UTF-8 internally + if (GetACP() == CP_UTF8) + return uchar_from_utf8(uchar, osdchar, count); + + // FIXME: This makes multiple bad assumptions: + // * Assumes any character can be converted to a single wchar_t. + // * Assumes characters are either one byte or maximum number of bytes. + // * Doesn't handle nominal single-byte encodings with combining characters. CPINFO cp; - if (!GetCPInfo(CP_ACP, &cp)) goto error; // The multibyte char can't be bigger than the max character size count = std::min(count, size_t(IsDBCSLeadByte(*osdchar) ? cp.MaxCharSize : 1)); + WCHAR wch; if (MultiByteToWideChar(CP_ACP, 0, osdchar, static_cast(count), &wch, 1) == 0) goto error; @@ -280,23 +286,27 @@ error: } -#else -#include "unicode.h" +#else // _WIN32 + //============================================================ // osd_uchar_from_osdchar //============================================================ int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count) { + // FIXME: mbstowcs depends on global state wchar_t wch; - count = mbstowcs(&wch, (char *)osdchar, 1); - if (count != -1) + if (count != size_t(-1)) + { *uchar = wch; + return int(count); + } else + { *uchar = 0; - - return count; + return -1; + } } -#endif +#endif // _WIN32 -- cgit v1.2.3