Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2017-04-19 20:23:56 +0300
committerSergey Yershov <syershov@maps.me>2017-04-21 20:06:36 +0300
commit6aa1e301b50c3c7b8d3c62cca2cf6938cefb8034 (patch)
tree8418948bac4539e9bf796a2e0c58a1a202329f21
parent2ae9a8d2d0a57782de5af9bd6502ded5fd60566f (diff)
Added new realization of right-to-left text reordering with BiDi algorithm from ICU library.
-rw-r--r--coding/transliteration.cpp3
-rw-r--r--data/copyright.html3
-rw-r--r--drape/CMakeLists.txt4
-rw-r--r--drape/drape.pro2
-rw-r--r--drape/drape_tests/drape_tests.pro3
-rw-r--r--drape/drape_tests/fribidi_tests.cpp2
-rw-r--r--drape/fribidi.cpp53
-rw-r--r--drape/fribidi.hpp5
-rw-r--r--drape_frontend/gui/gui_text.cpp4
-rw-r--r--drape_frontend/text_layout.cpp4
-rw-r--r--drape_frontend/watch/cpu_drawer.cpp14
-rw-r--r--drape_frontend/watch/glyph_cache.cpp17
-rw-r--r--drape_frontend/watch/glyph_cache.hpp2
13 files changed, 75 insertions, 41 deletions
diff --git a/coding/transliteration.cpp b/coding/transliteration.cpp
index 84cc8fca75..3c391f396a 100644
--- a/coding/transliteration.cpp
+++ b/coding/transliteration.cpp
@@ -2,6 +2,7 @@
#include "coding/multilang_utf8_string.hpp"
#include "base/logging.hpp"
+#include "base/string_utils.hpp"
#include "3party/icu/common/unicode/uclean.h"
#include "3party/icu/common/unicode/unistr.h"
@@ -60,7 +61,7 @@ void Transliteration::Init(std::string const & icuDataDir)
bool Transliteration::Transliterate(std::string const & str, int8_t langCode, std::string & out) const
{
- if (str.empty())
+ if (str.empty() || strings::IsASCIIString(str))
return false;
std::string transliteratorId(StringUtf8Multilang::GetTransliteratorIdByCode(langCode));
diff --git a/data/copyright.html b/data/copyright.html
index 684db76d53..da8634aad7 100644
--- a/data/copyright.html
+++ b/data/copyright.html
@@ -144,9 +144,6 @@
&copy; 2014 Google Inc.; <a href="#bsd3-license" class="license">BSD License;</a> <a href="#mit-license" class="license">MIT License;</a>
<a href="#apache2-license" class="license">Apache License</a></li>
- <li><a href="http://www.fribidi.org/">GNU FriBidi</a><br>
- &copy; Behdad Esfahbod, Dov Grobgeld, Roozbeh Pournader; <a href="#lgpl21-license" class="license">LGPL</a></li>
-
<li><a href="http://www.g-truc.net/project-0016.html">GLM</a><br>
&copy; 2005&ndash;2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt
index 4dd9c32e78..fba55fc05c 100644
--- a/drape/CMakeLists.txt
+++ b/drape/CMakeLists.txt
@@ -9,9 +9,13 @@ execute_process(
shader_def
)
+add_definitions(-DU_DISABLE_RENAMING)
+
include_directories(
${OMIM_ROOT}/3party/freetype/include
${OMIM_ROOT}/3party/glm
+ ${OMIM_ROOT}/3party/icu/common
+ ${OMIM_ROOT}/3party/icu/i18n
)
set(
diff --git a/drape/drape.pro b/drape/drape.pro
index 9d0247327b..26cc43a447 100644
--- a/drape/drape.pro
+++ b/drape/drape.pro
@@ -1,6 +1,8 @@
TARGET = drape
TEMPLATE = lib
CONFIG += staticlib warn_on
+INCLUDEPATH += ../3party/icu/common ../3party/icu/i18n
+DEFINES += U_DISABLE_RENAMING
ROOT_DIR = ..
SHADER_COMPILE_ARGS = $$PWD/shaders shader_index.txt shader_def
diff --git a/drape/drape_tests/drape_tests.pro b/drape/drape_tests/drape_tests.pro
index 1c6ed84c46..3d44b76b34 100644
--- a/drape/drape_tests/drape_tests.pro
+++ b/drape/drape_tests/drape_tests.pro
@@ -2,7 +2,8 @@ TARGET = drape_tests
CONFIG += console warn_on
CONFIG -= app_bundle
TEMPLATE = app
-DEFINES += OGL_TEST_ENABLED GTEST_DONT_DEFINE_TEST COMPILER_TESTS
+INCLUDEPATH += ../../3party/icu/common ../../3party/icu/i18n
+DEFINES += OGL_TEST_ENABLED GTEST_DONT_DEFINE_TEST COMPILER_TESTS U_DISABLE_RENAMING
ROOT_DIR = ../..
DEPENDENCIES = qt_tstfrm indexer platform coding geometry base gmock freetype fribidi expat stats_client stb_image sdf_image icu
diff --git a/drape/drape_tests/fribidi_tests.cpp b/drape/drape_tests/fribidi_tests.cpp
index 85061113d8..50030e622c 100644
--- a/drape/drape_tests/fribidi_tests.cpp
+++ b/drape/drape_tests/fribidi_tests.cpp
@@ -7,7 +7,7 @@ UNIT_TEST(FribidiDirection)
{
string base = "\u0686\u0631\u0645\u0647\u064A\u0646";
strings::UniString in = strings::MakeUniString(base);
- strings::UniString out1 = fribidi::log2vis(in);
+ strings::UniString out1 = bidi::log2vis(in);
string out = "\uFEE6\uFEF4\uFEEC\uFEE3\uFEAE\uFB7C";
strings::UniString out2 = strings::MakeUniString(out);
bool eq = out1 == out2;
diff --git a/drape/fribidi.cpp b/drape/fribidi.cpp
index df1f116ebe..8f5e534cdf 100644
--- a/drape/fribidi.cpp
+++ b/drape/fribidi.cpp
@@ -1,14 +1,61 @@
-#include "base/string_utils.hpp"
+#include "drape/fribidi.hpp"
-#include "3party/fribidi/lib/fribidi.h"
+#include "3party/icu/common/unicode/ubidi.h"
+#include "3party/icu/common/unicode/unistr.h"
+#include "3party/icu/common/unicode/ushape.h"
+#include "3party/fribidi/lib/fribidi.h"
#include "std/mutex.hpp"
-namespace fribidi
+namespace bidi
{
strings::UniString log2vis(strings::UniString const & str)
{
+ std::string str8 = strings::ToUtf8(str);
+ if (strings::IsASCIIString(str8))
+ return str;
+
+ UBiDi * bidi = ubidi_open();
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ UnicodeString ustr(str8.c_str());
+ ubidi_setPara(bidi, ustr.getTerminatedBuffer(), ustr.length(), UBIDI_DEFAULT_LTR, nullptr, &errorCode);
+
+ UBiDiDirection const direction = ubidi_getDirection(bidi);
+ if (direction == UBIDI_LTR || direction == UBIDI_NEUTRAL)
+ {
+ ubidi_close(bidi);
+ return str;
+ }
+
+ std::vector<UChar> buff(ustr.length() * 2, 0);
+
+ u_shapeArabic(ustr.getTerminatedBuffer(), ustr.length(), buff.data(), static_cast<uint32_t>(buff.size()),
+ U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED, &errorCode);
+ if (errorCode != U_ZERO_ERROR)
+ return str;
+
+ UnicodeString shaped(buff.data());
+
+ ubidi_setPara(bidi, shaped.getTerminatedBuffer(), shaped.length(), direction, nullptr, &errorCode);
+
+ ubidi_writeReordered(bidi, buff.data(), static_cast<uint32_t>(buff.size()), 0, &errorCode);
+ if (errorCode != U_ZERO_ERROR)
+ return str;
+
+ UnicodeString reordered(buff.data());
+
+ ubidi_close(bidi);
+
+ std::string out;
+ reordered.toUTF8String(out);
+
+ return strings::MakeUniString(out);
+}
+
+strings::UniString log2vis_old(strings::UniString const & str)
+{
static mutex log2visMutex;
size_t const count = str.size();
diff --git a/drape/fribidi.hpp b/drape/fribidi.hpp
index b3db34601d..9adb9fde5e 100644
--- a/drape/fribidi.hpp
+++ b/drape/fribidi.hpp
@@ -2,11 +2,10 @@
#include "base/string_utils.hpp"
-#include "3party/fribidi/lib/fribidi.h"
-
-namespace fribidi
+namespace bidi
{
strings::UniString log2vis(strings::UniString const & str);
+strings::UniString log2vis_old(strings::UniString const & str);
}
diff --git a/drape_frontend/gui/gui_text.cpp b/drape_frontend/gui/gui_text.cpp
index b28c1559a1..bc387f5cc1 100644
--- a/drape_frontend/gui/gui_text.cpp
+++ b/drape_frontend/gui/gui_text.cpp
@@ -118,7 +118,7 @@ void StaticLabel::CacheStaticText(string const & text, char const * delim,
dp::TextureManager::TMultilineText textParts;
strings::Tokenize(text, delim, [&textParts](string const & part)
{
- textParts.push_back(fribidi::log2vis(strings::MakeUniString(part)));
+ textParts.push_back(bidi::log2vis(strings::MakeUniString(part)));
});
ASSERT(!textParts.empty(), ());
@@ -370,7 +370,7 @@ void MutableLabel::SetText(LabelResult & result, string text) const
if (text.size() > m_maxLength)
text = text.erase(m_maxLength - 3) + "...";
- strings::UniString uniText = fribidi::log2vis(strings::MakeUniString(text));
+ strings::UniString uniText = bidi::log2vis(strings::MakeUniString(text));
float maxHeight = 0.0f;
float length = 0.0f;
diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp
index 6b58c5f198..7495ae3a4a 100644
--- a/drape_frontend/text_layout.cpp
+++ b/drape_frontend/text_layout.cpp
@@ -337,7 +337,7 @@ strings::UniString const & TextLayout::GetText() const
StraightTextLayout::StraightTextLayout(strings::UniString const & text, float fontSize, bool isSdf,
ref_ptr<dp::TextureManager> textures, dp::Anchor anchor)
{
- strings::UniString visibleText = fribidi::log2vis(text);
+ strings::UniString visibleText = bidi::log2vis(text);
buffer_vector<size_t, 2> delimIndexes;
if (visibleText == text)
SplitText(visibleText, delimIndexes);
@@ -393,7 +393,7 @@ PathTextLayout::PathTextLayout(m2::PointD const & tileCenter, strings::UniString
float fontSize, bool isSdf, ref_ptr<dp::TextureManager> textures)
: m_tileCenter(tileCenter)
{
- Init(fribidi::log2vis(text), fontSize, isSdf, textures);
+ Init(bidi::log2vis(text), fontSize, isSdf, textures);
}
void PathTextLayout::CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion,
diff --git a/drape_frontend/watch/cpu_drawer.cpp b/drape_frontend/watch/cpu_drawer.cpp
index 61dabb5163..0e60c859aa 100644
--- a/drape_frontend/watch/cpu_drawer.cpp
+++ b/drape_frontend/watch/cpu_drawer.cpp
@@ -27,13 +27,12 @@ void CorrectFont(dp::FontDecl & font)
strings::UniString PreProcessText(string const & text)
{
- strings::UniString logText = strings::MakeUniString(text);
- strings::UniString visText = df::watch::GlyphCache::log2vis(logText);
+ // Warning! This code processes text as left-to-right text
+ // and doesn't reorder right-to-left text. To support right-to-left text
+ // bidi algorithm should be applied.
+ strings::UniString visText = strings::MakeUniString(text);
char const * delims = " \n\t";
- if (logText != visText)
- return visText;
-
size_t count = visText.size();
if (count > 15)
{
@@ -637,7 +636,10 @@ void CPUDrawer::CallTextRendererFn(TextShape const * shape, TRoadNumberRendererC
{
string const & text = GetInfo(shape->m_geomID, m_roadNames);
- fn(shape->m_position, shape->m_anchor, m_roadNumberFont, GlyphCache::log2vis(strings::MakeUniString(text)));
+ // Warning! This code processes text as left-to-right text
+ // and doesn't reorder right-to-left text. To support right-to-left text
+ // bidi algorithm should be applied.
+ fn(shape->m_position, shape->m_anchor, m_roadNumberFont, strings::MakeUniString(text));
}
void CPUDrawer::CallTextRendererFn(ComplexShape const * shape, TPathTextRendererCall const & fn)
diff --git a/drape_frontend/watch/glyph_cache.cpp b/drape_frontend/watch/glyph_cache.cpp
index 5dd91bde1d..7d40582778 100644
--- a/drape_frontend/watch/glyph_cache.cpp
+++ b/drape_frontend/watch/glyph_cache.cpp
@@ -98,22 +98,5 @@ double GlyphCache::getTextLength(double fontSize, string const & text)
return len;
}
-threads::Mutex GlyphCache::s_fribidiMutex;
-
-strings::UniString GlyphCache::log2vis(strings::UniString const & str)
-{
- size_t const count = str.size();
- if (count == 0)
- return str;
-
- strings::UniString res(count);
-
- //FriBidiEnv env;
- threads::MutexGuard g(s_fribidiMutex);
- FriBidiParType dir = FRIBIDI_PAR_LTR; // requested base direction
- fribidi_log2vis(&str[0], static_cast<int>(count), &dir, &res[0], 0, 0, 0);
- return res;
-}
-
}
}
diff --git a/drape_frontend/watch/glyph_cache.hpp b/drape_frontend/watch/glyph_cache.hpp
index 9864c6bae0..7df1ad2f74 100644
--- a/drape_frontend/watch/glyph_cache.hpp
+++ b/drape_frontend/watch/glyph_cache.hpp
@@ -94,8 +94,6 @@ public:
GlyphMetrics const getGlyphMetrics(GlyphKey const & key);
double getTextLength(double fontSize, string const & text);
-
- static strings::UniString log2vis(strings::UniString const & str);
};
}