summaryrefslogtreecommitdiff
path: root/src/mbgl/style/layers
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/layers')
-rw-r--r--src/mbgl/style/layers/layer_properties.hpp.ejs5
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp15
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp98
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp5
4 files changed, 118 insertions, 5 deletions
diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs
index 792f858862..89dffdcd42 100644
--- a/src/mbgl/style/layers/layer_properties.hpp.ejs
+++ b/src/mbgl/style/layers/layer_properties.hpp.ejs
@@ -31,6 +31,11 @@ struct <%- camelize(property.name) %> : ColorRampProperty {
<% } else { -%>
struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> {
static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+<% if (isOverridable(property)) { -%>
+ static constexpr const char *name() { return "<%- property.name %>"; }
+ static constexpr auto expressionType() { return expression::type::<%- expressionType(property) %>{}; };
+ template<typename T> static bool hasOverride(const T& t) { return !!t.<%- camelizeWithLeadingLowercase(property.name) %>; };
+<% } -%>
};
<% } -%>
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
index 3dd1da1136..e35e7b0b9f 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.cpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -1,17 +1,24 @@
#include <mbgl/style/layers/symbol_layer_impl.hpp>
-
#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
+bool SymbolLayer::Impl::hasFormatSectionOverrides() const {
+ if (!hasFormatSectionOverrides_) {
+ hasFormatSectionOverrides_ = SymbolLayerPaintPropertyOverrides::hasOverrides(layout.get<TextField>());
+ }
+ return *hasFormatSectionOverrides_;
+}
+
bool SymbolLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const {
assert(other.getTypeInfo() == getTypeInfo());
const auto& impl = static_cast<const style::SymbolLayer::Impl&>(other);
return filter != impl.filter ||
visibility != impl.visibility ||
layout != impl.layout ||
- paint.hasDataDrivenPropertyDifference(impl.paint);
+ paint.hasDataDrivenPropertyDifference(impl.paint) ||
+ (hasFormatSectionOverrides() && SymbolLayerPaintPropertyOverrides::hasPaintPropertyDifference(paint, impl.paint));
}
void SymbolLayer::Impl::populateFontStack(std::set<FontStack>& fontStack) const {
@@ -20,10 +27,10 @@ void SymbolLayer::Impl::populateFontStack(std::set<FontStack>& fontStack) const
}
layout.get<TextFont>().match(
- [&] (Undefined) {
+ [&fontStack] (Undefined) {
fontStack.insert({"Open Sans Regular", "Arial Unicode MS Regular"});
},
- [&] (const FontStack& constant) {
+ [&fontStack] (const FontStack& constant) {
fontStack.insert(constant);
},
[&] (const auto& function) {
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
index a5b0332f6c..f937fccaa8 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.hpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -3,10 +3,104 @@
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
+#include <mbgl/style/expression/format_expression.hpp>
+#include <mbgl/style/expression/formatted.hpp>
+#include <mbgl/style/expression/format_section_override.hpp>
namespace mbgl {
namespace style {
+template<typename PaintProperty>
+struct FormatSectionOverrides;
+
+template<typename... PaintProperty>
+struct FormatSectionOverrides<TypeList<PaintProperty...>> {
+ template<typename Property, typename T, typename U>
+ static void setOverride(const T& overrides, U& overridable) {
+ if (hasOverride<Property>(overrides.template get<TextField>())) {
+ auto override =
+ std::make_unique<expression::FormatSectionOverride<typename Property::Type>>(Property::expressionType(),
+ std::move(overridable.template get<Property>()),
+ Property::name());
+ PropertyExpression<typename Property::Type> expr(std::move(override));
+ overridable.template get<Property>() = PossiblyEvaluatedPropertyValue<typename Property::Type>(std::move(expr));
+ }
+ }
+
+ template<typename T, typename U>
+ static void setOverrides(const T& overrides, U& overridable) {
+ util::ignore({(setOverride<PaintProperty>(overrides, overridable), 0)...});
+ }
+
+ template<typename Property, typename T, typename U>
+ static void updateOverride(T& evaluated, U& updated) {
+ auto property = evaluated.template get<Property>();
+ if (!property.isConstant()) {
+ const bool hasFormatSectionOverride = property.match(
+ [] (const style::PropertyExpression<typename Property::Type>& e) {
+ return e.getExpression().getKind() == expression::Kind::FormatSectionOverride;
+ },
+ [] (const auto&) {
+ return false;
+ });
+ if (hasFormatSectionOverride) {
+ updated.template get<Property>() = std::move(property);
+ }
+ }
+ }
+
+ template<typename T, typename U>
+ static void updateOverrides(T& evaluated, U& updated) {
+ util::ignore({(updateOverride<PaintProperty>(evaluated, updated), 0)...});
+ }
+
+ template<typename Property, typename FormattedProperty>
+ static bool hasOverride(const FormattedProperty& formatted) {
+ return formatted.match(
+ [] (const TextField::Type& t) {
+ for (const auto& section : t.sections) {
+ if (Property::hasOverride(section)) {
+ return true;
+ }
+ }
+ return false;
+ },
+ [] (const PropertyExpression<TextField::Type>& t) {
+ if (t.getExpression().getKind() == expression::Kind::FormatExpression) {
+ const auto* e = static_cast<const expression::FormatExpression*>(&t.getExpression());
+ for (const auto& section : e->getSections()) {
+ if (Property::hasOverride(section)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ [] (const auto&) {
+ return false;
+ }
+ );
+ }
+
+ template <typename FormattedProperty>
+ static bool hasOverrides(const FormattedProperty& formatted) {
+ bool result = false;
+ util::ignore({ (result |= hasOverride<PaintProperty>(formatted))... });
+ return result;
+ }
+
+ template <typename PaintProperties>
+ static bool hasPaintPropertyDifference(const PaintProperties& lhs, const PaintProperties& rhs) {
+ bool result = false;
+ util::ignore({ (result |= lhs.template get<PaintProperty>().value.isConstant() &&
+ rhs.template get<PaintProperty>().value.isConstant() &&
+ (lhs.template get<PaintProperty>().value.asConstant() != rhs.template get<PaintProperty>().value.asConstant()))... });
+ return result;
+ }
+};
+
+using SymbolLayerPaintPropertyOverrides = FormatSectionOverrides<SymbolPaintProperties::OverridableProperties>;
+
class SymbolLayer::Impl : public Layer::Impl {
public:
using Layer::Impl::Impl;
@@ -19,6 +113,10 @@ public:
SymbolPaintProperties::Transitionable paint;
DECLARE_LAYER_TYPE_INFO;
+
+private:
+ bool hasFormatSectionOverrides() const;
+ mutable optional<bool> hasFormatSectionOverrides_;
};
} // namespace style
diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp
index d5bdce1f5d..c352ab8e77 100644
--- a/src/mbgl/style/layers/symbol_layer_properties.hpp
+++ b/src/mbgl/style/layers/symbol_layer_properties.hpp
@@ -229,8 +229,11 @@ struct TextOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, unifo
static float defaultValue() { return 1; }
};
-struct TextColor : DataDrivenPaintProperty<Color, attributes::a_fill_color, uniforms::u_fill_color> {
+struct TextColor : DataDrivenPaintProperty<Color, attributes::a_fill_color, uniforms::u_fill_color, true> {
static Color defaultValue() { return Color::black(); }
+ static constexpr const char *name() { return "text-color"; }
+ static constexpr auto expressionType() { return expression::type::ColorType{}; };
+ template<typename T> static bool hasOverride(const T& t) { return !!t.textColor; };
};
struct TextHaloColor : DataDrivenPaintProperty<Color, attributes::a_halo_color, uniforms::u_halo_color> {