Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Initial implementation of 'format' expression
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisLoer committed Sep 19, 2018
1 parent a133e33 commit b036ccd
Show file tree
Hide file tree
Showing 62 changed files with 970 additions and 178 deletions.
6 changes: 6 additions & 0 deletions cmake/core-files.txt
Expand Up @@ -465,6 +465,8 @@ include/mbgl/style/expression/dsl.hpp
include/mbgl/style/expression/error.hpp
include/mbgl/style/expression/expression.hpp
include/mbgl/style/expression/find_zoom_curve.hpp
include/mbgl/style/expression/format_expression.hpp
include/mbgl/style/expression/formatted.hpp
include/mbgl/style/expression/get_covering_stops.hpp
include/mbgl/style/expression/interpolate.hpp
include/mbgl/style/expression/interpolator.hpp
Expand All @@ -491,6 +493,8 @@ src/mbgl/style/expression/compound_expression.cpp
src/mbgl/style/expression/dsl.cpp
src/mbgl/style/expression/expression.cpp
src/mbgl/style/expression/find_zoom_curve.cpp
src/mbgl/style/expression/format_expression.cpp
src/mbgl/style/expression/formatted.cpp
src/mbgl/style/expression/get_covering_stops.cpp
src/mbgl/style/expression/interpolate.cpp
src/mbgl/style/expression/is_constant.cpp
Expand Down Expand Up @@ -620,6 +624,8 @@ src/mbgl/text/quads.cpp
src/mbgl/text/quads.hpp
src/mbgl/text/shaping.cpp
src/mbgl/text/shaping.hpp
src/mbgl/text/tagged_string.cpp
src/mbgl/text/tagged_string.hpp

# tile
include/mbgl/tile/tile_id.hpp
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/conversion/function.hpp
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions include/mbgl/style/conversion/property_value.hpp
Expand Up @@ -28,6 +28,13 @@ struct Converter<PropertyValue<T>> {
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToExpression(t)))
: PropertyValue<T>(t);
}

PropertyValue<T> maybeConvertTokens(const expression::Formatted& t) const {
std::string todoText = t.sections[0].text;
return hasTokens(todoText)
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToFormatExpression(todoText)))
: PropertyValue<T>(t);
}
};

} // namespace conversion
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/expression/expression.hpp
Expand Up @@ -133,6 +133,7 @@ enum class Kind : int32_t {
Any,
All,
Comparison,
FormatExpression,
};

class Expression {
Expand Down
52 changes: 52 additions & 0 deletions 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
62 changes: 62 additions & 0 deletions 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() {}

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();
}

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
9 changes: 9 additions & 0 deletions include/mbgl/style/expression/type.hpp
Expand Up @@ -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;
Expand All @@ -75,6 +82,7 @@ constexpr ColorType Color;
constexpr ValueType Value;
constexpr ObjectType Object;
constexpr CollatorType Collator;
constexpr FormattedType Formatted;
constexpr ErrorType Error;

struct Array;
Expand All @@ -89,6 +97,7 @@ using Type = variant<
ValueType,
mapbox::util::recursive_wrapper<Array>,
CollatorType,
FormattedType,
ErrorType>;

struct Array {
Expand Down
2 changes: 2 additions & 0 deletions 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>
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/background_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/circle_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/fill_extrusion_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/fill_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/heatmap_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/hillshade_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/layer.hpp.ejs
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/line_layer.hpp
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions include/mbgl/style/layers/raster_layer.hpp
Expand Up @@ -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>

Expand Down
7 changes: 4 additions & 3 deletions include/mbgl/style/layers/symbol_layer.hpp
Expand Up @@ -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>

Expand Down Expand Up @@ -121,9 +122,9 @@ class SymbolLayer : public Layer {
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;
Expand Down
5 changes: 3 additions & 2 deletions include/mbgl/util/font_stack.hpp
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions platform/darwin/scripts/generate-style-code.js
Expand Up @@ -559,6 +559,7 @@ global.valueTransformerArguments = function (property) {
case 'number':
return ['float', objCType];
case 'formatted':
return ['mbgl::style::expression::Formatted', objCType];
case 'string':
return ['std::string', objCType];
case 'enum':
Expand Down Expand Up @@ -593,6 +594,7 @@ global.mbglType = function(property) {
case 'number':
return 'float';
case 'formatted':
return 'mbgl::style::expression::Formatted';
case 'string':
return 'std::string';
case 'enum': {
Expand Down
7 changes: 6 additions & 1 deletion platform/darwin/src/MGLStyleLayer.mm.ejs
Expand Up @@ -125,8 +125,13 @@ namespace mbgl {
if (<%- objCName(property) %> && <%- objCName(property) %>.expressionType == NSConstantValueExpressionType) {
std::string string = ((NSString *)<%- objCName(property) %>.constantValue).UTF8String;
if (mbgl::style::conversion::hasTokens(string)) {
self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<std::string>(
<% if (property.type === 'formatted') { -%>
self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<mbgl::style::expression::Formatted>(
mbgl::style::conversion::convertTokenStringToFormatExpression(string)));
<% } else { -%>
self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<std::string>(
mbgl::style::conversion::convertTokenStringToExpression(string)));
<% } -%>
return;
}
}
Expand Down
10 changes: 10 additions & 0 deletions platform/darwin/src/MGLStyleValue_Private.h
Expand Up @@ -161,6 +161,11 @@ class MGLStyleValueTransformer {
void getMBGLValue(NSString *rawValue, std::string &mbglValue) {
mbglValue = rawValue.UTF8String;
}

// Formmatted
void getMBGLValue(NSString *rawValue, mbgl::style::expression::Formatted &mbglValue) {
mbglValue = mbgl::style::expression::Formatted(rawValue.UTF8String);
}

// Offsets
void getMBGLValue(id rawValue, std::array<float, 2> &mbglValue) {
Expand Down Expand Up @@ -249,6 +254,11 @@ class MGLStyleValueTransformer {
static NSString *toMGLRawStyleValue(const std::string &mbglStopValue) {
return @(mbglStopValue.c_str());
}

// Formatted
static NSString *toMGLRawStyleValue(const mbgl::style::expression::Formatted &mbglStopValue) {
return @(mbglStopValue.toString().c_str());
}

// Offsets
static NSValue *toMGLRawStyleValue(const std::array<float, 2> &mbglStopValue) {
Expand Down

0 comments on commit b036ccd

Please sign in to comment.