From 65a4ee2373d053ac5b8d179123fdc51b320a1bb7 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Thu, 26 Apr 2018 13:41:19 -0700 Subject: [core] Port is-supported-script to native. Native port is much simpler because RTL text support is always enabled. --- platform/node/test/ignores.json | 4 +-- src/mbgl/style/expression/compound_expression.cpp | 5 +++ src/mbgl/util/i18n.cpp | 37 +++++++++++++++++++++-- src/mbgl/util/i18n.hpp | 2 ++ test/style/expression/expression.test.cpp | 2 +- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 98d7e016bc..a1d4d68511 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -14,7 +14,7 @@ "expression-tests/collator/non-object-error": "https://github.com/mapbox/mapbox-gl-native/issues/11692", "expression-tests/collator/variant-equals-en": "https://github.com/mapbox/mapbox-gl-native/issues/11692", "expression-tests/collator/variant-gteq-en": "https://github.com/mapbox/mapbox-gl-native/issues/11692", - "expression-tests/is-supported-script/default": "https://github.com/mapbox/mapbox-gl-native/issues/11693", + "expression-tests/is-supported-script/default": "This tests RTL text plugin behavior specific to GL JS", "expression-tests/resolved-locale/basic": "https://github.com/mapbox/mapbox-gl-native/issues/11692", "expression-tests/to-string/basic": "https://github.com/mapbox/mapbox-gl-native/issues/11719", "query-tests/geometry/multilinestring": "needs investigation", @@ -39,8 +39,6 @@ "render-tests/fill-extrusion-pattern/opacity": "https://github.com/mapbox/mapbox-gl-js/issues/3327", "render-tests/geojson/inline-linestring-fill": "current behavior is arbitrary", "render-tests/geojson/inline-polygon-symbol": "behavior needs reconciliation with gl-js", - "render-tests/is-supported-script/filter": "https://github.com/mapbox/mapbox-gl-native/issues/11693", - "render-tests/is-supported-script/layout": "https://github.com/mapbox/mapbox-gl-native/issues/11693", "render-tests/line-gradient/gradient": "https://github.com/mapbox/mapbox-gl-native/issues/11718", "render-tests/line-gradient/translucent": "https://github.com/mapbox/mapbox-gl-native/issues/11718", "render-tests/mixed-zoom/z10-z11": "https://github.com/mapbox/mapbox-gl-native/issues/10397", diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index c36ffa33e3..c257dbf2bb 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -379,6 +380,10 @@ std::unordered_map initiali define("!", [](bool e) -> Result { return !e; }); + define("is-supported-script", [](const std::string& x) -> Result { + return util::i18n::isStringInSupportedScript(x); + }); + define("upcase", [](const std::string& input) -> Result { return platform::uppercase(input); }); diff --git a/src/mbgl/util/i18n.cpp b/src/mbgl/util/i18n.cpp index 1fc13bfb7d..5530796915 100644 --- a/src/mbgl/util/i18n.cpp +++ b/src/mbgl/util/i18n.cpp @@ -1,4 +1,5 @@ -#include "i18n.hpp" +#include +#include #include #include @@ -65,7 +66,7 @@ DEFINE_IS_IN_UNICODE_BLOCK(UnifiedCanadianAboriginalSyllabics, 0x1400, 0x167F) // DEFINE_IS_IN_UNICODE_BLOCK(Hanunoo, 0x1720, 0x173F) // DEFINE_IS_IN_UNICODE_BLOCK(Buhid, 0x1740, 0x175F) // DEFINE_IS_IN_UNICODE_BLOCK(Tagbanwa, 0x1760, 0x177F) -// DEFINE_IS_IN_UNICODE_BLOCK(Khmer, 0x1780, 0x17FF) +DEFINE_IS_IN_UNICODE_BLOCK(Khmer, 0x1780, 0x17FF) // DEFINE_IS_IN_UNICODE_BLOCK(Mongolian, 0x1800, 0x18AF) DEFINE_IS_IN_UNICODE_BLOCK(UnifiedCanadianAboriginalSyllabicsExtended, 0x18B0, 0x18FF) // DEFINE_IS_IN_UNICODE_BLOCK(Limbu, 0x1900, 0x194F) @@ -581,6 +582,38 @@ std::u16string verticalizePunctuation(const std::u16string& input) { char16_t verticalizePunctuation(char16_t chr) { return verticalPunctuation.count(chr) ? verticalPunctuation.at(chr) : 0; } + +bool charInSupportedScript(char16_t chr) { + // This is a rough heuristic: whether we "can render" a script + // actually depends on the properties of the font being used + // and whether differences from the ideal rendering are considered + // semantically significant. + + // Even in Latin script, we "can't render" combinations such as the fi + // ligature, but we don't consider that semantically significant.n false; + if ((chr >= 0x0900 && chr <= 0x0DFF) || + // Main blocks for Indic scripts and Sinhala + (chr >= 0x0F00 && chr <= 0x109F) || + // Main blocks for Tibetan and Myanmar + isInKhmer(chr)) { + // These blocks cover common scripts that require + // complex text shaping, based on unicode script metadata: + // http://www.unicode.org/repos/cldr/trunk/common/properties/scriptMetadata.txt + // where "Web Rank <= 32" "Shaping Required = YES" + return false; + } + return true; +} + +bool isStringInSupportedScript(const std::string& input) { + auto u16string = util::utf8_to_utf16::convert(input); + for (char16_t chr : u16string) { + if (!charInSupportedScript(chr)) { + return false; + } + } + return true; +} } // namespace i18n } // namespace util diff --git a/src/mbgl/util/i18n.hpp b/src/mbgl/util/i18n.hpp index b3960c743c..a74215a134 100644 --- a/src/mbgl/util/i18n.hpp +++ b/src/mbgl/util/i18n.hpp @@ -72,6 +72,8 @@ std::u16string verticalizePunctuation(const std::u16string& input); @return The character’s specialized vertical form; 0 if not applicable. */ char16_t verticalizePunctuation(char16_t chr); + +bool isStringInSupportedScript(const std::string& input); } // namespace i18n } // namespace util diff --git a/test/style/expression/expression.test.cpp b/test/style/expression/expression.test.cpp index d5598d873b..9d5e172888 100644 --- a/test/style/expression/expression.test.cpp +++ b/test/style/expression/expression.test.cpp @@ -29,7 +29,7 @@ TEST(Expression, IsExpression) { for(auto& entry : allExpressions.GetObject()) { const std::string name { entry.name.GetString(), entry.name.GetStringLength() }; - if (name == "collator" || name == "line-progress" || name == "is-supported-script" || name == "resolved-locale") { + if (name == "collator" || name == "line-progress" || name == "resolved-locale") { // Not yet implemented continue; } -- cgit v1.2.1