diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-12-12 12:46:24 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-12-12 22:34:52 +0200 |
commit | ce5ed9e6498a832f070400fb281e46cd04e39ea1 (patch) | |
tree | 68b51821738b03558da85d981903b4febb3e39af /platform | |
parent | eff986bfc42c450ebca075a9a2b59940d5cd8e33 (diff) | |
download | qtlocation-mapboxgl-ce5ed9e6498a832f070400fb281e46cd04e39ea1.tar.gz |
[build] ICU is now configured per platform
Diffstat (limited to 'platform')
-rw-r--r-- | platform/android/config.cmake | 3 | ||||
-rw-r--r-- | platform/default/bidi.cpp | 125 | ||||
-rw-r--r-- | platform/ios/config.cmake | 4 | ||||
-rw-r--r-- | platform/linux/config.cmake | 3 | ||||
-rw-r--r-- | platform/macos/config.cmake | 3 | ||||
-rw-r--r-- | platform/qt/config.cmake | 4 | ||||
-rw-r--r-- | platform/qt/qt.cmake | 1 |
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, ¶graphEndIndex, 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 |