summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/core-files.json1
-rwxr-xr-xplatform/android/src/jni.cpp2
-rw-r--r--platform/android/src/text/format_number.cpp81
-rw-r--r--platform/android/src/text/format_number_jni.hpp29
4 files changed, 113 insertions, 0 deletions
diff --git a/platform/android/core-files.json b/platform/android/core-files.json
index 7e2f7cc07b..62ecc0c671 100644
--- a/platform/android/core-files.json
+++ b/platform/android/core-files.json
@@ -81,6 +81,7 @@
"platform/android/src/style/value.cpp",
"platform/android/src/text/collator.cpp",
"platform/android/src/text/local_glyph_rasterizer.cpp",
+ "platform/android/src/text/format_number.cpp",
"platform/android/src/gl_functions.cpp",
"platform/android/src/thread.cpp",
"platform/android/src/timer.cpp",
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 410c962384..088b3b796c 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -54,6 +54,7 @@
#endif
#include "text/collator_jni.hpp"
#include "text/local_glyph_rasterizer_jni.hpp"
+#include "text/format_number_jni.hpp"
#include "logger.hpp"
namespace mbgl {
@@ -200,6 +201,7 @@ void registerNatives(JavaVM *vm) {
Locale::registerNative(env);
Collator::registerNative(env);
StringUtils::registerNative(env);
+ NumberFormat::registerNative(env);
// Logger
Logger::registerNative(env);
diff --git a/platform/android/src/text/format_number.cpp b/platform/android/src/text/format_number.cpp
new file mode 100644
index 0000000000..3a41175ecc
--- /dev/null
+++ b/platform/android/src/text/format_number.cpp
@@ -0,0 +1,81 @@
+#include <mbgl/style/expression/collator.hpp>
+#include <mbgl/text/language_tag.hpp>
+#include <mbgl/util/platform.hpp>
+
+#include <jni/jni.hpp>
+
+#include "../attach_env.hpp"
+#include "format_number_jni.hpp"
+
+namespace mbgl {
+namespace android {
+
+void NumberFormat::registerNative(jni::JNIEnv& env) {
+ jni::Class<NumberFormat>::Singleton(env);
+}
+
+jni::Local<jni::Object<NumberFormat>> NumberFormat::getInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
+ static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
+ static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getInstance");
+ return javaClass.Call(env, method, locale);
+}
+
+jni::Local<jni::Object<NumberFormat>> NumberFormat::getCurrencyInstance(jni::JNIEnv& env, const jni::Object<Locale>& locale) {
+ static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
+ static auto method = javaClass.GetStaticMethod<jni::Object<NumberFormat> (jni::Object<Locale>)>(env, "getCurrencyInstance");
+ return javaClass.Call(env, method, locale);
+}
+
+jni::Local<jni::String> NumberFormat::format(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jdouble number) {
+ static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
+ static auto method = javaClass.GetMethod<jni::String (jni::jdouble)>(env, "format");
+ return nf.Call(env, method, number);
+}
+
+void NumberFormat::setMinimumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
+ static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
+ static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setMinimumFractionDigits");
+ return nf.Call(env, method, value);
+}
+
+void NumberFormat::setMaximumFractionDigits(jni::JNIEnv& env, const jni::Object<NumberFormat>& nf, jni::jint value) {
+ static auto& javaClass = jni::Class<NumberFormat>::Singleton(env);
+ static auto method = javaClass.GetMethod<void (jni::jint)>(env, "setMaximumFractionDigits");
+ return nf.Call(env, method, value);
+}
+
+} // namespace android
+
+namespace platform {
+
+std::string formatNumber(double number, const std::string& localeId, const std::string& currency,
+ uint8_t minFractionDigits, uint8_t maxFractionDigits) {
+
+ auto env{ android::AttachEnv() };
+
+ jni::Global<jni::Object<android::Locale>> locale;
+ LanguageTag languageTag = !localeId.empty() ? LanguageTag::fromBCP47(localeId) : LanguageTag();
+ if (!languageTag.language) {
+ locale = jni::NewGlobal(*env, android::Locale::getDefault(*env));
+ } else if (!languageTag.region) {
+ locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language)));
+ } else {
+ locale = jni::NewGlobal(*env, android::Locale::New(*env, jni::Make<jni::String>(*env, *languageTag.language),
+ jni::Make<jni::String>(*env, *languageTag.region)));
+ }
+
+ jni::Global<jni::Object<android::NumberFormat>> formatter;
+ if (currency.empty()) {
+ formatter = jni::NewGlobal(*env, android::NumberFormat::getInstance(*env, locale));
+ android::NumberFormat::setMinimumFractionDigits(*env, formatter, static_cast<jni::jint>(minFractionDigits));
+ android::NumberFormat::setMaximumFractionDigits(*env, formatter, static_cast<jni::jint>(maxFractionDigits));
+ } else {
+ formatter = jni::NewGlobal(*env, android::NumberFormat::getCurrencyInstance(*env, locale));
+ }
+
+ auto result = android::NumberFormat::format(*env, formatter, static_cast<jni::jdouble>(number));
+ return jni::Make<std::string>(*env, result);
+}
+
+} // namespace platform
+} // namespace mbgl
diff --git a/platform/android/src/text/format_number_jni.hpp b/platform/android/src/text/format_number_jni.hpp
new file mode 100644
index 0000000000..1720038925
--- /dev/null
+++ b/platform/android/src/text/format_number_jni.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <jni/jni.hpp>
+
+#include "collator_jni.hpp"
+
+/*
+ android::NumberFormat is the JNI wrapper
+ of java/text/NumberFormat.
+ */
+
+namespace mbgl {
+namespace android {
+
+class NumberFormat {
+public:
+ static constexpr auto Name() { return "java/text/NumberFormat"; };
+
+ static jni::Local<jni::Object<NumberFormat>> getInstance(jni::JNIEnv&, const jni::Object<Locale>&);
+ static jni::Local<jni::Object<NumberFormat>> getCurrencyInstance(jni::JNIEnv&, const jni::Object<Locale>&);
+ static jni::Local<jni::String> format(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jdouble);
+ static void setMinimumFractionDigits(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jint);
+ static void setMaximumFractionDigits(jni::JNIEnv&, const jni::Object<NumberFormat>&, jni::jint);
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace android
+} // namespace mbgl