summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-03-28 00:44:32 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-03-28 22:27:59 +0200
commit4e335d0b050c6d5b94ae0d28cb4fd36b939ad84b (patch)
tree55d8f2e17ba3d7083a648aed4aac9cb366da8bf7 /src
parent21155772ef086c949f951e32424c36b9dd7dc430 (diff)
downloadqtlocation-mapboxgl-4e335d0b050c6d5b94ae0d28cb4fd36b939ad84b.tar.gz
[core] Traverse expression tree when checking for property overrides
Before this change, symbol layer was only checking whether top level 'text-field' layout property expression is FormatExpression and if it has paint property overrides. This change takes into account that 'text-field' might have nested expressions, thus, requires traversal over child expressions. Fixes: #14254
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/style/expression/value.cpp5
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp62
2 files changed, 53 insertions, 14 deletions
diff --git a/src/mbgl/style/expression/value.cpp b/src/mbgl/style/expression/value.cpp
index 436ed83ecd..c2c2105336 100644
--- a/src/mbgl/style/expression/value.cpp
+++ b/src/mbgl/style/expression/value.cpp
@@ -166,6 +166,11 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
}
options.emplace("text-font", std::vector<mbgl::Value>{ std::string("literal"), fontStack });
}
+
+ if (section.textColor) {
+ options.emplace("text-color", fromExpressionValue(*section.textColor));
+ }
+
serialized.push_back(options);
}
return serialized;
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
index f937fccaa8..9b63e0e8d6 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.hpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -3,9 +3,11 @@
#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/literal.hpp>
#include <mbgl/style/expression/format_expression.hpp>
#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/style/expression/format_section_override.hpp>
+#include <mbgl/style/expression/value.hpp>
namespace mbgl {
namespace style {
@@ -56,25 +58,57 @@ struct FormatSectionOverrides<TypeList<PaintProperty...>> {
template<typename Property, typename FormattedProperty>
static bool hasOverride(const FormattedProperty& formatted) {
+
+ const auto checkLiteral = [] (const TextField::Type& literal) {
+ for (const auto& section : literal.sections) {
+ if (Property::hasOverride(section)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
return formatted.match(
- [] (const TextField::Type& t) {
- for (const auto& section : t.sections) {
- if (Property::hasOverride(section)) {
- return true;
- }
- }
- return false;
+ [&checkLiteral] (const TextField::Type& literal) {
+ return checkLiteral(literal);
},
- [] (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;
+ [&checkLiteral] (const PropertyExpression<TextField::Type>& property) {
+ bool expressionHasOverrides = false;
+ const auto checkExpression = [&](const expression::Expression& e) {
+ if (expressionHasOverrides) {
+ return;
+ }
+
+ if (e.getKind() == expression::Kind::Literal &&
+ e.getType() == expression::type::Formatted) {
+ const auto* literalExpr = static_cast<const expression::Literal*>(&e);
+ const auto formattedValue = expression::fromExpressionValue<expression::Formatted>(literalExpr->getValue());
+ if (formattedValue && checkLiteral(*formattedValue)) {
+ expressionHasOverrides = true;
+ }
+ return;
+ }
+
+ if (e.getKind() == expression::Kind::FormatExpression) {
+ const auto* formatExpr = static_cast<const expression::FormatExpression*>(&e);
+ for (const auto& section : formatExpr->getSections()) {
+ if (Property::hasOverride(section)) {
+ expressionHasOverrides = true;
+ break;
+ }
}
}
+ };
+
+ // Check root property expression and return early.
+ checkExpression(property.getExpression());
+ if (expressionHasOverrides) {
+ return true;
}
- return false;
+
+ // Traverse thru children and check whether any of them have overrides.
+ property.getExpression().eachChild(checkExpression);
+ return expressionHasOverrides;
},
[] (const auto&) {
return false;