diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-03-20 18:08:01 +0200 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2019-03-29 16:18:41 +0200 |
commit | b39c71eea805d0551608f97ad1f35525d0586b14 (patch) | |
tree | aec6480c147f560dd3e50025b283e0f705ee2ac2 /src/mbgl/text | |
parent | 9fc42b9c3ceef09a51686a29985ce70dd0a78f6d (diff) | |
download | qtlocation-mapboxgl-b39c71eea805d0551608f97ad1f35525d0586b14.tar.gz |
[core] Introduce variable text placement for point labels - Layout part
Diffstat (limited to 'src/mbgl/text')
-rw-r--r-- | src/mbgl/text/glyph.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/text/placement.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/text/placement.hpp | 12 | ||||
-rw-r--r-- | src/mbgl/text/quads.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/text/quads.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/text/shaping.cpp | 71 | ||||
-rw-r--r-- | src/mbgl/text/shaping.hpp | 15 |
7 files changed, 74 insertions, 50 deletions
diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp index c97b242c10..7d6415c057 100644 --- a/src/mbgl/text/glyph.hpp +++ b/src/mbgl/text/glyph.hpp @@ -78,15 +78,17 @@ enum class WritingModeType : uint8_t; class Shaping { public: - explicit Shaping() = default; - explicit Shaping(float x, float y, WritingModeType writingMode_) - : top(y), bottom(y), left(x), right(x), writingMode(writingMode_) {} + Shaping() = default; + explicit Shaping(float x, float y, WritingModeType writingMode_, std::size_t lineCount_) + : top(y), bottom(y), left(x), right(x), writingMode(writingMode_), lineCount(lineCount_) {} std::vector<PositionedGlyph> positionedGlyphs; float top = 0; float bottom = 0; float left = 0; float right = 0; WritingModeType writingMode; + std::size_t lineCount = 0u; + std::string text = {}; explicit operator bool() const { return !positionedGlyphs.empty(); } }; diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 4cc12b0980..bb7e2d1a6c 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -176,8 +176,8 @@ void Placement::placeLayerBucket( bool placeIcon = false; bool offscreen = true; - if (symbolInstance.placedTextIndex) { - PlacedSymbol& placedSymbol = bucket.text.placedSymbols.at(*symbolInstance.placedTextIndex); + if (symbolInstance.placedRightTextIndex) { + PlacedSymbol& placedSymbol = bucket.text.placedSymbols.at(*symbolInstance.placedRightTextIndex); const float fontSize = evaluateSizeForFeature(partiallyEvaluatedTextSize, placedSymbol); auto placed = collisionIndex.placeFeature(symbolInstance.textCollisionFeature, @@ -339,14 +339,15 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& if (symbolInstance.hasText) { auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity); - for (size_t i = 0; i < symbolInstance.horizontalGlyphQuads.size() * 4; i++) { + for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } for (size_t i = 0; i < symbolInstance.verticalGlyphQuads.size() * 4; i++) { bucket.text.opacityVertices.emplace_back(opacityVertex); } - if (symbolInstance.placedTextIndex) { - bucket.text.placedSymbols[*symbolInstance.placedTextIndex].hidden = opacityState.isHidden(); + if (symbolInstance.placedRightTextIndex) { + PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex]; + placed.hidden = opacityState.isHidden(); } if (symbolInstance.placedVerticalTextIndex) { bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden(); diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index cc23110e54..32310f723e 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -31,6 +31,16 @@ public: OpacityState text; }; +class VariableOffset { +public: + float radialOffset; + float width; + float height; + style::TextVariableAnchorType anchor; + float textBoxScale; + optional<style::TextVariableAnchorType> prevAnchor; +}; + class JointPlacement { public: JointPlacement(bool text_, bool icon_, bool skipFade_) @@ -45,7 +55,7 @@ public: // visible right away. const bool skipFade; }; - + struct RetainedQueryData { uint32_t bucketInstanceId; std::shared_ptr<FeatureIndex> featureIndex; diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index ec0045caad..6be5d8c01e 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -92,16 +92,12 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, } SymbolQuads getGlyphQuads(const Shaping& shapedText, + const std::array<float, 2> textOffset, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const GlyphPositions& positions) { const float textRotate = layout.get<TextRotate>() * util::DEG2RAD; - const float oneEm = 24.0; - std::array<float, 2> textOffset = layout.get<TextOffset>(); - textOffset[0] *= oneEm; - textOffset[1] *= oneEm; - SymbolQuads quads; for (const PositionedGlyph &positionedGlyph: shapedText.positionedGlyphs) { diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index f41a4fec66..0bb892e4d1 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -49,6 +49,7 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, const Shaping& shapedText); SymbolQuads getGlyphQuads(const Shaping& shapedText, + const std::array<float, 2> textOffset, const style::SymbolLayoutProperties::Evaluated&, style::SymbolPlacementType placement, const GlyphPositions& positions); diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 02dbf146e1..348c2ddccc 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -1,4 +1,5 @@ #include <mbgl/text/shaping.hpp> +#include <mbgl/util/constants.hpp> #include <mbgl/util/i18n.hpp> #include <mbgl/layout/symbol_feature.hpp> #include <mbgl/math/minmax.hpp> @@ -10,58 +11,61 @@ namespace mbgl { -struct AnchorAlignment { - AnchorAlignment(float horizontal_, float vertical_) - : horizontalAlign(horizontal_), verticalAlign(vertical_) { - } - - float horizontalAlign; - float verticalAlign; -}; -AnchorAlignment getAnchorAlignment(style::SymbolAnchorType anchor) { - float horizontalAlign = 0.5; - float verticalAlign = 0.5; +// static +AnchorAlignment AnchorAlignment::getAnchorAlignment(style::SymbolAnchorType anchor) { + AnchorAlignment result(0.5f, 0.5f); switch (anchor) { - case style::SymbolAnchorType::Top: - case style::SymbolAnchorType::Bottom: - case style::SymbolAnchorType::Center: - break; case style::SymbolAnchorType::Right: case style::SymbolAnchorType::TopRight: case style::SymbolAnchorType::BottomRight: - horizontalAlign = 1; + result.horizontalAlign = 1.0f; break; case style::SymbolAnchorType::Left: case style::SymbolAnchorType::TopLeft: case style::SymbolAnchorType::BottomLeft: - horizontalAlign = 0; + result.horizontalAlign = 0.0f; break; + default: + break; } switch (anchor) { - case style::SymbolAnchorType::Left: - case style::SymbolAnchorType::Right: - case style::SymbolAnchorType::Center: - break; case style::SymbolAnchorType::Bottom: case style::SymbolAnchorType::BottomLeft: case style::SymbolAnchorType::BottomRight: - verticalAlign = 1; + result.verticalAlign = 1.0f; break; case style::SymbolAnchorType::Top: case style::SymbolAnchorType::TopLeft: case style::SymbolAnchorType::TopRight: - verticalAlign = 0; + result.verticalAlign = 0.0f; + break; + default: break; } - return AnchorAlignment(horizontalAlign, verticalAlign); + return result; +} + +style::TextJustifyType getAnchorJustification(style::SymbolAnchorType anchor) { + switch (anchor) { + case style::SymbolAnchorType::Right: + case style::SymbolAnchorType::TopRight: + case style::SymbolAnchorType::BottomRight: + return style::TextJustifyType::Right; + case style::SymbolAnchorType::Left: + case style::SymbolAnchorType::TopLeft: + case style::SymbolAnchorType::BottomLeft: + return style::TextJustifyType::Left; + default: + return style::TextJustifyType::Center; + } } PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, style::SymbolAnchorType iconAnchor, const float iconRotation) { - AnchorAlignment anchorAlign = getAnchorAlignment(iconAnchor); + AnchorAlignment anchorAlign = AnchorAlignment::getAnchorAlignment(iconAnchor); float dx = iconOffset[0]; float dy = iconOffset[1]; float x1 = dx - image.displaySize()[0] * anchorAlign.horizontalAlign; @@ -269,7 +273,6 @@ void shapeLines(Shaping& shaping, const float lineHeight, const style::SymbolAnchorType textAnchor, const style::TextJustifyType textJustify, - const float verticalHeight, const WritingModeType writingMode, const GlyphMap& glyphMap) { @@ -314,7 +317,7 @@ void shapeLines(Shaping& shaping, // We don't know the baseline, but since we're laying out // at 24 points, we can calculate how much it will move when // we scale up or down. - const double baselineOffset = (lineMaxScale - section.scale) * 24; + const double baselineOffset = (lineMaxScale - section.scale) * util::ONE_EM; const Glyph& glyph = **it->second; @@ -323,7 +326,7 @@ void shapeLines(Shaping& shaping, x += glyph.metrics.advance * section.scale + spacing; } else { shaping.positionedGlyphs.emplace_back(codePoint, x, baselineOffset, true, section.fontStackHash, section.scale, sectionIndex); - x += verticalHeight * section.scale + spacing; + x += util::ONE_EM * section.scale + spacing; } } @@ -340,7 +343,7 @@ void shapeLines(Shaping& shaping, y += lineHeight * lineMaxScale; } - auto anchorAlign = getAnchorAlignment(textAnchor); + auto anchorAlign = AnchorAlignment::getAnchorAlignment(textAnchor); align(shaping, justify, anchorAlign.horizontalAlign, anchorAlign.verticalAlign, maxLineLength, lineHeight, lines.size()); @@ -360,12 +363,10 @@ const Shaping getShaping(const TaggedString& formattedString, const style::TextJustifyType textJustify, const float spacing, const Point<float>& translate, - const float verticalHeight, + //const float verticalHeight, const WritingModeType writingMode, BiDi& bidi, - const GlyphMap& glyphs) { - Shaping shaping(translate.x, translate.y, writingMode); - + const GlyphMap& glyphs) { std::vector<TaggedString> reorderedLines; if (formattedString.sectionCount() == 1) { auto untaggedLines = bidi.processText(formattedString.rawText(), @@ -380,9 +381,9 @@ const Shaping getShaping(const TaggedString& formattedString, reorderedLines.emplace_back(line, formattedString.getSections()); } } - + Shaping shaping(translate.x, translate.y, writingMode, reorderedLines.size()); shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor, - textJustify, verticalHeight, writingMode, glyphs); + textJustify, writingMode, glyphs); return shaping; } diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index 50ac893098..766b1ce233 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -7,6 +7,20 @@ namespace mbgl { +struct AnchorAlignment { + AnchorAlignment(float horizontal, float vertical) + : horizontalAlign(horizontal), verticalAlign(vertical) { + } + + static AnchorAlignment getAnchorAlignment(style::SymbolAnchorType anchor); + + float horizontalAlign; + float verticalAlign; +}; + +// Choose the justification that matches the direction of the TextAnchor +style::TextJustifyType getAnchorJustification(style::SymbolAnchorType anchor); + class SymbolFeature; class BiDi; @@ -53,7 +67,6 @@ const Shaping getShaping(const TaggedString& string, style::TextJustifyType textJustify, float spacing, const Point<float>& translate, - float verticalHeight, const WritingModeType, BiDi& bidi, const GlyphMap& glyphs); |