summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
authorLauren Budorick <lauren@mapbox.com>2017-08-28 13:32:56 -0700
committerGitHub <noreply@github.com>2017-08-28 13:32:56 -0700
commit2de89a99bc86776c8cadedc0ae9b344fb78b8217 (patch)
treee930ceb8436646e0d6747f2b3e805bd640f2a436 /src/mbgl
parentc6ab20e5c69c3705422e49c3511faf3e5ab79b05 (diff)
downloadqtlocation-mapboxgl-2de89a99bc86776c8cadedc0ae9b344fb78b8217.tar.gz
Implement icon-anchor property
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/layout/symbol_layout.cpp1
-rw-r--r--src/mbgl/style/function/categorical_stops.cpp2
-rw-r--r--src/mbgl/style/function/identity_stops.cpp4
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp22
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp10
-rw-r--r--src/mbgl/style/types.cpp20
-rw-r--r--src/mbgl/text/shaping.cpp106
-rw-r--r--src/mbgl/text/shaping.hpp7
8 files changed, 107 insertions, 65 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 229b8f2ee2..adb8ce5927 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -233,6 +233,7 @@ void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyph
shapedIcon = PositionedIcon::shapeIcon(
imagePositions.at(*feature.icon),
layout.evaluate<IconOffset>(zoom, feature),
+ layout.evaluate<IconAnchor>(zoom, feature),
layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD);
if (image->second->sdf) {
sdfIcons = true;
diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp
index 1a30a1f1c7..dd179f5376 100644
--- a/src/mbgl/style/function/categorical_stops.cpp
+++ b/src/mbgl/style/function/categorical_stops.cpp
@@ -34,7 +34,7 @@ template class CategoricalStops<std::array<float, 2>>;
template class CategoricalStops<std::string>;
template class CategoricalStops<TextTransformType>;
template class CategoricalStops<TextJustifyType>;
-template class CategoricalStops<TextAnchorType>;
+template class CategoricalStops<SymbolAnchorType>;
template class CategoricalStops<LineJoinType>;
} // namespace style
diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp
index 7815f4aca0..0ac6fda846 100644
--- a/src/mbgl/style/function/identity_stops.cpp
+++ b/src/mbgl/style/function/identity_stops.cpp
@@ -50,12 +50,12 @@ optional<TextJustifyType> IdentityStops<TextJustifyType>::evaluate(const Value&
}
template <>
-optional<TextAnchorType> IdentityStops<TextAnchorType>::evaluate(const Value& value) const {
+optional<SymbolAnchorType> IdentityStops<SymbolAnchorType>::evaluate(const Value& value) const {
if (!value.is<std::string>()) {
return {};
}
- return Enum<TextAnchorType>::toEnum(value.get<std::string>());
+ return Enum<SymbolAnchorType>::toEnum(value.get<std::string>());
}
template <>
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index 803ae7397e..2b86b26025 100644
--- a/src/mbgl/style/layers/symbol_layer.cpp
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -332,6 +332,22 @@ void SymbolLayer::setIconOffset(DataDrivenPropertyValue<std::array<float, 2>> va
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
+DataDrivenPropertyValue<SymbolAnchorType> SymbolLayer::getDefaultIconAnchor() {
+ return IconAnchor::defaultValue();
+}
+
+DataDrivenPropertyValue<SymbolAnchorType> SymbolLayer::getIconAnchor() const {
+ return impl().layout.get<IconAnchor>();
+}
+
+void SymbolLayer::setIconAnchor(DataDrivenPropertyValue<SymbolAnchorType> value) {
+ if (value == getIconAnchor())
+ return;
+ auto impl_ = mutableImpl();
+ impl_->layout.get<IconAnchor>() = value;
+ baseImpl = std::move(impl_);
+ observer->onLayerChanged(*this);
+}
PropertyValue<AlignmentType> SymbolLayer::getDefaultIconPitchAlignment() {
return IconPitchAlignment::defaultValue();
}
@@ -492,15 +508,15 @@ void SymbolLayer::setTextJustify(DataDrivenPropertyValue<TextJustifyType> value)
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
-DataDrivenPropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() {
+DataDrivenPropertyValue<SymbolAnchorType> SymbolLayer::getDefaultTextAnchor() {
return TextAnchor::defaultValue();
}
-DataDrivenPropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const {
+DataDrivenPropertyValue<SymbolAnchorType> SymbolLayer::getTextAnchor() const {
return impl().layout.get<TextAnchor>();
}
-void SymbolLayer::setTextAnchor(DataDrivenPropertyValue<TextAnchorType> value) {
+void SymbolLayer::setTextAnchor(DataDrivenPropertyValue<SymbolAnchorType> value) {
if (value == getTextAnchor())
return;
auto impl_ = mutableImpl();
diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp
index fe6ab38e92..0d163b9fb9 100644
--- a/src/mbgl/style/layers/symbol_layer_properties.hpp
+++ b/src/mbgl/style/layers/symbol_layer_properties.hpp
@@ -87,6 +87,11 @@ struct IconOffset : DataDrivenLayoutProperty<std::array<float, 2>> {
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
};
+struct IconAnchor : DataDrivenLayoutProperty<SymbolAnchorType> {
+ static constexpr const char * key = "icon-anchor";
+ static SymbolAnchorType defaultValue() { return SymbolAnchorType::Center; }
+};
+
struct IconPitchAlignment : LayoutProperty<AlignmentType> {
static constexpr const char * key = "icon-pitch-alignment";
static AlignmentType defaultValue() { return AlignmentType::Auto; }
@@ -137,9 +142,9 @@ struct TextJustify : DataDrivenLayoutProperty<TextJustifyType> {
static TextJustifyType defaultValue() { return TextJustifyType::Center; }
};
-struct TextAnchor : DataDrivenLayoutProperty<TextAnchorType> {
+struct TextAnchor : DataDrivenLayoutProperty<SymbolAnchorType> {
static constexpr const char * key = "text-anchor";
- static TextAnchorType defaultValue() { return TextAnchorType::Center; }
+ static SymbolAnchorType defaultValue() { return SymbolAnchorType::Center; }
};
struct TextMaxAngle : LayoutProperty<float> {
@@ -259,6 +264,7 @@ class SymbolLayoutProperties : public Properties<
IconPadding,
IconKeepUpright,
IconOffset,
+ IconAnchor,
IconPitchAlignment,
TextPitchAlignment,
TextRotationAlignment,
diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp
index 4fbf767e11..0a1781e01b 100644
--- a/src/mbgl/style/types.cpp
+++ b/src/mbgl/style/types.cpp
@@ -53,16 +53,16 @@ MBGL_DEFINE_ENUM(SymbolPlacementType, {
{ SymbolPlacementType::Line, "line" },
});
-MBGL_DEFINE_ENUM(TextAnchorType, {
- { TextAnchorType::Center, "center" },
- { TextAnchorType::Left, "left" },
- { TextAnchorType::Right, "right" },
- { TextAnchorType::Top, "top" },
- { TextAnchorType::Bottom, "bottom" },
- { TextAnchorType::TopLeft, "top-left" },
- { TextAnchorType::TopRight, "top-right" },
- { TextAnchorType::BottomLeft, "bottom-left" },
- { TextAnchorType::BottomRight, "bottom-right" }
+MBGL_DEFINE_ENUM(SymbolAnchorType, {
+ { SymbolAnchorType::Center, "center" },
+ { SymbolAnchorType::Left, "left" },
+ { SymbolAnchorType::Right, "right" },
+ { SymbolAnchorType::Top, "top" },
+ { SymbolAnchorType::Bottom, "bottom" },
+ { SymbolAnchorType::TopLeft, "top-left" },
+ { SymbolAnchorType::TopRight, "top-right" },
+ { SymbolAnchorType::BottomLeft, "bottom-left" },
+ { SymbolAnchorType::BottomRight, "bottom-right" }
});
MBGL_DEFINE_ENUM(TextJustifyType, {
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index a40ef0cf39..5d688ea539 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -11,12 +11,63 @@
namespace mbgl {
-PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, const float iconRotation) {
+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;
+
+ 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;
+ break;
+ case style::SymbolAnchorType::Left:
+ case style::SymbolAnchorType::TopLeft:
+ case style::SymbolAnchorType::BottomLeft:
+ horizontalAlign = 0;
+ 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;
+ break;
+ case style::SymbolAnchorType::Top:
+ case style::SymbolAnchorType::TopLeft:
+ case style::SymbolAnchorType::TopRight:
+ verticalAlign = 0;
+ break;
+ }
+
+ return AnchorAlignment(horizontalAlign, verticalAlign);
+}
+
+PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, style::SymbolAnchorType iconAnchor, const float iconRotation) {
+ AnchorAlignment anchorAlign = getAnchorAlignment(iconAnchor);
float dx = iconOffset[0];
float dy = iconOffset[1];
- float x1 = dx - image.displaySize()[0] / 2.0f;
+ float x1 = dx - image.displaySize()[0] * anchorAlign.horizontalAlign;
float x2 = x1 + image.displaySize()[0];
- float y1 = dy - image.displaySize()[1] / 2.0f;
+ float y1 = dy - image.displaySize()[1] * anchorAlign.verticalAlign;
float y2 = y1 + image.displaySize()[1];
return PositionedIcon { image, y1, y2, x1, x2, iconRotation };
@@ -200,7 +251,7 @@ void shapeLines(Shaping& shaping,
const std::vector<std::u16string>& lines,
const float spacing,
const float lineHeight,
- const style::TextAnchorType textAnchor,
+ const style::SymbolAnchorType textAnchor,
const style::TextJustifyType textJustify,
const float verticalHeight,
const WritingModeType writingMode,
@@ -258,58 +309,23 @@ void shapeLines(Shaping& shaping,
y += lineHeight;
}
- float horizontalAlign = 0.5;
- float verticalAlign = 0.5;
-
- switch (textAnchor) {
- case style::TextAnchorType::Top:
- case style::TextAnchorType::Bottom:
- case style::TextAnchorType::Center:
- break;
- case style::TextAnchorType::Right:
- case style::TextAnchorType::TopRight:
- case style::TextAnchorType::BottomRight:
- horizontalAlign = 1;
- break;
- case style::TextAnchorType::Left:
- case style::TextAnchorType::TopLeft:
- case style::TextAnchorType::BottomLeft:
- horizontalAlign = 0;
- break;
- }
-
- switch (textAnchor) {
- case style::TextAnchorType::Left:
- case style::TextAnchorType::Right:
- case style::TextAnchorType::Center:
- break;
- case style::TextAnchorType::Bottom:
- case style::TextAnchorType::BottomLeft:
- case style::TextAnchorType::BottomRight:
- verticalAlign = 1;
- break;
- case style::TextAnchorType::Top:
- case style::TextAnchorType::TopLeft:
- case style::TextAnchorType::TopRight:
- verticalAlign = 0;
- break;
- }
+ auto anchorAlign = getAnchorAlignment(textAnchor);
- align(shaping, justify, horizontalAlign, verticalAlign,
- maxLineLength, lineHeight, lines.size());
+ align(shaping, justify, anchorAlign.horizontalAlign, anchorAlign.verticalAlign, maxLineLength,
+ lineHeight, lines.size());
const uint32_t height = lines.size() * lineHeight;
// Calculate the bounding box
- shaping.top += -verticalAlign * height;
+ shaping.top += -anchorAlign.verticalAlign * height;
shaping.bottom = shaping.top + height;
- shaping.left += -horizontalAlign * maxLineLength;
+ shaping.left += -anchorAlign.horizontalAlign * maxLineLength;
shaping.right = shaping.left + maxLineLength;
}
const Shaping getShaping(const std::u16string& logicalInput,
const float maxWidth,
const float lineHeight,
- const style::TextAnchorType textAnchor,
+ const style::SymbolAnchorType textAnchor,
const style::TextJustifyType textJustify,
const float spacing,
const Point<float>& translate,
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index 00e4ec55f8..0a961849e5 100644
--- a/src/mbgl/text/shaping.hpp
+++ b/src/mbgl/text/shaping.hpp
@@ -32,7 +32,10 @@ private:
float _angle;
public:
- static PositionedIcon shapeIcon(const ImagePosition&, const std::array<float, 2>& iconOffset, const float iconRotation);
+ static PositionedIcon shapeIcon(const ImagePosition&,
+ const std::array<float, 2>& iconOffset,
+ style::SymbolAnchorType iconAnchor,
+ const float iconRotation);
const ImagePosition& image() const { return _image; }
float top() const { return _top; }
@@ -45,7 +48,7 @@ public:
const Shaping getShaping(const std::u16string& string,
float maxWidth,
float lineHeight,
- style::TextAnchorType textAnchor,
+ style::SymbolAnchorType textAnchor,
style::TextJustifyType textJustify,
float spacing,
const Point<float>& translate,