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.cpp226
1 files changed, 135 insertions, 91 deletions
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 454e786573..1fc57e2f7e 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -341,7 +341,7 @@ std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
return std::tuple<bool, Function<T>> { true, StopsFunction<T>(std::get<1>(stops), base) };
}
-template <typename T> inline timestamp defaultDurationValue() { return 300_milliseconds; }
+template <typename T> inline std::chrono::duration<float> defaultDurationValue() { return std::chrono::duration<float>(300.0f); }
template <typename T>
std::tuple<bool, FadedStopsFunction<T>> StyleParser::parseFadedStopsFunction(JSVal value) {
@@ -350,13 +350,12 @@ std::tuple<bool, FadedStopsFunction<T>> StyleParser::parseFadedStopsFunction(JSV
return std::tuple<bool, FadedStopsFunction<T>> { false, {} };
}
- timestamp duration = defaultDurationValue<T>();
+ std::chrono::duration<float> 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_;
+ duration = static_cast<std::chrono::duration<float>>(value_duration.GetDouble());
} else {
Log::Warning(Event::ParseStyle, "duration must be numeric");
}
@@ -381,6 +380,18 @@ bool StyleParser::setProperty(JSVal value, const char *property_name, PropertyKe
}
template<typename T>
+void StyleParser::parseVisibility(StyleBucket &bucket, JSVal value) {
+ if (!value.HasMember("visibility")) {
+ return;
+ } else if (!value["visibility"].IsString()) {
+ Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string");
+ bucket.visibility = VisibilityType::Visible;
+ return;
+ }
+ bucket.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
+}
+
+template<typename T>
bool StyleParser::parseOptionalProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
if (!value.HasMember(property_name)) {
return false;
@@ -398,6 +409,15 @@ template<> std::tuple<bool, std::string> StyleParser::parseProperty(JSVal value,
return std::tuple<bool, std::string> { true, { value.GetString(), value.GetStringLength() } };
}
+template<> std::tuple<bool, bool> StyleParser::parseProperty(JSVal value, const char *property_name) {
+ if (!value.IsBool()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a boolean", property_name);
+ return std::tuple<bool, bool> { false, true };
+ }
+
+ return std::tuple<bool, bool> { true, value.GetBool() };
+}
+
template<> std::tuple<bool, TranslateAnchorType> StyleParser::parseProperty(JSVal value, const char *property_name) {
if (!value.IsString()) {
Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
@@ -416,18 +436,81 @@ template<> std::tuple<bool, RotateAnchorType> StyleParser::parseProperty<RotateA
return std::tuple<bool, RotateAnchorType> { true, RotateAnchorTypeClass({ value.GetString(), value.GetStringLength() }) };
}
+template<> std::tuple<bool, CapType> StyleParser::parseProperty<CapType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, CapType> { false, CapType::Butt };
+ }
+
+ return std::tuple<bool, CapType> { true, CapTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, JoinType> StyleParser::parseProperty<JoinType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, JoinType> { false, JoinType::Miter };
+ }
+
+ return std::tuple<bool, JoinType> { true, JoinTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, PlacementType> StyleParser::parseProperty<PlacementType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, PlacementType> { false, PlacementType::Point };
+ }
+
+ return std::tuple<bool, PlacementType> { true, PlacementTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, TextAnchorType> StyleParser::parseProperty<TextAnchorType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, TextAnchorType> { false, TextAnchorType::Center };
+ }
+
+ return std::tuple<bool, TextAnchorType> { true, TextAnchorTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, TextJustifyType> StyleParser::parseProperty<TextJustifyType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, TextJustifyType> { false, TextJustifyType::Center };
+ }
+
+ return std::tuple<bool, TextJustifyType> { true, TextJustifyTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, TextTransformType> StyleParser::parseProperty<TextTransformType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, TextTransformType> { false, TextTransformType::None };
+ }
+
+ return std::tuple<bool, TextTransformType> { true, TextTransformTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
+template<> std::tuple<bool, RotationAlignmentType> StyleParser::parseProperty<RotationAlignmentType>(JSVal value, const char *property_name) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
+ return std::tuple<bool, RotationAlignmentType> { false, RotationAlignmentType::Map };
+ }
+
+ return std::tuple<bool, RotationAlignmentType> { true, RotationAlignmentTypeClass({ value.GetString(), value.GetStringLength() }) };
+}
+
template<> std::tuple<bool, PropertyTransition> StyleParser::parseProperty(JSVal value, const char */*property_name*/) {
PropertyTransition transition;
if (value.IsObject()) {
if (value.HasMember("duration") && value["duration"].IsNumber()) {
- transition.duration = value["duration"].GetUint();
+ transition.duration = std::chrono::milliseconds(value["duration"].GetUint());
}
if (value.HasMember("delay") && value["delay"].IsNumber()) {
- transition.delay = value["delay"].GetUint();
+ transition.delay = std::chrono::milliseconds(value["delay"].GetUint());
}
}
- if (transition.duration == 0 && transition.delay == 0) {
+ if (transition.duration == std::chrono::steady_clock::duration::zero() && transition.delay == std::chrono::steady_clock::duration::zero()) {
return std::tuple<bool, PropertyTransition> { false, std::move(transition) };
}
@@ -710,6 +793,50 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) {
parseOptionalProperty<FadedStopsFunction<Faded<std::string>>>("background-image", Key::BackgroundImage, klass, value);
}
+void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) {
+ using Key = PropertyKey;
+
+ parseVisibility<VisibilityType>(*bucket, value);
+
+ parseOptionalProperty<CapType>("line-cap", Key::LineCap, bucket->layout, value);
+ parseOptionalProperty<JoinType>("line-join", Key::LineJoin, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("line-miter-limit", Key::LineMiterLimit, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("line-round-limit", Key::LineRoundLimit, bucket->layout, value);
+
+ parseOptionalProperty<PlacementType>("symbol-placement", Key::SymbolPlacement, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("symbol-min-distance", Key::SymbolMinDistance, bucket->layout, value);
+ parseOptionalProperty<bool>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value);
+ parseOptionalProperty<bool>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value);
+ parseOptionalProperty<bool>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value);
+ parseOptionalProperty<bool>("icon-optional", Key::IconOptional, bucket->layout, value);
+ parseOptionalProperty<RotationAlignmentType>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("icon-max-size", Key::IconMaxSize, bucket->layout, value);
+ parseOptionalProperty<std::string>("icon-image", Key::IconImage, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("icon-rotate", Key::IconRotate, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("icon-padding", Key::IconPadding, bucket->layout, value);
+ parseOptionalProperty<bool>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("icon-offset", { Key::IconOffsetX, Key::IconOffsetY }, bucket->layout, value);
+ parseOptionalProperty<RotationAlignmentType>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value);
+ parseOptionalProperty<std::string>("text-field", Key::TextField, bucket->layout, value);
+ parseOptionalProperty<std::string>("text-font", Key::TextFont, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-max-size", Key::TextMaxSize, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-max-width", Key::TextMaxWidth, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-line-height", Key::TextLineHeight, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-letter-spacing", Key::TextLetterSpacing, bucket->layout, value);
+ parseOptionalProperty<TextJustifyType>("text-justify", Key::TextJustify, bucket->layout, value);
+ parseOptionalProperty<TextAnchorType>("text-anchor", Key::TextAnchor, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-max-angle", Key::TextMaxAngle, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-rotate", Key::TextRotate, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-padding", Key::TextPadding, bucket->layout, value);
+ parseOptionalProperty<bool>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value);
+ parseOptionalProperty<TextTransformType>("text-transform", Key::TextTransform, bucket->layout, value);
+ parseOptionalProperty<Function<float>>("text-offset", { Key::TextOffsetX, Key::TextOffsetY }, bucket->layout, value);
+ parseOptionalProperty<bool>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value);
+ parseOptionalProperty<bool>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value);
+ parseOptionalProperty<bool>("text-optional", Key::TextOptional, bucket->layout, value);
+
+}
+
void StyleParser::parseReference(JSVal value, util::ptr<StyleLayer> &layer) {
if (!value.IsString()) {
Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", layer->id.c_str());
@@ -772,7 +899,7 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) {
if (value.HasMember("layout")) {
JSVal value_render = replaceConstant(value["layout"]);
- parseLayout(value_render, layer);
+ parseLayout(value_render, layer->bucket);
}
if (value.HasMember("minzoom")) {
@@ -794,89 +921,6 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) {
}
}
-void StyleParser::parseLayout(JSVal value, util::ptr<StyleLayer> &layer) {
- if (!value.IsObject()) {
- Log::Warning(Event::ParseStyle, "layout property of layer '%s' must be an object", layer->id.c_str());
- return;
- }
-
- StyleBucket &bucket = *layer->bucket;
- parseRenderProperty<VisibilityTypeClass>(value, bucket.visibility, "visibility");
-
- switch (layer->type) {
- case StyleLayerType::Fill: {
- StyleBucketFill &render = bucket.render.get<StyleBucketFill>();
-
- parseRenderProperty<WindingTypeClass>(value, render.winding, "fill-winding");
- } break;
-
- case StyleLayerType::Line: {
- StyleBucketLine &render = bucket.render.get<StyleBucketLine>();
-
- parseRenderProperty<CapTypeClass>(value, render.cap, "line-cap");
- parseRenderProperty<JoinTypeClass>(value, render.join, "line-join");
- parseRenderProperty(value, render.miter_limit, "line-miter-limit");
- parseRenderProperty(value, render.round_limit, "line-round-limit");
- } break;
-
- case StyleLayerType::Symbol: {
- StyleBucketSymbol &render = bucket.render.get<StyleBucketSymbol>();
-
- parseRenderProperty<PlacementTypeClass>(value, render.placement, "symbol-placement");
- if (render.placement == PlacementType::Line) {
- // Change the default value in case of line placement.
- render.text.rotation_alignment = RotationAlignmentType::Map;
- render.icon.rotation_alignment = RotationAlignmentType::Map;
- }
-
- parseRenderProperty(value, render.min_distance, "symbol-min-distance");
- parseRenderProperty(value, render.avoid_edges, "symbol-avoid-edges");
-
- parseRenderProperty(value, render.icon.allow_overlap, "icon-allow-overlap");
- parseRenderProperty(value, render.icon.ignore_placement, "icon-ignore-placement");
- parseRenderProperty(value, render.icon.optional, "icon-optional");
- parseRenderProperty<RotationAlignmentTypeClass>(value, render.icon.rotation_alignment, "icon-rotation-alignment");
- parseRenderProperty(value, render.icon.max_size, "icon-max-size");
- parseRenderProperty(value, render.icon.image, "icon-image");
- parseRenderProperty(value, render.icon.rotate, "icon-rotate");
- parseRenderProperty(value, render.icon.padding, "icon-padding");
- parseRenderProperty(value, render.icon.keep_upright, "icon-keep-upright");
- parseRenderProperty(value, render.icon.offset, "icon-offset");
-
-
- parseRenderProperty<RotationAlignmentTypeClass>(value, render.text.rotation_alignment, "text-rotation-alignment");
- parseRenderProperty(value, render.text.field, "text-field");
- parseRenderProperty(value, render.text.font, "text-font");
- parseRenderProperty(value, render.text.max_size, "text-max-size");
- if (parseRenderProperty(value, render.text.max_width, "text-max-width")) {
- render.text.max_width *= 24; // em
- }
- if (parseRenderProperty(value, render.text.line_height, "text-line-height")) {
- render.text.line_height *= 24; // em
- }
- if (parseRenderProperty(value, render.text.letter_spacing, "text-letter-spacing")) {
- render.text.letter_spacing *= 24; // em
- }
- parseRenderProperty<TextJustifyTypeClass>(value, render.text.justify, "text-justify");
- parseRenderProperty<TextAnchorTypeClass>(value, render.text.anchor, "text-anchor");
- parseRenderProperty(value, render.text.max_angle, "text-max-angle");
- parseRenderProperty(value, render.text.rotate, "text-rotate");
- parseRenderProperty(value, render.text.slant, "text-slant");
- parseRenderProperty(value, render.text.padding, "text-padding");
- parseRenderProperty(value, render.text.keep_upright, "text-keep-upright");
- parseRenderProperty<TextTransformTypeClass>(value, render.text.transform, "text-transform");
- parseRenderProperty(value, render.text.offset, "text-offset");
- parseRenderProperty(value, render.text.allow_overlap, "text-allow-overlap");
- parseRenderProperty(value, render.text.ignore_placement, "text-ignore-placement");
- parseRenderProperty(value, render.text.optional, "text-optional");
- } break;
-
- default:
- // There are no render properties for these layer types.
- break;
- }
-}
-
void StyleParser::parseSprite(JSVal value) {
if (value.IsString()) {
sprite = { value.GetString(), value.GetStringLength() };