summaryrefslogtreecommitdiff
path: root/src/mbgl/text
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-03-20 18:08:01 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-03-29 16:18:41 +0200
commitb39c71eea805d0551608f97ad1f35525d0586b14 (patch)
treeaec6480c147f560dd3e50025b283e0f705ee2ac2 /src/mbgl/text
parent9fc42b9c3ceef09a51686a29985ce70dd0a78f6d (diff)
downloadqtlocation-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.hpp8
-rw-r--r--src/mbgl/text/placement.cpp11
-rw-r--r--src/mbgl/text/placement.hpp12
-rw-r--r--src/mbgl/text/quads.cpp6
-rw-r--r--src/mbgl/text/quads.hpp1
-rw-r--r--src/mbgl/text/shaping.cpp71
-rw-r--r--src/mbgl/text/shaping.hpp15
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);