Browse Source

Merge pull request #1479 from ombre5733/MF-FINALLY-FIX-LINUX-LOCALE

Keep the locale when initializing the CEF.
JoshEngebretson 8 years ago
parent
commit
da9c728e70
2 changed files with 79 additions and 154 deletions
  1. 67 154
      Source/Atomic/Core/StringUtils.cpp
  2. 12 0
      Source/AtomicWebView/WebBrowserHost.cpp

+ 67 - 154
Source/Atomic/Core/StringUtils.cpp

@@ -28,60 +28,6 @@
 
 
 #include "../DebugNew.h"
 #include "../DebugNew.h"
 
 
-// ATOMIC BEGIN
-
-// The built-in strtod() function uses the current locale for parsing strings. On certain
-// locales (German, Swedish, ...) a comma is used as decimal separator. For portable XML,
-// we need to parse floating point values the same way on all platforms no matter what
-// locale is set. The strtod_c_locale() is a workaround using the "C" locale explicitly,
-// which uses a dot as decimal separator.
-
-#include <locale.h>
-#ifdef ATOMIC_PLATFORM_OSX
-#include <xlocale.h>
-#endif
-
-#include <stdlib.h>
-
-#ifdef ATOMIC_PLATFORM_WINDOWS
-
-static _locale_t get_c_locale()
-{
-    static _locale_t loc = _create_locale(LC_ALL, "C");
-    return loc;
-}
-
-static double strtod_c_locale(const char* nptr, char** endptr)
-{
-    return _strtod_l(nptr, endptr, get_c_locale());
-}
-
-#elif defined(ATOMIC_PLATFORM_ANDROID) || defined(ATOMIC_PLATFORM_IOS)
-
-// Android NDK/iOS don't do locale, so just revert to strtod
-
-static double strtod_c_locale(const char* nptr, char** endptr)
-{
-    return strtod(nptr, endptr);
-}
-
-#else
-
-static locale_t get_c_locale()
-{
-    static locale_t loc = newlocale(LC_ALL_MASK, "C", NULL);
-    return loc;
-}
-
-static double strtod_c_locale(const char* nptr, char** endptr)
-{
-    return strtod_l(nptr, endptr, get_c_locale());
-}
-
-#endif // ATOMIC_PLATFORM_WINDOWS
-
-// ATOMIC END
-
 namespace Atomic
 namespace Atomic
 {
 {
 
 
@@ -200,9 +146,7 @@ float ToFloat(const char* source)
     if (!source)
     if (!source)
         return 0;
         return 0;
 
 
-    // ATOMIC BEGIN
-    return (float)strtod_c_locale(source, 0);
-    // ATOMIC END
+    return (float)strtod(source, 0);
 }
 }
 
 
 double ToDouble(const String& source)
 double ToDouble(const String& source)
@@ -215,9 +159,7 @@ double ToDouble(const char* source)
     if (!source)
     if (!source)
         return 0;
         return 0;
 
 
-    // ATOMIC BEGIN
-    return strtod_c_locale(source, 0);
-    // ATOMIC END
+    return strtod(source, 0);
 }
 }
 
 
 Color ToColor(const String& source)
 Color ToColor(const String& source)
