Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions Builder/External/SDL2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,10 @@ else()
endif()
set(SDL_TEST_ENABLED_BY_DEFAULT OFF)

# Apple環境の場合、システムのiconvを使用する設定
if(APPLE)
set(SDL_SYSTEM_ICONV ON CACHE BOOL "Use iconv() from system-installed libraries")
set(SDL_LIBICONV OFF CACHE BOOL "Prefer iconv() from libiconv, if available, over libc version")
endif()

include(functions/FetchContent_ExcludeFromAll_backport)
include(FetchContent)
FetchContent_Declare(SDL2
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.8/SDL2-2.32.8.tar.gz
URL_HASH SHA256=0ca83e9c9b31e18288c7ec811108e58bac1f1bb5ec6577ad386830eac51c787e
)
FetchContent_MakeAvailable_ExcludeFromAll(SDL2)
FetchContent_MakeAvailable_ExcludeFromAll(SDL2)
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ set(SRCS
)

if(APPLE)
list(APPEND SRCS Source/UI/pathresolver_mac.mm)
list(APPEND SRCS
Source/UI/converter_mac.mm
Source/UI/pathresolver_mac.mm
)
endif()

set(BIN_TARGET "xm8")
Expand Down Expand Up @@ -232,6 +235,14 @@ if(BUILD_TESTING)
add_test(NAME pathresolver_test COMMAND pathresolver_test)

if(APPLE)
add_executable(converter_mac_test
Tests/converter_mac_test.mm
Source/UI/converter_mac.mm
)
target_include_directories(converter_mac_test PRIVATE Source/UI)
target_link_libraries(converter_mac_test PRIVATE "-framework Foundation")
add_test(NAME converter_mac_test COMMAND converter_mac_test)

add_executable(pathresolver_mac_test
Tests/pathresolver_mac_test.mm
Source/UI/pathresolver.cpp
Expand Down
41 changes: 14 additions & 27 deletions Source/UI/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include "common.h"
#include "converter.h"

#if defined(__APPLE__)
#include "converter_mac.h"
#endif
#if defined(__ANDROID__)
#include "xm8jni.h"
#endif
Expand Down Expand Up @@ -100,29 +103,7 @@ void Converter::Deinit()
//
int Converter::Utf8macToUtf8(const char *src, char *dst, size_t len)
{
SDL_iconv_t conv; // conversion descriptor
char buf[_MAX_PATH];
const char *src_buf = buf;
char *dst_buf = dst;
size_t src_len = strlen(src);
size_t dst_len = len - 1;
int ret = 0;
strncpy(buf, src, sizeof(buf));
if ((conv = SDL_iconv_open("UTF-8", "UTF-8-MAC")) == (SDL_iconv_t) - 1) {
fprintf(stderr, "error: %s: %s\n", __FUNCTION__, SDL_GetError());
return -1;
}
if (SDL_iconv(conv, &src_buf, &src_len, &dst_buf, &dst_len) == (size_t) - 1) {
fprintf(stderr, "error: %s: %s\n", __FUNCTION__, SDL_GetError());
ret = -1;
}
*dst_buf = '\0';
if (SDL_iconv_close(conv) == -1) {
fprintf(stderr, "error: %s: %s\n", __FUNCTION__, SDL_GetError());
ret = -1;
}

return ret;
return NormalizeUtf8ToNfcMac(src, dst, len);
}
#endif

Expand Down Expand Up @@ -244,10 +225,16 @@ void Converter::SjisToUtf(const char *sjis, char *utf)
//
void Converter::UtfToSjis(const char *utf, char *sjis)
{
#if defined(__APPLE__)
char* utf8_nfc = (char*)SDL_malloc(strlen(utf) * 3 + 1);
Utf8macToUtf8(utf, utf8_nfc, strlen(utf) + 1);
UtfNfcToSjis(utf8_nfc, sjis);
#if defined(__APPLE__)
size_t utf8_nfc_len = strlen(utf) * 3 + 1;
char* utf8_nfc = (char*)SDL_malloc(utf8_nfc_len);
if (utf8_nfc != NULL && Utf8macToUtf8(utf, utf8_nfc,
utf8_nfc_len) == 0) {
UtfNfcToSjis(utf8_nfc, sjis);
}
else {
UtfNfcToSjis(utf, sjis);
}
SDL_free(utf8_nfc);
#elif defined(__ANDROID__)
char* utf8_nfc = (char*)SDL_malloc(strlen(utf) * 3 + 1);
Expand Down
8 changes: 8 additions & 0 deletions Source/UI/converter_mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef CONVERTER_MAC_H
#define CONVERTER_MAC_H

#include <cstddef>

int NormalizeUtf8ToNfcMac(const char *src, char *dst, size_t capacity);

#endif // CONVERTER_MAC_H
38 changes: 38 additions & 0 deletions Source/UI/converter_mac.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#import <Foundation/Foundation.h>

#include <cstring>

#include "converter_mac.h"

int NormalizeUtf8ToNfcMac(const char *src, char *dst, size_t capacity)
{
if (src == nullptr || dst == nullptr || capacity == 0) {
return -1;
}

@autoreleasepool {
NSString *string = [NSString stringWithUTF8String:src];
if (string == nil) {
dst[0] = '\0';
return -1;
}

NSString *normalized =
[string precomposedStringWithCanonicalMapping];
const char *utf8 = [normalized UTF8String];
if (utf8 == nullptr) {
dst[0] = '\0';
return -1;
}

const size_t length = std::strlen(utf8);
if (length >= capacity) {
dst[0] = '\0';
return -1;
}

std::memcpy(dst, utf8, length + 1);
}

return 0;
}
57 changes: 57 additions & 0 deletions Tests/converter_mac_test.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#import <Foundation/Foundation.h>

#include <cstring>
#include <iostream>

#include "converter_mac.h"

namespace {

int failures = 0;

void Check(bool condition, const char *message)
{
if (!condition) {
std::cerr << "FAIL: " << message << '\n';
failures++;
}
}

}

int main()
{
@autoreleasepool {
char normalized[32];
Check(NormalizeUtf8ToNfcMac("ka", normalized,
sizeof(normalized)) == 0, "normalize ascii succeeds");
Check(std::strcmp(normalized, "ka") == 0,
"ascii remains unchanged");

const char *nfd = "\xe3\x81\x8b\xe3\x82\x99";
const char *nfc = "\xe3\x81\x8c";
Check(NormalizeUtf8ToNfcMac(nfd, normalized,
sizeof(normalized)) == 0, "normalize nfd succeeds");
Check(std::strcmp(normalized, nfc) == 0,
"nfd kana becomes nfc kana");

char too_small[3] = {'x', 'y', 'z'};
Check(NormalizeUtf8ToNfcMac(nfd, too_small,
sizeof(too_small)) == -1, "small buffer fails");
Check(too_small[0] == '\0',
"small buffer is cleared after failure");

Check(NormalizeUtf8ToNfcMac(nullptr, normalized,
sizeof(normalized)) == -1, "null source fails");
Check(NormalizeUtf8ToNfcMac("ka", nullptr,
sizeof(normalized)) == -1, "null destination fails");
Check(NormalizeUtf8ToNfcMac("ka", normalized, 0) == -1,
"zero capacity fails");

const char invalid[] = {static_cast<char>(0xff), '\0'};
Check(NormalizeUtf8ToNfcMac(invalid, normalized,
sizeof(normalized)) == -1, "invalid utf-8 fails");
}

return failures == 0 ? 0 : 1;
}
Loading