diff options
Diffstat (limited to 'src/mbgl/style/style_parser.cpp')
-rw-r--r-- | src/mbgl/style/style_parser.cpp | 142 |
1 files changed, 63 insertions, 79 deletions
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index 4767bdafa3..6dc92a8d3d 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -27,8 +27,11 @@ StyleParser::StyleParser(MapData& data_) } void StyleParser::parse(JSVal document) { - if (document.HasMember("constants")) { - parseConstants(document["constants"]); + if (document.HasMember("version")) { + version = document["version"].GetInt(); + if (version != 8) { + Log::Warning(Event::ParseStyle, "current renderer implementation only supports style spec version 8; using an outdated style will cause rendering errors"); + } } if (document.HasMember("sources")) { @@ -89,37 +92,11 @@ void StyleParser::parse(JSVal document) { } } -void StyleParser::parseConstants(JSVal value) { - if (value.IsObject()) { - rapidjson::Value::ConstMemberIterator itr = value.MemberBegin(); - for (; itr != value.MemberEnd(); ++itr) { - std::string name { itr->name.GetString(), itr->name.GetStringLength() }; - // Discard constants that don't start with an @ sign. - if (name.length() && name[0] == '@') { - constants.emplace(std::move(name), &itr->value); - } - } - } else { - Log::Warning(Event::ParseStyle, "constants must be an object"); - } -} - -JSVal StyleParser::replaceConstant(JSVal value) { - if (value.IsString()) { - auto it = constants.find({ value.GetString(), value.GetStringLength() }); - if (it != constants.end()) { - return *it->second; - } - } - - return value; -} - #pragma mark - Parse Render Properties template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, bool &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsBool()) { target = property.GetBool(); return StyleParserSuccess; @@ -133,7 +110,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, boo template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, std::string &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsString()) { target = { property.GetString(), property.GetStringLength() }; return StyleParserSuccess; @@ -146,7 +123,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, std template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, float &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsNumber()) { target = property.GetDouble(); return StyleParserSuccess; @@ -159,7 +136,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, flo template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, uint16_t &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsUint()) { unsigned int int_value = property.GetUint(); if (int_value > std::numeric_limits<uint16_t>::max()) { @@ -178,7 +155,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, uin template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, int32_t &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsInt()) { target = property.GetInt(); return StyleParserSuccess; @@ -191,7 +168,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, int template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, vec2<float> &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsArray()) { if (property.Size() >= 2) { target.x = property[(rapidjson::SizeType)0].GetDouble(); @@ -210,7 +187,7 @@ template<> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, vec template<typename Parser, typename T> StyleParser::Status StyleParser::parseRenderProperty(JSVal value, T &target, const char *name) { if (value.HasMember(name)) { - JSVal property = replaceConstant(value[name]); + JSVal property = value[name]; if (property.IsString()) { target = Parser({ property.GetString(), property.GetStringLength() }); return StyleParserSuccess; @@ -270,7 +247,7 @@ StyleParser::Result<std::vector<float>> StyleParser::parseFloatArray(JSVal value std::vector<float> vec; for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { - JSVal part = replaceConstant(value[i]); + JSVal part = value[i]; if (!part.IsNumber()) { Log::Warning(Event::ParseStyle, "dasharray value must be an array of numbers"); return Result<std::vector<float>> { StyleParserFailure, std::vector<float>() }; @@ -297,9 +274,8 @@ StyleParser::Result<std::array<float, 2>> StyleParser::parseProperty(JSVal value template <> StyleParser::Result<float> StyleParser::parseProperty(JSVal value, const char* property_name) { - JSVal rvalue = replaceConstant(value); - if (rvalue.IsNumber()) { - return Result<float> { StyleParserSuccess, rvalue.GetDouble() }; + if (value.IsNumber()) { + return Result<float> { StyleParserSuccess, value.GetDouble() }; } else { Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", property_name); return Result<float> { StyleParserFailure, 0.0f }; @@ -308,23 +284,20 @@ StyleParser::Result<float> StyleParser::parseProperty(JSVal value, const char* p template <> StyleParser::Result<Color> StyleParser::parseProperty(JSVal value, const char*) { - JSVal rvalue = replaceConstant(value); - return Result<Color> { StyleParserSuccess, parseColor(rvalue) }; + return Result<Color> { StyleParserSuccess, parseColor(value) }; } template <> StyleParser::Result<Faded<std::vector<float>>> StyleParser::parseProperty(JSVal value, const char*) { Faded<std::vector<float>> parsed; - JSVal rvalue = replaceConstant(value); - parsed.to = std::get<1>(parseFloatArray(rvalue)); + parsed.to = std::get<1>(parseFloatArray(value)); return Result<Faded<std::vector<float>>> { StyleParserSuccess, parsed }; } template <> StyleParser::Result<Faded<std::string>> StyleParser::parseProperty(JSVal value, const char *property_name) { - JSVal rvalue = replaceConstant(value); Faded<std::string> parsed; - if (rvalue.IsString()) { + if (value.IsString()) { parsed.to = { value.GetString(), value.GetStringLength() }; return Result<Faded<std::string>> { StyleParserSuccess, parsed }; } else { @@ -357,7 +330,7 @@ StyleParser::Result<std::vector<std::pair<float, T>>> StyleParser::parseStops(JS return Result<std::vector<std::pair<float, T>>> { StyleParserFailure, {}}; } - stops.emplace_back(z.GetDouble(), std::get<1>(parseProperty<T>(replaceConstant(stop[rapidjson::SizeType(1)]), property_name))); + stops.emplace_back(z.GetDouble(), std::get<1>(parseProperty<T>(stop[rapidjson::SizeType(1)], property_name))); } else { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); return Result<std::vector<std::pair<float, T>>> { StyleParserFailure, {}}; @@ -448,7 +421,7 @@ StyleParser::Status StyleParser::parseOptionalProperty(const char *property_name if (!value.HasMember(property_name)) { return StyleParserFailure; } else { - return setProperty<T>(replaceConstant(value[property_name]), property_name, key, klass); + return setProperty<T>(value[property_name], property_name, key, klass); } } @@ -458,32 +431,38 @@ StyleParser::Status StyleParser::parseOptionalProperty(const char *property_name return StyleParserFailure; } else { if (value.HasMember(transition_name)) { - return setProperty<T>(replaceConstant(value[property_name]), property_name, key, klass, value[transition_name]); + return setProperty<T>(value[property_name], property_name, key, klass, value[transition_name]); } else { JSVal val = JSVal(rapidjson::kObjectType); - return setProperty<T>(replaceConstant(value[property_name]), property_name, key, klass, val); + return setProperty<T>(value[property_name], property_name, key, klass, val); } } } -std::string normalizeFontStack(const std::string &name) { - namespace algo = boost::algorithm; - std::vector<std::string> parts; - algo::split(parts, name, algo::is_any_of(","), algo::token_compress_on); - std::for_each(parts.begin(), parts.end(), [](std::string& str) { algo::trim(str); }); - return algo::join(parts, ", "); -} - template<> StyleParser::Result<std::string> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (!value.IsString()) { + if (std::string { "text-font" } == property_name) { + if (!value.IsArray()) { + Log::Warning(Event::ParseStyle, "value of '%s' must be an array of strings", property_name); + return Result<std::string> { StyleParserFailure, std::string() }; + } else { + std::string result = ""; + for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { + JSVal stop = value[i]; + if (stop.IsString()) { + result += stop.GetString(); + if (i < value.Size()-1) { + result += ","; + } + } else { + Log::Warning(Event::ParseStyle, "text-font members must be strings"); + return Result<std::string> { StyleParserFailure, {} }; + } + } + return Result<std::string> { StyleParserSuccess, result }; + } + } else if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name); return Result<std::string> { StyleParserFailure, std::string() }; - } - - if (std::string { "text-font" } == property_name) { - return Result<std::string> { - StyleParserSuccess, normalizeFontStack({ value.GetString(), value.GetStringLength() }) - }; } else { return Result<std::string> { StyleParserSuccess, { value.GetString(), value.GetStringLength() } }; } @@ -767,7 +746,7 @@ void StyleParser::parseLayer(std::pair<JSVal, util::ptr<StyleLayer>> &pair) { if (value.HasMember("ref")) { // This layer is referencing another layer. Inherit the bucket from that layer, if we // already parsed it. - parseReference(replaceConstant(value["ref"]), layer); + parseReference(value["ref"], layer); } else { // Otherwise, parse the source/source-layer/filter/render keys to form the bucket. parseBucket(value, layer); @@ -782,10 +761,10 @@ void StyleParser::parsePaints(JSVal value, std::map<ClassID, ClassProperties> &p const std::string name { itr->name.GetString(), itr->name.GetStringLength() }; if (name == "paint") { - parsePaint(replaceConstant(itr->value), paints[ClassID::Default]); + parsePaint(itr->value, paints[ClassID::Default]); } else if (name.compare(0, 6, "paint.") == 0 && name.length() > 6) { const ClassID class_id = ClassDictionary::Get().lookup(name.substr(6)); - parsePaint(replaceConstant(itr->value), paints[class_id]); + parsePaint(itr->value, paints[class_id]); } } } @@ -803,7 +782,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<std::array<float, 2>>>("fill-translate", Key::FillTranslate, klass, value); parseOptionalProperty<PropertyTransition>("fill-translate-transition", Key::FillTranslate, klass, value); parseOptionalProperty<Function<TranslateAnchorType>>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value); - parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("fill-image", Key::FillImage, klass, value, "fill-image-transition"); + parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("fill-pattern", Key::FillImage, klass, value, "fill-pattern-transition"); parseOptionalProperty<Function<float>>("line-opacity", Key::LineOpacity, klass, value); parseOptionalProperty<PropertyTransition>("line-opacity-transition", Key::LineOpacity, klass, value); @@ -819,7 +798,14 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<float>>("line-blur", Key::LineBlur, klass, value); parseOptionalProperty<PropertyTransition>("line-blur-transition", Key::LineBlur, klass, value); parseOptionalProperty<PiecewiseConstantFunction<Faded<std::vector<float>>>>("line-dasharray", Key::LineDashArray, klass, value, "line-dasharray-transition"); - parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("line-image", Key::LineImage, klass, value, "line-image-transition"); + parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("line-pattern", Key::LineImage, klass, value, "line-pattern-transition"); + + parseOptionalProperty<Function<float>>("circle-radius", Key::CircleRadius, klass, value); + parseOptionalProperty<Function<Color>>("circle-color", Key::CircleColor, klass, value); + parseOptionalProperty<Function<float>>("circle-opacity", Key::CircleOpacity, klass, value); + parseOptionalProperty<Function<std::array<float,2>>>("circle-translate", Key::CircleTranslate, klass, value); + parseOptionalProperty<Function<TranslateAnchorType>>("circle-translate-anchor", Key::CircleTranslateAnchor, klass, value); + parseOptionalProperty<Function<float>>("circle-blur", Key::CircleBlur, klass, value); parseOptionalProperty<Function<float>>("icon-opacity", Key::IconOpacity, klass, value); parseOptionalProperty<PropertyTransition>("icon-opacity-transition", Key::IconOpacity, klass, value); @@ -869,7 +855,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<float>>("background-opacity", Key::BackgroundOpacity, klass, value); parseOptionalProperty<Function<Color>>("background-color", Key::BackgroundColor, klass, value); - parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("background-image", Key::BackgroundImage, klass, value, "background-image-transition"); + parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("background-pattern", Key::BackgroundImage, klass, value, "background-pattern-transition"); } void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) { @@ -883,13 +869,13 @@ void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) { parseOptionalProperty<Function<float>>("line-round-limit", Key::LineRoundLimit, bucket->layout, value); parseOptionalProperty<Function<PlacementType>>("symbol-placement", Key::SymbolPlacement, bucket->layout, value); - parseOptionalProperty<Function<float>>("symbol-min-distance", Key::SymbolMinDistance, bucket->layout, value); + parseOptionalProperty<Function<float>>("symbol-spacing", Key::SymbolSpacing, bucket->layout, value); parseOptionalProperty<Function<bool>>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value); parseOptionalProperty<Function<bool>>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value); parseOptionalProperty<Function<bool>>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value); parseOptionalProperty<Function<bool>>("icon-optional", Key::IconOptional, bucket->layout, value); parseOptionalProperty<Function<RotationAlignmentType>>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value); - parseOptionalProperty<Function<float>>("icon-max-size", Key::IconMaxSize, bucket->layout, value); + parseOptionalProperty<Function<float>>("icon-size", Key::IconSize, bucket->layout, value); parseOptionalProperty<Function<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); @@ -898,7 +884,7 @@ void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) { parseOptionalProperty<Function<RotationAlignmentType>>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value); parseOptionalProperty<Function<std::string>>("text-field", Key::TextField, bucket->layout, value); parseOptionalProperty<Function<std::string>>("text-font", Key::TextFont, bucket->layout, value); - parseOptionalProperty<Function<float>>("text-max-size", Key::TextMaxSize, bucket->layout, value); + parseOptionalProperty<Function<float>>("text-size", Key::TextSize, 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); @@ -948,7 +934,7 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) { bucket->name = layer->id; if (value.HasMember("source")) { - JSVal value_source = replaceConstant(value["source"]); + JSVal value_source = value["source"]; if (value_source.IsString()) { bucket->source = { value_source.GetString(), value_source.GetStringLength() }; auto source_it = sourcesMap.find(bucket->source); @@ -961,7 +947,7 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) { } if (value.HasMember("source-layer")) { - JSVal value_source_layer = replaceConstant(value["source-layer"]); + JSVal value_source_layer = value["source-layer"]; if (value_source_layer.IsString()) { bucket->source_layer = { value_source_layer.GetString(), value_source_layer.GetStringLength() }; } else { @@ -970,13 +956,11 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) { } if (value.HasMember("filter")) { - JSVal value_filter = replaceConstant(value["filter"]); - bucket->filter = parseFilterExpression(value_filter); + bucket->filter = parseFilterExpression(value["filter"]); } if (value.HasMember("layout")) { - JSVal value_render = replaceConstant(value["layout"]); - parseLayout(value_render, bucket); + parseLayout(value["layout"], bucket); } if (value.HasMember("minzoom")) { |