diff options
author | Chris Loer <chris.loer@gmail.com> | 2016-11-16 12:50:57 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-11-17 14:33:03 -0800 |
commit | d4fc66af3924805d40576989c1e139ddafcc4670 (patch) | |
tree | 87e8dac7bc21051086f2765b4d04e884aad4cec7 /src/mbgl/text | |
parent | bceeba29a3fa85105c21718ed0be8704508ab585 (diff) | |
download | qtlocation-mapboxgl-d4fc66af3924805d40576989c1e139ddafcc4670.tar.gz |
[core] Add minimal line breaking support for RTL text.
Diffstat (limited to 'src/mbgl/text')
-rw-r--r-- | src/mbgl/text/bidi.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/text/bidi.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/text/glyph_set.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/text/glyph_set.hpp | 5 |
4 files changed, 22 insertions, 12 deletions
diff --git a/src/mbgl/text/bidi.cpp b/src/mbgl/text/bidi.cpp index 2b6967110c..4c127e9cab 100644 --- a/src/mbgl/text/bidi.cpp +++ b/src/mbgl/text/bidi.cpp @@ -2,6 +2,7 @@ #include <mbgl/text/bidi.hpp> #include <unicode/ubidi.h> +#include <unicode/ubiditransform.h> #include <unicode/ushape.h> namespace mbgl { @@ -44,10 +45,12 @@ std::u16string BiDi::bidiTransform(const std::u16string& input) { return std::u16string(outputText.get(), outputLength); } -bool BiDi::baseDirectionRightToLeft(const std::u16string& input) { +WritingDirection BiDi::baseWritingDirection(const std::u16string& input) { // This just looks for the first character with a strong direction property, it does not perform // the BiDi algorithm - return ubidi_getBaseDirection(input.c_str(), static_cast<int32_t>(input.size())) == UBIDI_RTL; + return ubidi_getBaseDirection(input.c_str(), static_cast<int32_t>(input.size())) == UBIDI_RTL + ? WritingDirection::RightToLeft + : WritingDirection::LeftToRight; } } // end namespace mbgl diff --git a/src/mbgl/text/bidi.hpp b/src/mbgl/text/bidi.hpp index 030ac88ce2..e29bf041e2 100644 --- a/src/mbgl/text/bidi.hpp +++ b/src/mbgl/text/bidi.hpp @@ -3,17 +3,20 @@ #include <string> #include <mbgl/util/noncopyable.hpp> -#include <unicode/ubiditransform.h> -namespace mbgl { +struct UBiDiTransform; +namespace mbgl { + +enum class WritingDirection : bool { LeftToRight, RightToLeft }; + class BiDi : private util::noncopyable { public: BiDi(); ~BiDi(); std::u16string bidiTransform(const std::u16string&); - bool baseDirectionRightToLeft(const std::u16string&); + WritingDirection baseWritingDirection(const std::u16string&); private: UBiDiTransform* transform; diff --git a/src/mbgl/text/glyph_set.cpp b/src/mbgl/text/glyph_set.cpp index f0e3991540..67c2ab93e4 100644 --- a/src/mbgl/text/glyph_set.cpp +++ b/src/mbgl/text/glyph_set.cpp @@ -2,6 +2,7 @@ #include <mbgl/platform/log.hpp> #include <mbgl/math/minmax.hpp> #include <mbgl/util/i18n.hpp> +#include <mbgl/text/bidi.hpp> #include <cassert> @@ -31,7 +32,7 @@ const std::map<uint32_t, SDFGlyph> &GlyphSet::getSDFs() const { return sdfs; } -const Shaping GlyphSet::getShaping(const std::u16string &string, const float maxWidth, +const Shaping GlyphSet::getShaping(const std::u16string &string, const WritingDirection writingDirection, const float maxWidth, const float lineHeight, const float horizontalAlign, const float verticalAlign, const float justify, const float spacing, const Point<float> &translate) const { @@ -56,7 +57,7 @@ const Shaping GlyphSet::getShaping(const std::u16string &string, const float max return shaping; lineWrap(shaping, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate, - util::i18n::allowsIdeographicBreaking(string)); + util::i18n::allowsIdeographicBreaking(string), writingDirection); return shaping; } @@ -90,7 +91,9 @@ void justifyLine(std::vector<PositionedGlyph> &positionedGlyphs, const std::map< void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, float maxWidth, const float horizontalAlign, const float verticalAlign, const float justify, const Point<float> &translate, - bool useBalancedIdeographicBreaking) const { + bool useBalancedIdeographicBreaking, const WritingDirection writingDirection) const { + float lineFeedOffset = writingDirection == WritingDirection::RightToLeft ? -lineHeight : lineHeight; + uint32_t lastSafeBreak = 0; uint32_t lengthBeforeCurrentLine = 0; @@ -112,7 +115,7 @@ void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, float maxWidth PositionedGlyph &shape = positionedGlyphs[i]; shape.x -= lengthBeforeCurrentLine; - shape.y += lineHeight * line; + shape.y += lineFeedOffset * line; if (shape.x > maxWidth && lastSafeBreak > 0) { @@ -120,7 +123,7 @@ void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, float maxWidth maxLineLength = util::max(lineLength, maxLineLength); for (uint32_t k = lastSafeBreak + 1; k <= i; k++) { - positionedGlyphs[k].y += lineHeight; + positionedGlyphs[k].y += lineFeedOffset; positionedGlyphs[k].x -= lineLength; } diff --git a/src/mbgl/text/glyph_set.hpp b/src/mbgl/text/glyph_set.hpp index 004cae343d..b4fcf4c3a4 100644 --- a/src/mbgl/text/glyph_set.hpp +++ b/src/mbgl/text/glyph_set.hpp @@ -1,5 +1,6 @@ #pragma once +#include <mbgl/text/bidi.hpp> #include <mbgl/text/glyph.hpp> #include <mbgl/util/geometry.hpp> @@ -9,12 +10,12 @@ class GlyphSet { public: void insert(uint32_t id, SDFGlyph&&); const std::map<uint32_t, SDFGlyph> &getSDFs() const; - const Shaping getShaping(const std::u16string &string, float maxWidth, float lineHeight, + const Shaping getShaping(const std::u16string &string, const WritingDirection writingDirection, float maxWidth, float lineHeight, float horizontalAlign, float verticalAlign, float justify, float spacing, const Point<float> &translate) const; void lineWrap(Shaping &shaping, float lineHeight, float maxWidth, float horizontalAlign, float verticalAlign, float justify, const Point<float> &translate, - bool useBalancedIdeographicBreaking) const; + bool useBalancedIdeographicBreaking, const WritingDirection writingDirection) const; private: std::map<uint32_t, SDFGlyph> sdfs; |