summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-12-12 12:46:24 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-12-12 22:34:52 +0200
commitce5ed9e6498a832f070400fb281e46cd04e39ea1 (patch)
tree68b51821738b03558da85d981903b4febb3e39af /platform
parenteff986bfc42c450ebca075a9a2b59940d5cd8e33 (diff)
downloadqtlocation-mapboxgl-ce5ed9e6498a832f070400fb281e46cd04e39ea1.tar.gz
[build] ICU is now configured per platform
Diffstat (limited to 'platform')
-rw-r--r--platform/android/config.cmake3
-rw-r--r--platform/default/bidi.cpp125
-rw-r--r--platform/ios/config.cmake4
-rw-r--r--platform/linux/config.cmake3
-rw-r--r--platform/macos/config.cmake3
-rw-r--r--platform/qt/config.cmake4
-rw-r--r--platform/qt/qt.cmake1
7 files changed, 143 insertions, 0 deletions
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 32745720e5..635c27a44f 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -25,6 +25,7 @@ mason_use(libzip VERSION 1.1.3)
mason_use(nunicode VERSION 1.7.1)
mason_use(sqlite VERSION 3.14.2)
mason_use(gtest VERSION 1.7.0)
+mason_use(icu VERSION 58.1)
set(ANDROID_SDK_PROJECT_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDK)
set(ANDROID_JNI_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/jniLibs/${ANDROID_JNIDIR})
@@ -77,6 +78,7 @@ macro(mbgl_platform_core)
# Misc
PRIVATE platform/android/src/logging_android.cpp
PRIVATE platform/default/string_stdlib.cpp
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/default/image.cpp
@@ -163,6 +165,7 @@ macro(mbgl_platform_core)
target_add_mason_package(mbgl-core PUBLIC geojson)
target_add_mason_package(mbgl-core PUBLIC jni.hpp)
target_add_mason_package(mbgl-core PUBLIC rapidjson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fvisibility=hidden
diff --git a/platform/default/bidi.cpp b/platform/default/bidi.cpp
new file mode 100644
index 0000000000..7d5f6313bc
--- /dev/null
+++ b/platform/default/bidi.cpp
@@ -0,0 +1,125 @@
+#include <memory>
+
+#include <mbgl/text/bidi.hpp>
+#include <unicode/ubidi.h>
+#include <unicode/ushape.h>
+
+namespace mbgl {
+
+// Takes UTF16 input in logical order and applies Arabic shaping to the input while maintaining
+// logical order
+// Output won't be intelligible until the bidirectional algorithm is applied
+std::u16string applyArabicShaping(const std::u16string& input) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ int32_t outputLength =
+ u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), NULL, 0,
+ (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) |
+ (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK),
+ &errorCode);
+
+ // Pre-flighting will always set U_BUFFER_OVERFLOW_ERROR
+ errorCode = U_ZERO_ERROR;
+
+ std::unique_ptr<UChar[]> outputText = std::make_unique<UChar[]>(outputLength);
+ u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), outputText.get(), outputLength,
+ (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) |
+ (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK),
+ &errorCode);
+
+ // If the algorithm fails for any reason, fall back to non-transformed text
+ if (U_FAILURE(errorCode))
+ return input;
+
+ return std::u16string(outputText.get(), outputLength);
+}
+
+ProcessedBiDiText::ProcessedBiDiText(BiDi& p_bidi) : bidi(p_bidi) {
+}
+
+void ProcessedBiDiText::mergeParagraphLineBreaks(std::set<int32_t>& lineBreakPoints) {
+ int32_t paragraphCount = ubidi_countParagraphs(bidi.bidiText);
+ for (int32_t i = 0; i < paragraphCount; i++) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ int32_t paragraphEndIndex;
+ ubidi_getParagraphByIndex(bidi.bidiText, i, NULL, &paragraphEndIndex, NULL, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("ProcessedBiDiText::mergeParagraphLineBreaks: ") +
+ u_errorName(errorCode));
+
+ lineBreakPoints.insert(paragraphEndIndex);
+ }
+}
+
+std::vector<std::u16string>
+ProcessedBiDiText::applyLineBreaking(std::set<int32_t> lineBreakPoints) {
+ // BiDi::getLine will error if called across a paragraph boundary, so we need to ensure that all
+ // paragraph
+ // boundaries are included in the set of line break points. The calling code might not include
+ // the line break because it
+ // didn't need to wrap at that point, or because the text was separated with a more exotic code
+ // point such as (U+001C)
+ mergeParagraphLineBreaks(lineBreakPoints);
+
+ std::vector<std::u16string> transformedLines;
+ int32_t start = 0;
+ for (int32_t lineBreakPoint : lineBreakPoints) {
+ transformedLines.push_back(bidi.getLine(start, lineBreakPoint));
+ start = lineBreakPoint;
+ }
+
+ return transformedLines;
+}
+
+BiDi::BiDi() {
+ bidiText = ubidi_open();
+ bidiLine = ubidi_open();
+}
+
+BiDi::~BiDi() {
+ if (bidiText)
+ ubidi_close(bidiText);
+
+ if (bidiLine)
+ ubidi_close(bidiLine);
+}
+
+ProcessedBiDiText BiDi::processText(const std::u16string& input) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ ubidi_setPara(bidiText, input.c_str(), static_cast<int32_t>(input.size()), UBIDI_DEFAULT_LTR,
+ NULL, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::processText: ") + u_errorName(errorCode));
+
+ return ProcessedBiDiText(*this);
+}
+
+std::u16string BiDi::getLine(int32_t start, int32_t end) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ ubidi_setLine(bidiText, start, end, bidiLine, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::getLine (setLine): ") + u_errorName(errorCode));
+
+ // Because we set UBIDI_REMOVE_BIDI_CONTROLS, the output may be smaller than what we reserve
+ // Setting UBIDI_INSERT_LRM_FOR_NUMERIC would require
+ // ubidi_getLength(pBiDi)+2*ubidi_countRuns(pBiDi)
+ int32_t outputLength = ubidi_getProcessedLength(bidiLine);
+ std::unique_ptr<UChar[]> outputText = std::make_unique<UChar[]>(outputLength);
+
+ // UBIDI_DO_MIRRORING: Apply unicode mirroring of characters like parentheses
+ // UBIDI_REMOVE_BIDI_CONTROLS: Now that all the lines are set, remove control characters so that
+ // they don't show up on screen (some fonts have glyphs representing them)
+ ubidi_writeReordered(bidiLine, outputText.get(), outputLength,
+ UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::getLine (writeReordered): ") + u_errorName(errorCode));
+
+ return std::u16string(outputText.get(), outputLength);
+}
+
+} // end namespace mbgl
diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake
index 195687fea5..12db02921c 100644
--- a/platform/ios/config.cmake
+++ b/platform/ios/config.cmake
@@ -1,5 +1,7 @@
add_definitions(-DMBGL_USE_GLES2=1)
+mason_use(icu VERSION 58.1)
+
macro(mbgl_platform_core)
set_xcode_property(mbgl-core IPHONEOS_DEPLOYMENT_TARGET "8.0")
set_xcode_property(mbgl-core ENABLE_BITCODE "YES")
@@ -38,6 +40,7 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/logging_nslog.mm
PRIVATE platform/darwin/src/nsthread.mm
PRIVATE platform/darwin/src/string_nsstring.mm
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/darwin/src/image.mm
@@ -57,6 +60,7 @@ macro(mbgl_platform_core)
)
target_add_mason_package(mbgl-core PUBLIC geojson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fobjc-arc
diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake
index f71d8aa4f9..51aecb86a9 100644
--- a/platform/linux/config.cmake
+++ b/platform/linux/config.cmake
@@ -11,6 +11,7 @@ mason_use(libjpeg-turbo VERSION 1.5.0)
mason_use(webp VERSION 0.5.1)
mason_use(gtest VERSION 1.7.0${MASON_CXXABI_SUFFIX})
mason_use(benchmark VERSION 1.0.0)
+mason_use(icu VERSION 58.1)
include(cmake/loop-uv.cmake)
@@ -70,6 +71,7 @@ macro(mbgl_platform_core)
PRIVATE platform/default/logging_stderr.cpp
PRIVATE platform/default/string_stdlib.cpp
PRIVATE platform/default/thread.cpp
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/default/image.cpp
@@ -98,6 +100,7 @@ macro(mbgl_platform_core)
target_add_mason_package(mbgl-core PUBLIC libpng)
target_add_mason_package(mbgl-core PUBLIC libjpeg-turbo)
target_add_mason_package(mbgl-core PUBLIC webp)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_link_libraries(mbgl-core
PUBLIC -lz
diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake
index 207ac3257c..af274f7fc2 100644
--- a/platform/macos/config.cmake
+++ b/platform/macos/config.cmake
@@ -4,6 +4,7 @@ mason_use(glfw VERSION 3.2.1)
mason_use(boost_libprogram_options VERSION 1.62.0)
mason_use(gtest VERSION 1.7.0${MASON_CXXABI_SUFFIX})
mason_use(benchmark VERSION 1.0.0)
+mason_use(icu VERSION 58.1)
include(cmake/loop-darwin.cmake)
@@ -37,6 +38,7 @@ macro(mbgl_platform_core)
PRIVATE platform/darwin/src/logging_nslog.mm
PRIVATE platform/darwin/src/nsthread.mm
PRIVATE platform/darwin/src/string_nsstring.mm
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/darwin/src/image.mm
@@ -56,6 +58,7 @@ macro(mbgl_platform_core)
)
target_add_mason_package(mbgl-core PUBLIC geojson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fobjc-arc
diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake
index 30781fa428..f6b7d509f8 100644
--- a/platform/qt/config.cmake
+++ b/platform/qt/config.cmake
@@ -2,6 +2,7 @@ include(platform/qt/qt.cmake)
mason_use(sqlite VERSION 3.14.2)
mason_use(gtest VERSION 1.7.0${MASON_CXXABI_SUFFIX})
+mason_use(icu VERSION 58.1)
if(NOT WITH_QT_DECODERS)
mason_use(libjpeg-turbo VERSION 1.5.0)
@@ -38,6 +39,9 @@ macro(mbgl_platform_core)
else()
add_definitions(-DQT_IMAGE_DECODERS)
endif()
+
+ target_add_mason_package(mbgl-core PRIVATE icu)
+
endmacro()
macro(mbgl_platform_test)
diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake
index 3efdf6cad8..c640ca5689 100644
--- a/platform/qt/qt.cmake
+++ b/platform/qt/qt.cmake
@@ -29,6 +29,7 @@ set(MBGL_QT_FILES
# Misc
PRIVATE platform/default/logging_stderr.cpp
+ PRIVATE platform/default/bidi.cpp
# Thread pool
PRIVATE platform/default/mbgl/util/default_thread_pool.cpp