@@ -234,14 +176,11 @@ Color ToColor(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.r_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.g_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.b_ = (float)strtod_c_locale(ptr, &ptr);
+    ret.r_ = (float)strtod(ptr, &ptr);
+    ret.g_ = (float)strtod(ptr, &ptr);
+    ret.b_ = (float)strtod(ptr, &ptr);
     if (elements > 3)
     if (elements > 3)
-        ret.a_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+        ret.a_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -302,13 +241,10 @@ Rect ToRect(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.min_.x_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.min_.y_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.max_.x_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.max_.y_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.min_.x_ = (float)strtod(ptr, &ptr);
+    ret.min_.y_ = (float)strtod(ptr, &ptr);
+    ret.max_.x_ = (float)strtod(ptr, &ptr);
+    ret.max_.y_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -329,12 +265,9 @@ Quaternion ToQuaternion(const char* source)
     {
     {
         // 3 coords specified: conversion from Euler angles
         // 3 coords specified: conversion from Euler angles
         float x, y, z;
         float x, y, z;
-
-        // ATOMIC BEGIN
-        x = (float)strtod_c_locale(ptr, &ptr);
-        y = (float)strtod_c_locale(ptr, &ptr);
-        z = (float)strtod_c_locale(ptr, &ptr);
-        // ATOMIC END
+        x = (float)strtod(ptr, &ptr);
+        y = (float)strtod(ptr, &ptr);
+        z = (float)strtod(ptr, &ptr);
 
 
         return Quaternion(x, y, z);
         return Quaternion(x, y, z);
     }
     }
@@ -342,13 +275,10 @@ Quaternion ToQuaternion(const char* source)
     {
     {
         // 4 coords specified: full quaternion
         // 4 coords specified: full quaternion
         Quaternion ret;
         Quaternion ret;
-
-        // ATOMIC BEGIN
-        ret.w_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.x_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.y_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.z_ = (float)strtod_c_locale(ptr, &ptr);
-        // ATOMIC END
+        ret.w_ = (float)strtod(ptr, &ptr);
+        ret.x_ = (float)strtod(ptr, &ptr);
+        ret.y_ = (float)strtod(ptr, &ptr);
+        ret.z_ = (float)strtod(ptr, &ptr);
 
 
         return ret;
         return ret;
     }
     }
@@ -368,11 +298,8 @@ Vector2 ToVector2(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.x_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.y_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.x_ = (float)strtod(ptr, &ptr);
+    ret.y_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -391,12 +318,9 @@ Vector3 ToVector3(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.x_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.y_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.z_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.x_ = (float)strtod(ptr, &ptr);
+    ret.y_ = (float)strtod(ptr, &ptr);
+    ret.z_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -413,33 +337,31 @@ Vector4 ToVector4(const char* source, bool allowMissingCoords)
     unsigned elements = CountElements(source, ' ');
     unsigned elements = CountElements(source, ' ');
     char* ptr = (char*)source;
     char* ptr = (char*)source;
 
 
-    // ATOMIC BEGIN
     if (!allowMissingCoords)
     if (!allowMissingCoords)
     {
     {
         if (elements < 4)
         if (elements < 4)
             return ret;
             return ret;
 
 
-        ret.x_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.y_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.z_ = (float)strtod_c_locale(ptr, &ptr);
-        ret.w_ = (float)strtod_c_locale(ptr, &ptr);
+        ret.x_ = (float)strtod(ptr, &ptr);
+        ret.y_ = (float)strtod(ptr, &ptr);
+        ret.z_ = (float)strtod(ptr, &ptr);
+        ret.w_ = (float)strtod(ptr, &ptr);
 
 
         return ret;
         return ret;
     }
     }
     else
     else
     {
     {
         if (elements > 0)
         if (elements > 0)
-            ret.x_ = (float)strtod_c_locale(ptr, &ptr);
+            ret.x_ = (float)strtod(ptr, &ptr);
         if (elements > 1)
         if (elements > 1)
-            ret.y_ = (float)strtod_c_locale(ptr, &ptr);
+            ret.y_ = (float)strtod(ptr, &ptr);
         if (elements > 2)
         if (elements > 2)
-            ret.z_ = (float)strtod_c_locale(ptr, &ptr);
+            ret.z_ = (float)strtod(ptr, &ptr);
         if (elements > 3)
         if (elements > 3)
-            ret.w_ = (float)strtod_c_locale(ptr, &ptr);
+            ret.w_ = (float)strtod(ptr, &ptr);
 
 
         return ret;
         return ret;
     }
     }
-    // ATOMIC END
 }
 }
 
 
 Variant ToVectorVariant(const String& source)
 Variant ToVectorVariant(const String& source)
@@ -504,18 +426,15 @@ Matrix3 ToMatrix3(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.m00_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m01_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m02_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m10_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m11_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m12_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m20_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m21_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m22_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -534,21 +453,18 @@ Matrix3x4 ToMatrix3x4(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.m00_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m01_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m02_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m03_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m10_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m11_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m12_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m13_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m20_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m21_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m22_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m23_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m03_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m13_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
+    ret.m23_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }
@@ -567,25 +483,22 @@ Matrix4 ToMatrix4(const char* source)
         return ret;
         return ret;
 
 
     char* ptr = (char*)source;
     char* ptr = (char*)source;
-
-    // ATOMIC BEGIN
-    ret.m00_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m01_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m02_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m03_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m10_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m11_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m12_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m13_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m20_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m21_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m22_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m23_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m30_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m31_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m32_ = (float)strtod_c_locale(ptr, &ptr);
-    ret.m33_ = (float)strtod_c_locale(ptr, &ptr);
-    // ATOMIC END
+    ret.m00_ = (float)strtod(ptr, &ptr);
+    ret.m01_ = (float)strtod(ptr, &ptr);
+    ret.m02_ = (float)strtod(ptr, &ptr);
+    ret.m03_ = (float)strtod(ptr, &ptr);
+    ret.m10_ = (float)strtod(ptr, &ptr);
+    ret.m11_ = (float)strtod(ptr, &ptr);
+    ret.m12_ = (float)strtod(ptr, &ptr);
+    ret.m13_ = (float)strtod(ptr, &ptr);
+    ret.m20_ = (float)strtod(ptr, &ptr);
+    ret.m21_ = (float)strtod(ptr, &ptr);
+    ret.m22_ = (float)strtod(ptr, &ptr);
+    ret.m23_ = (float)strtod(ptr, &ptr);
+    ret.m30_ = (float)strtod(ptr, &ptr);
+    ret.m31_ = (float)strtod(ptr, &ptr);
+    ret.m32_ = (float)strtod(ptr, &ptr);
+    ret.m33_ = (float)strtod(ptr, &ptr);
 
 
     return ret;
     return ret;
 }
 }

+ 12 - 0
Source/AtomicWebView/WebBrowserHost.cpp

@@ -46,6 +46,7 @@
 
 
 #ifdef ATOMIC_PLATFORM_LINUX
 #ifdef ATOMIC_PLATFORM_LINUX
 
 
+#include <locale>
 #include <X11/Xlib.h>
 #include <X11/Xlib.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <unistd.h>
@@ -208,6 +209,13 @@ WebBrowserHost::WebBrowserHost(Context* context) : Object (context)
 
 
     d_ = new WebBrowserHostPrivate(this);
     d_ = new WebBrowserHostPrivate(this);
 
 
+#ifdef ATOMIC_PLATFORM_LINUX
+    // On Linux systems, CEF ignores the locale in CefSettings and sets it based on environment variables.
+    // On non-English systems this changes the decimal separator to a comma (e.g. with a German
+    // locale such as de-AT), which in turn breaks the cross-platform behavior of strtod() and sprintf().
+    std::locale oldLocale;
+#endif
+
     // If losing OSX system menu, it means we're calling this
     // If losing OSX system menu, it means we're calling this
     // before initializing graphics subsystem
     // before initializing graphics subsystem
     if (!CefInitialize(args, settings, d_->app_, nullptr))
     if (!CefInitialize(args, settings, d_->app_, nullptr))
@@ -215,6 +223,10 @@ WebBrowserHost::WebBrowserHost(Context* context) : Object (context)
         ATOMIC_LOGERROR("CefInitialize - Error");
         ATOMIC_LOGERROR("CefInitialize - Error");
     }
     }
 
 
+#ifdef ATOMIC_PLATFORM_LINUX
+    std::locale::global(oldLocale);
+#endif
+
     RegisterWebSchemeHandlers(this);
     RegisterWebSchemeHandlers(this);
 
 
     // Ensure cookie manager is created
     // Ensure cookie manager is created