From fd2b525c4d196520abaf9f347d3a73c37b47bd61 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Mon, 14 Aug 2017 15:33:19 -0700 Subject: [core] Correct x-offset introduced by vertical glyph rotation Fixes issue#9768. Port of GL JS PR #5100. --- mapbox-gl-js | 2 +- src/mbgl/text/glyph.hpp | 6 +++--- src/mbgl/text/quads.cpp | 23 ++++++++++++++++------- src/mbgl/text/shaping.cpp | 4 ++-- test/text/quads.test.cpp | 2 +- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index 94ded74b15..f13860935a 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 94ded74b1562ac0adba97ab80fb8eae970ad2473 +Subproject commit f13860935a183bfaa9ef28bb88946b5843c2faa3 diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp index 19ecdfd17c..6cccb72ebe 100644 --- a/src/mbgl/text/glyph.hpp +++ b/src/mbgl/text/glyph.hpp @@ -58,13 +58,13 @@ using GlyphMap = std::map; class PositionedGlyph { public: - explicit PositionedGlyph(GlyphID glyph_, float x_, float y_, float angle_) - : glyph(glyph_), x(x_), y(y_), angle(angle_) {} + explicit PositionedGlyph(GlyphID glyph_, float x_, float y_, bool vertical_) + : glyph(glyph_), x(x_), y(y_), vertical(vertical_) {} GlyphID glyph = 0; float x = 0; float y = 0; - float angle = 0; + bool vertical = false; }; enum class WritingModeType : uint8_t; diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 7908ea4abc..0014ae8d01 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -133,18 +133,27 @@ SymbolQuads getGlyphQuads(const Shaping& shapedText, const float x2 = x1 + rect.w; const float y2 = y1 + rect.h; - const Point center{builtInOffset.x - halfAdvance, static_cast(static_cast(glyph.metrics.advance) / 2.0)}; - Point tl{x1, y1}; Point tr{x2, y1}; Point bl{x1, y2}; Point br{x2, y2}; - if (positionedGlyph.angle != 0) { - tl = util::rotate(tl - center, positionedGlyph.angle) + center; - tr = util::rotate(tr - center, positionedGlyph.angle) + center; - bl = util::rotate(bl - center, positionedGlyph.angle) + center; - br = util::rotate(br - center, positionedGlyph.angle) + center; + if (alongLine && positionedGlyph.vertical) { + // Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em) + // In horizontal orientation, the y values for glyphs are below the midline + // and we use a "yOffset" of -17 to pull them up to the middle. + // By rotating counter-clockwise around the point at the center of the left + // edge of a 24x24 layout box centered below the midline, we align the center + // of the glyphs with the horizontal midline, so the yOffset is no longer + // necessary, but we also pull the glyph to the left along the x axis + const Point center{-halfAdvance, halfAdvance}; + const float verticalRotation = -M_PI_2; + const Point xOffsetCorrection{5, 0}; + + tl = util::rotate(tl - center, verticalRotation) + center + xOffsetCorrection; + tr = util::rotate(tr - center, verticalRotation) + center + xOffsetCorrection; + bl = util::rotate(bl - center, verticalRotation) + center + xOffsetCorrection; + br = util::rotate(br - center, verticalRotation) + center + xOffsetCorrection; } if (textRotate) { diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 4a206e9bae..a40ef0cf39 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -237,10 +237,10 @@ void shapeLines(Shaping& shaping, const Glyph& glyph = **it->second; if (writingMode == WritingModeType::Horizontal || !util::i18n::hasUprightVerticalOrientation(chr)) { - shaping.positionedGlyphs.emplace_back(chr, x, y, 0); + shaping.positionedGlyphs.emplace_back(chr, x, y, false); x += glyph.metrics.advance + spacing; } else { - shaping.positionedGlyphs.emplace_back(chr, x, 0, -M_PI_2); + shaping.positionedGlyphs.emplace_back(chr, x, 0, true); x += verticalHeight + spacing; } } diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp index 682ba9d795..c4c1a7ac15 100644 --- a/test/text/quads.test.cpp +++ b/test/text/quads.test.cpp @@ -50,7 +50,7 @@ TEST(getIconQuads, style) { shapedText.bottom = 30.0f; shapedText.left = -60.0f; shapedText.right = 20.0f; - shapedText.positionedGlyphs.emplace_back(PositionedGlyph(32, 0.0f, 0.0f, 0)); + shapedText.positionedGlyphs.emplace_back(PositionedGlyph(32, 0.0f, 0.0f, false)); // none { -- cgit v1.2.1