From 8d7cd6a5262ae151e30fe6db18d04648ebe9d8d7 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 23 Sep 2018 19:26:09 +0200 Subject: Add: [OSX] Native natural sort implementation. --- source.list | 2 ++ src/os/macosx/string_osx.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++ src/os/macosx/string_osx.h | 19 +++++++++++++ src/string.cpp | 9 ++++++ src/strings.cpp | 5 ++++ 5 files changed, 101 insertions(+) create mode 100644 src/os/macosx/string_osx.cpp create mode 100644 src/os/macosx/string_osx.h diff --git a/source.list b/source.list index 7b31df91b..b89f7d736 100644 --- a/source.list +++ b/source.list @@ -413,6 +413,7 @@ music/qtmidi.h os/macosx/macos.h os/macosx/osx_stdafx.h os/macosx/splash.h +os/macosx/string_osx.h sound/cocoa_s.h video/cocoa/cocoa_keys.h video/cocoa/cocoa_v.h @@ -1167,6 +1168,7 @@ sound/null_s.cpp music/cocoa_m.cpp sound/cocoa_s.cpp os/macosx/splash.cpp + os/macosx/string_osx.cpp #end #end diff --git a/src/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp new file mode 100644 index 000000000..93c50722b --- /dev/null +++ b/src/os/macosx/string_osx.cpp @@ -0,0 +1,66 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file string_osx.cpp Functions related to localized text support on OSX. */ + +#include "../../stdafx.h" +#include "string_osx.h" +#include "macos.h" + +#include + + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +static CFLocaleRef _osx_locale = NULL; + +/** Store current language locale as a CoreFounation locale. */ +void MacOSSetCurrentLocaleName(const char *iso_code) +{ + if (!MacOSVersionIsAtLeast(10, 5, 0)) return; + + if (_osx_locale != NULL) CFRelease(_osx_locale); + + CFStringRef iso = CFStringCreateWithCString(kCFAllocatorNull, iso_code, kCFStringEncodingUTF8); + _osx_locale = CFLocaleCreate(kCFAllocatorDefault, iso); + CFRelease(iso); +} + +/** + * Compares two strings using case insensitive natural sort. + * + * @param s1 First string to compare. + * @param s2 Second string to compare. + * @return 1 if s1 < s2, 2 if s1 == s2, 3 if s1 > s2, or 0 if not supported by the OS. + */ +int MacOSStringCompare(const char *s1, const char *s2) +{ + static bool supported = MacOSVersionIsAtLeast(10, 5, 0); + if (!supported) return 0; + + CFStringCompareFlags flags = kCFCompareCaseInsensitive | kCFCompareNumerically | kCFCompareLocalized | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; + + CFStringRef cf1 = CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8); + CFStringRef cf2 = CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8); + + CFComparisonResult res = CFStringCompareWithOptionsAndLocale(cf1, cf2, CFRangeMake(0, CFStringGetLength(cf1)), flags, _osx_locale); + + CFRelease(cf1); + CFRelease(cf2); + + return (int)res + 2; +} + +#else +void MacOSSetCurrentLocaleName(const char *iso_code) {} + +int MacOSStringCompare(const char *s1, const char *s2) +{ + return 0; +} +#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */ diff --git a/src/os/macosx/string_osx.h b/src/os/macosx/string_osx.h new file mode 100644 index 000000000..90bac48d2 --- /dev/null +++ b/src/os/macosx/string_osx.h @@ -0,0 +1,19 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file string_osx.h Functions related to localized text support on OSX. */ + +#ifndef STRING_OSX_H +#define STRING_OSX_H + + +void MacOSSetCurrentLocaleName(const char *iso_code); +int MacOSStringCompare(const char *s1, const char *s2); + +#endif /* STRING_OSX_H */ diff --git a/src/string.cpp b/src/string.cpp index 66140b7d4..845225d6f 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -33,6 +33,10 @@ #include "os/windows/string_uniscribe.h" #endif +#if defined(WITH_COCOA) +#include "os/macosx/string_osx.h" +#endif + #ifdef WITH_ICU_SORT /* Required by strnatcmp. */ #include @@ -593,6 +597,11 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) if (res != 0) return res - 2; // Convert to normal C return values. #endif +#if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) + int res = MacOSStringCompare(s1, s2); + if (res != 0) return res - 2; // Convert to normal C return values. +#endif + /* Do a normal comparison if ICU is missing or if we cannot create a collator. */ return strcasecmp(s1, s2); } diff --git a/src/strings.cpp b/src/strings.cpp index 8ec9844b6..eaaa38758 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -1791,6 +1791,11 @@ bool ReadLanguagePack(const LanguageMetadata *lang) Win32SetCurrentLocaleName(_current_language->isocode); #endif +#ifdef WITH_COCOA + extern void MacOSSetCurrentLocaleName(const char *iso_code); + MacOSSetCurrentLocaleName(_current_language->isocode); +#endif + #ifdef WITH_ICU_SORT /* Delete previous collator. */ if (_current_collator != NULL) { -- cgit v1.2.3-70-g09d2