summaryrefslogtreecommitdiff
path: root/src/mbgl/text
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-11-14 14:53:21 -0800
committerGitHub <noreply@github.com>2016-11-14 14:53:21 -0800
commitdbd22357441ec66c46cc7e46a01ed114a18f685c (patch)
tree7f4af9a1276139863b6828b6f7ea152fd5b954a9 /src/mbgl/text
parent1c79147a84fe9f852fa21bcf5629f490e8e2a8bf (diff)
downloadqtlocation-mapboxgl-dbd22357441ec66c46cc7e46a01ed114a18f685c.tar.gz
[core] Line-break ideographic text by character (#6828)
* [core] Line-break ideographic text by character Allow a line break to be inserted after any supported Chinese, Japanese, or Yi character in a point-placed label. Balance the lines unless non-ideographic text such as Latin letters are present. Fixes #1223. * [core] Moved more character classing into util::i18n * [core] Detect character properties by Unicode block * [test] Reenabled ideographic breaking tests
Diffstat (limited to 'src/mbgl/text')
-rw-r--r--src/mbgl/text/glyph_set.cpp35
-rw-r--r--src/mbgl/text/glyph_set.hpp3
2 files changed, 20 insertions, 18 deletions
diff --git a/src/mbgl/text/glyph_set.cpp b/src/mbgl/text/glyph_set.cpp
index 0875a83850..c778de207b 100644
--- a/src/mbgl/text/glyph_set.cpp
+++ b/src/mbgl/text/glyph_set.cpp
@@ -1,6 +1,7 @@
#include <mbgl/text/glyph_set.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/math/minmax.hpp>
+#include <mbgl/util/i18n.hpp>
#include <cassert>
@@ -54,7 +55,8 @@ const Shaping GlyphSet::getShaping(const std::u32string &string, const float max
if (shaping.positionedGlyphs.empty())
return shaping;
- lineWrap(shaping, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate);
+ lineWrap(shaping, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate,
+ util::i18n::allowsIdeographicBreaking(string));
return shaping;
}
@@ -85,9 +87,10 @@ void justifyLine(std::vector<PositionedGlyph> &positionedGlyphs, const std::map<
}
}
-void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float maxWidth,
- const float horizontalAlign, const float verticalAlign,
- const float justify, const Point<float> &translate) const {
+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 {
uint32_t lastSafeBreak = 0;
uint32_t lengthBeforeCurrentLine = 0;
@@ -99,6 +102,12 @@ void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float ma
std::vector<PositionedGlyph> &positionedGlyphs = shaping.positionedGlyphs;
if (maxWidth) {
+ if (useBalancedIdeographicBreaking) {
+ auto lastPositionedGlyph = positionedGlyphs[positionedGlyphs.size() - 1];
+ uint32_t estimatedLineCount = std::fmax(1, std::ceil(lastPositionedGlyph.x / maxWidth));
+ maxWidth = lastPositionedGlyph.x / estimatedLineCount;
+ }
+
for (uint32_t i = 0; i < positionedGlyphs.size(); i++) {
PositionedGlyph &shape = positionedGlyphs[i];
@@ -119,8 +128,7 @@ void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float ma
// Collapse invisible characters.
uint32_t breakGlyph = positionedGlyphs[lastSafeBreak].glyph;
uint32_t lineEnd = lastSafeBreak;
- if (breakGlyph == 0x20 /* space */
- || breakGlyph == 0x200b /* zero-width space */) {
+ if (util::i18n::isVisible(breakGlyph)) {
lineEnd--;
}
@@ -133,17 +141,10 @@ void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float ma
line++;
}
- // Spaces, plus word-breaking punctuation that often appears without surrounding spaces.
- if (shape.glyph == 0x20 /* space */
- || shape.glyph == 0x26 /* ampersand */
- || shape.glyph == 0x2b /* plus sign */
- || shape.glyph == 0x2d /* hyphen-minus */
- || shape.glyph == 0x2f /* solidus */
- || shape.glyph == 0xad /* soft hyphen */
- || shape.glyph == 0xb7 /* middle dot */
- || shape.glyph == 0x200b /* zero-width space */
- || shape.glyph == 0x2010 /* hyphen */
- || shape.glyph == 0x2013 /* en dash */) {
+ // Ideographic characters, spaces, and word-breaking punctuation that often appear without surrounding spaces.
+ if (useBalancedIdeographicBreaking
+ || util::i18n::allowsWordBreaking(shape.glyph)
+ || util::i18n::allowsIdeographicBreaking(shape.glyph)) {
lastSafeBreak = i;
}
}
diff --git a/src/mbgl/text/glyph_set.hpp b/src/mbgl/text/glyph_set.hpp
index 37ffdb070a..fed7960a5f 100644
--- a/src/mbgl/text/glyph_set.hpp
+++ b/src/mbgl/text/glyph_set.hpp
@@ -13,7 +13,8 @@ public:
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) const;
+ float verticalAlign, float justify, const Point<float> &translate,
+ bool useBalancedIdeographicBreaking) const;
private:
std::map<uint32_t, SDFGlyph> sdfs;