summaryrefslogtreecommitdiff
path: root/include/mbgl
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2018-10-02 17:03:50 -0700
committerChris Loer <chris.loer@mapbox.com>2018-10-15 13:15:46 -0700
commitce76bde13d0f4381ee861f81daf636defaff0bc5 (patch)
treee37d93d14fc64620069bac5488bae871af2fa431 /include/mbgl
parentbc718257748f1ad87658e85f8c31b574afca57a9 (diff)
downloadqtlocation-mapboxgl-ce76bde13d0f4381ee861f81daf636defaff0bc5.tar.gz
[core] Initial implementation of 'format' expression
Diffstat (limited to 'include/mbgl')
-rw-r--r--include/mbgl/style/conversion/function.hpp1
-rw-r--r--include/mbgl/style/conversion/property_value.hpp11
-rw-r--r--include/mbgl/style/expression/coercion.hpp7
-rw-r--r--include/mbgl/style/expression/expression.hpp1
-rw-r--r--include/mbgl/style/expression/format_expression.hpp52
-rw-r--r--include/mbgl/style/expression/formatted.hpp62
-rw-r--r--include/mbgl/style/expression/type.hpp9
-rw-r--r--include/mbgl/style/expression/value.hpp2
-rw-r--r--include/mbgl/style/layers/background_layer.hpp1
-rw-r--r--include/mbgl/style/layers/circle_layer.hpp1
-rw-r--r--include/mbgl/style/layers/fill_extrusion_layer.hpp1
-rw-r--r--include/mbgl/style/layers/fill_layer.hpp1
-rw-r--r--include/mbgl/style/layers/heatmap_layer.hpp1
-rw-r--r--include/mbgl/style/layers/hillshade_layer.hpp1
-rw-r--r--include/mbgl/style/layers/layer.hpp.ejs1
-rw-r--r--include/mbgl/style/layers/line_layer.hpp1
-rw-r--r--include/mbgl/style/layers/raster_layer.hpp1
-rw-r--r--include/mbgl/style/layers/symbol_layer.hpp7
-rw-r--r--include/mbgl/util/font_stack.hpp5
19 files changed, 156 insertions, 10 deletions
diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp
index ba9acd7a3b..47ce6843b5 100644
--- a/include/mbgl/style/conversion/function.hpp
+++ b/include/mbgl/style/conversion/function.hpp
@@ -11,6 +11,7 @@ namespace style {
namespace conversion {
bool hasTokens(const std::string&);
+std::unique_ptr<expression::Expression> convertTokenStringToFormatExpression(const std::string&);
std::unique_ptr<expression::Expression> convertTokenStringToExpression(const std::string&);
optional<std::unique_ptr<expression::Expression>> convertFunctionToExpression(expression::type::Type, const Convertible&, Error&, bool convertTokens);
diff --git a/include/mbgl/style/conversion/property_value.hpp b/include/mbgl/style/conversion/property_value.hpp
index f6f36db983..9d619f7a02 100644
--- a/include/mbgl/style/conversion/property_value.hpp
+++ b/include/mbgl/style/conversion/property_value.hpp
@@ -28,6 +28,17 @@ struct Converter<PropertyValue<T>> {
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToExpression(t)))
: PropertyValue<T>(t);
}
+
+ PropertyValue<T> maybeConvertTokens(const expression::Formatted& t) const {
+ // This only works with a single-section `Formatted` created automatically
+ // by parsing a plain-text `text-field` property.
+ // Token conversion happens later than the initial string->Formatted conversion
+ // General purpose `format` expressions with embedded tokens are not supported
+ const std::string& firstUnformattedSection = t.sections[0].text;
+ return hasTokens(firstUnformattedSection)
+ ? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToFormatExpression(firstUnformattedSection)))
+ : PropertyValue<T>(t);
+ }
};
} // namespace conversion
diff --git a/include/mbgl/style/expression/coercion.hpp b/include/mbgl/style/expression/coercion.hpp
index d83bd6dfa7..28c2c0c679 100644
--- a/include/mbgl/style/expression/coercion.hpp
+++ b/include/mbgl/style/expression/coercion.hpp
@@ -10,11 +10,6 @@ namespace mbgl {
namespace style {
namespace expression {
-/**
- * Special form for error-coalescing coercion expressions "to-number",
- * "to-color". Since these coercions can fail at runtime, they accept multiple
- * arguments, only evaluating one at a time until one succeeds.
- */
class Coercion : public Expression {
public:
Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_);
@@ -23,6 +18,8 @@ public:
EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;
+
+ mbgl::Value serialize() const override;
bool operator==(const Expression& e) const override;
diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp
index ce02c4114b..97b143b3d9 100644
--- a/include/mbgl/style/expression/expression.hpp
+++ b/include/mbgl/style/expression/expression.hpp
@@ -133,6 +133,7 @@ enum class Kind : int32_t {
Any,
All,
Comparison,
+ FormatExpression,
};
class Expression {
diff --git a/include/mbgl/style/expression/format_expression.hpp b/include/mbgl/style/expression/format_expression.hpp
new file mode 100644
index 0000000000..b00674a88e
--- /dev/null
+++ b/include/mbgl/style/expression/format_expression.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/formatted.hpp>
+#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/conversion.hpp>
+
+#include <memory>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+struct FormatExpressionSection {
+ FormatExpressionSection(std::unique_ptr<Expression> text_,
+ optional<std::unique_ptr<Expression>> fontScale_,
+ optional<std::unique_ptr<Expression>> textFont_);
+
+ std::shared_ptr<Expression> text;
+ optional<std::shared_ptr<Expression>> fontScale;
+ optional<std::shared_ptr<Expression>> textFont;
+};
+
+class FormatExpression : public Expression {
+public:
+ FormatExpression(std::vector<FormatExpressionSection> sections);
+
+ EvaluationResult evaluate(const EvaluationContext&) const override;
+ static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
+
+ void eachChild(const std::function<void(const Expression&)>&) const override;
+
+ bool operator==(const Expression& e) const override;
+
+ std::vector<optional<Value>> possibleOutputs() const override {
+ // Technically the combinatoric set of all children
+ // Usually, this.text will be undefined anyway
+ return { nullopt };
+ }
+
+ mbgl::Value serialize() const override;
+ std::string getOperator() const override { return "format"; }
+private:
+ std::vector<FormatExpressionSection> sections;
+ std::unique_ptr<Expression> text;
+ optional<std::unique_ptr<Expression>> fontScale;
+ optional<std::unique_ptr<Expression>> textFont;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/formatted.hpp b/include/mbgl/style/expression/formatted.hpp
new file mode 100644
index 0000000000..9e7e7308cb
--- /dev/null
+++ b/include/mbgl/style/expression/formatted.hpp
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/util/font_stack.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/variant.hpp>
+
+#include <vector>
+#include <string>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+struct FormattedSection {
+ FormattedSection(std::string text_, optional<double> fontScale_, optional<FontStack> fontStack_)
+ : text(std::move(text_))
+ , fontScale(std::move(fontScale_))
+ , fontStack(std::move(fontStack_))
+ {}
+ std::string text;
+ optional<double> fontScale;
+ optional<FontStack> fontStack;
+};
+
+class Formatted {
+public:
+ Formatted() = default;
+
+ Formatted(const char* plainU8String) {
+ sections.emplace_back(std::string(plainU8String), nullopt, nullopt);
+ }
+
+ Formatted(std::vector<FormattedSection> sections_)
+ : sections(std::move(sections_))
+ {}
+
+ bool operator==(const Formatted& ) const;
+
+ std::string toString() const;
+
+ bool empty() const {
+ return sections.empty() || sections.at(0).text.empty();
+ }
+
+ std::vector<FormattedSection> sections;
+};
+
+} // namespace expression
+
+namespace conversion {
+
+template <>
+struct Converter<mbgl::style::expression::Formatted> {
+public:
+ optional<mbgl::style::expression::Formatted> operator()(const Convertible& value, Error& error) const;
+};
+
+} // namespace conversion
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/type.hpp b/include/mbgl/style/expression/type.hpp
index 316496839b..a5a1e76164 100644
--- a/include/mbgl/style/expression/type.hpp
+++ b/include/mbgl/style/expression/type.hpp
@@ -66,6 +66,13 @@ struct CollatorType {
std::string getName() const { return "collator"; }
bool operator==(const CollatorType&) const { return true; }
};
+
+struct FormattedType {
+ constexpr FormattedType() {}; // NOLINT
+ std::string getName() const { return "formatted"; }
+ bool operator==(const FormattedType&) const { return true; }
+};
+
constexpr NullType Null;
constexpr NumberType Number;
@@ -75,6 +82,7 @@ constexpr ColorType Color;
constexpr ValueType Value;
constexpr ObjectType Object;
constexpr CollatorType Collator;
+constexpr FormattedType Formatted;
constexpr ErrorType Error;
struct Array;
@@ -89,6 +97,7 @@ using Type = variant<
ValueType,
mapbox::util::recursive_wrapper<Array>,
CollatorType,
+ FormattedType,
ErrorType>;
struct Array {
diff --git a/include/mbgl/style/expression/value.hpp b/include/mbgl/style/expression/value.hpp
index 2036ab8abe..91239d083f 100644
--- a/include/mbgl/style/expression/value.hpp
+++ b/include/mbgl/style/expression/value.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/style/expression/collator.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/style/expression/type.hpp>
#include <mbgl/style/position.hpp>
#include <mbgl/style/types.hpp>
@@ -25,6 +26,7 @@ using ValueBase = variant<
std::string,
Color,
Collator,
+ Formatted,
mapbox::util::recursive_wrapper<std::vector<Value>>,
mapbox::util::recursive_wrapper<std::unordered_map<std::string, Value>>>;
struct Value : ValueBase {
diff --git a/include/mbgl/style/layers/background_layer.hpp b/include/mbgl/style/layers/background_layer.hpp
index 76230df12c..ef01ea41be 100644
--- a/include/mbgl/style/layers/background_layer.hpp
+++ b/include/mbgl/style/layers/background_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp
index cde691c893..0f8d1c0c13 100644
--- a/include/mbgl/style/layers/circle_layer.hpp
+++ b/include/mbgl/style/layers/circle_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/fill_extrusion_layer.hpp b/include/mbgl/style/layers/fill_extrusion_layer.hpp
index e72fcade61..d30ffa26da 100644
--- a/include/mbgl/style/layers/fill_extrusion_layer.hpp
+++ b/include/mbgl/style/layers/fill_extrusion_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/fill_layer.hpp b/include/mbgl/style/layers/fill_layer.hpp
index 430d7a011f..25c46d312f 100644
--- a/include/mbgl/style/layers/fill_layer.hpp
+++ b/include/mbgl/style/layers/fill_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/heatmap_layer.hpp b/include/mbgl/style/layers/heatmap_layer.hpp
index fd0051f44c..347bb8a4aa 100644
--- a/include/mbgl/style/layers/heatmap_layer.hpp
+++ b/include/mbgl/style/layers/heatmap_layer.hpp
@@ -6,6 +6,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/hillshade_layer.hpp b/include/mbgl/style/layers/hillshade_layer.hpp
index 89d0ae686f..697d4c71ad 100644
--- a/include/mbgl/style/layers/hillshade_layer.hpp
+++ b/include/mbgl/style/layers/hillshade_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs
index cf31a4d672..9d595d2035 100644
--- a/include/mbgl/style/layers/layer.hpp.ejs
+++ b/include/mbgl/style/layers/layer.hpp.ejs
@@ -13,6 +13,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp
index 9350b3d102..1e55561bbd 100644
--- a/include/mbgl/style/layers/line_layer.hpp
+++ b/include/mbgl/style/layers/line_layer.hpp
@@ -6,6 +6,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/raster_layer.hpp b/include/mbgl/style/layers/raster_layer.hpp
index fcc35412a0..b1c716c17f 100644
--- a/include/mbgl/style/layers/raster_layer.hpp
+++ b/include/mbgl/style/layers/raster_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp
index aabda0d794..6d82e5df85 100644
--- a/include/mbgl/style/layers/symbol_layer.hpp
+++ b/include/mbgl/style/layers/symbol_layer.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/expression/formatted.hpp>
#include <mbgl/util/color.hpp>
@@ -121,9 +122,9 @@ public:
PropertyValue<AlignmentType> getTextRotationAlignment() const;
void setTextRotationAlignment(PropertyValue<AlignmentType>);
- static PropertyValue<std::string> getDefaultTextField();
- PropertyValue<std::string> getTextField() const;
- void setTextField(PropertyValue<std::string>);
+ static PropertyValue<expression::Formatted> getDefaultTextField();
+ PropertyValue<expression::Formatted> getTextField() const;
+ void setTextField(PropertyValue<expression::Formatted>);
static PropertyValue<std::vector<std::string>> getDefaultTextFont();
PropertyValue<std::vector<std::string>> getTextFont() const;
diff --git a/include/mbgl/util/font_stack.hpp b/include/mbgl/util/font_stack.hpp
index ace60a4ba6..ccc1a06068 100644
--- a/include/mbgl/util/font_stack.hpp
+++ b/include/mbgl/util/font_stack.hpp
@@ -11,11 +11,12 @@ namespace mbgl {
// An array of font names
using FontStack = std::vector<std::string>;
+using FontStackHash = std::size_t;
std::string fontStackToString(const FontStack&);
-struct FontStackHash {
- std::size_t operator()(const FontStack&) const;
+struct FontStackHasher {
+ FontStackHash operator()(const FontStack&) const;
};
// Statically evaluate layer properties to determine what font stacks are used.