summaryrefslogtreecommitdiff
path: root/src/mbgl/style/style_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/style_parser.cpp')
-rw-r--r--src/mbgl/style/style_parser.cpp120
1 files changed, 92 insertions, 28 deletions
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index f048b24bd4..3f1fc64dab 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -263,6 +263,52 @@ std::vector<float> StyleParser::parseFunctionArgument(JSVal value) {
return std::get<1>(parseFloatArray(rvalue));
}
+template <>
+Faded<std::string> StyleParser::parseFunctionArgument(JSVal value) {
+ JSVal rvalue = replaceConstant(value);
+ if (rvalue.IsString()) {
+ Faded<std::string> parsed;
+ parsed.low = { value.GetString(), value.GetStringLength() };
+ return parsed;
+ } else {
+ Log::Warning(Event::ParseStyle, "function argument must be a string");
+ return {};
+ }
+}
+
+template <typename T>
+std::tuple<bool, std::vector<std::pair<float, T>>> StyleParser::parseStops(JSVal value_stops) {
+
+ if (!value_stops.IsArray()) {
+ Log::Warning(Event::ParseStyle, "stops function must specify a stops array");
+ return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
+ }
+
+ std::vector<std::pair<float, T>> stops;
+
+ for (rapidjson::SizeType i = 0; i < value_stops.Size(); ++i) {
+ JSVal stop = value_stops[i];
+ if (stop.IsArray()) {
+ if (stop.Size() != 2) {
+ Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification");
+ return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
+ }
+
+ JSVal z = stop[rapidjson::SizeType(0)];
+ if (!z.IsNumber()) {
+ Log::Warning(Event::ParseStyle, "zoom level in stop must be a number");
+ return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
+ }
+
+ stops.emplace_back(z.GetDouble(), parseFunctionArgument<T>(stop[rapidjson::SizeType(1)]));
+ } else {
+ Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
+ return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}};
+ }
+ }
+ return { true, stops };
+}
+
template <typename T> inline float defaultBaseValue() { return 1.75; }
template <> inline float defaultBaseValue<Color>() { return 1.0; }
@@ -284,47 +330,52 @@ std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
}
}
- JSVal value_stops = value["stops"];
- if (!value_stops.IsArray()) {
- Log::Warning(Event::ParseStyle, "stops function must specify a stops array");
+ auto stops = parseStops<T>(value["stops"]);
+
+ if (!std::get<0>(stops)) {
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
}
- std::vector<std::pair<float, T>> stops;
- for (rapidjson::SizeType i = 0; i < value_stops.Size(); ++i) {
- JSVal stop = value_stops[i];
- if (stop.IsArray()) {
- if (stop.Size() != 2) {
- Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification");
- return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
- }
+ return std::tuple<bool, Function<T>> { true, StopsFunction<T>(std::get<1>(stops), base) };
+}
- JSVal z = stop[rapidjson::SizeType(0)];
- if (!z.IsNumber()) {
- Log::Warning(Event::ParseStyle, "zoom level in stop must be a number");
- return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
- }
+template <typename T> inline timestamp defaultDurationValue() { return 300_milliseconds; }
- stops.emplace_back(z.GetDouble(), parseFunctionArgument<T>(stop[rapidjson::SizeType(1)]));
+template <typename T>
+std::tuple<bool, FadedStopsFunction<T>> StyleParser::parseFadedStopsFunction(JSVal value) {
+ if (!value.HasMember("stops")) {
+ Log::Warning(Event::ParseStyle, "function must specify a function type");
+ return std::tuple<bool, FadedStopsFunction<T>> { false, {} };
+ }
+
+ timestamp duration = defaultDurationValue<T>();
+
+ if (value.HasMember("duration")) {
+ JSVal value_duration = value["duration"];
+ if (value_duration.IsNumber()) {
+ float duration_ = value_duration.GetDouble();
+ duration = 1_millisecond * duration_;
} else {
- Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
- return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
+ Log::Warning(Event::ParseStyle, "duration must be numeric");
}
}
- return std::tuple<bool, Function<T>> { true, StopsFunction<T>(stops, base) };
-}
+ auto stops = parseStops<T>(value["stops"]);
+
+ if (!std::get<0>(stops)) {
+ return std::tuple<bool, FadedStopsFunction<T>> { false, {} };
+ }
+ return std::tuple<bool, FadedStopsFunction<T>> { true, { std::get<1>(stops), duration } };
+}
template <typename T>
bool StyleParser::setProperty(JSVal value, const char *property_name, PropertyKey key, ClassProperties &klass) {
- bool parsed;
- T result;
- std::tie(parsed, result) = parseProperty<T>(value, property_name);
- if (parsed) {
- klass.set(key, result);
+ auto res = parseProperty<T>(value, property_name);
+ if (std::get<0>(res)) {
+ klass.set(key, std::get<1>(res));
}
- return parsed;
+ return std::get<0>(res);
}
template<typename T>
@@ -430,6 +481,19 @@ template<> std::tuple<bool, Function<std::vector<float>>> StyleParser::parseProp
}
}
+template<> std::tuple<bool, FadedStopsFunction<Faded<std::string>>> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ if (value.IsObject()) {
+ return parseFadedStopsFunction<Faded<std::string>>(value);
+ } else if (value.IsString()) {
+ Faded<std::string> parsed;
+ parsed.low = { value.GetString(), value.GetStringLength() };
+ return std::tuple<bool, FadedStopsFunction<Faded<std::string>>> { true, parsed };
+ } else {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be string or a string function", property_name);
+ return std::tuple<bool, FadedStopsFunction<Faded<std::string>>> { false, {} };
+ }
+}
+
template <typename T>
bool StyleParser::parseOptionalProperty(const char *property_name, const std::vector<PropertyKey> &keys, ClassProperties &klass, JSVal value) {
if (value.HasMember(property_name)) {
@@ -573,7 +637,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<Function<float>>("fill-translate", { Key::FillTranslateX, Key::FillTranslateY }, klass, value);
parseOptionalProperty<PropertyTransition>("fill-translate-transition", Key::FillTranslate, klass, value);
parseOptionalProperty<TranslateAnchorType>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value);
- parseOptionalProperty<std::string>("fill-image", Key::FillImage, klass, value);
+ parseOptionalProperty<FadedStopsFunction<Faded<std::string>>>("fill-image", Key::FillImage, klass, value);
parseOptionalProperty<Function<float>>("line-opacity", Key::LineOpacity, klass, value);
parseOptionalProperty<PropertyTransition>("line-opacity-transition", Key::LineOpacity, klass, value);