summaryrefslogtreecommitdiff
path: root/src/mbgl/layer
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/layer')
-rw-r--r--src/mbgl/layer/background_layer.cpp57
-rw-r--r--src/mbgl/layer/background_layer.hpp36
-rw-r--r--src/mbgl/layer/background_layer_impl.cpp26
-rw-r--r--src/mbgl/layer/background_layer_impl.hpp24
-rw-r--r--src/mbgl/layer/background_layer_properties.cpp29
-rw-r--r--src/mbgl/layer/background_layer_properties.hpp25
-rw-r--r--src/mbgl/layer/circle_layer.cpp118
-rw-r--r--src/mbgl/layer/circle_layer.hpp46
-rw-r--r--src/mbgl/layer/circle_layer_impl.cpp60
-rw-r--r--src/mbgl/layer/circle_layer_impl.hpp31
-rw-r--r--src/mbgl/layer/circle_layer_properties.cpp38
-rw-r--r--src/mbgl/layer/circle_layer_properties.hpp28
-rw-r--r--src/mbgl/layer/custom_layer.cpp69
-rw-r--r--src/mbgl/layer/custom_layer_impl.cpp66
-rw-r--r--src/mbgl/layer/custom_layer_impl.hpp (renamed from src/mbgl/layer/custom_layer.hpp)26
-rw-r--r--src/mbgl/layer/fill_layer.cpp133
-rw-r--r--src/mbgl/layer/fill_layer.hpp47
-rw-r--r--src/mbgl/layer/fill_layer_impl.cpp66
-rw-r--r--src/mbgl/layer/fill_layer_impl.hpp31
-rw-r--r--src/mbgl/layer/fill_layer_properties.cpp41
-rw-r--r--src/mbgl/layer/fill_layer_properties.hpp29
-rw-r--r--src/mbgl/layer/layer.cpp32
-rw-r--r--src/mbgl/layer/layer_impl.cpp17
-rw-r--r--src/mbgl/layer/layer_impl.hpp88
-rw-r--r--src/mbgl/layer/line_layer.cpp229
-rw-r--r--src/mbgl/layer/line_layer.hpp64
-rw-r--r--src/mbgl/layer/line_layer_impl.cpp114
-rw-r--r--src/mbgl/layer/line_layer_impl.hpp38
-rw-r--r--src/mbgl/layer/line_layer_properties.cpp64
-rw-r--r--src/mbgl/layer/line_layer_properties.hpp43
-rw-r--r--src/mbgl/layer/raster_layer.cpp108
-rw-r--r--src/mbgl/layer/raster_layer.hpp40
-rw-r--r--src/mbgl/layer/raster_layer_impl.cpp26
-rw-r--r--src/mbgl/layer/raster_layer_impl.hpp24
-rw-r--r--src/mbgl/layer/raster_layer_properties.cpp41
-rw-r--r--src/mbgl/layer/raster_layer_properties.hpp29
-rw-r--r--src/mbgl/layer/symbol_layer.cpp542
-rw-r--r--src/mbgl/layer/symbol_layer_impl.cpp80
-rw-r--r--src/mbgl/layer/symbol_layer_impl.hpp35
-rw-r--r--src/mbgl/layer/symbol_layer_properties.cpp130
-rw-r--r--src/mbgl/layer/symbol_layer_properties.hpp (renamed from src/mbgl/layer/symbol_layer.hpp)78
41 files changed, 2035 insertions, 813 deletions
diff --git a/src/mbgl/layer/background_layer.cpp b/src/mbgl/layer/background_layer.cpp
index e2879f786e..8d097344fc 100644
--- a/src/mbgl/layer/background_layer.cpp
+++ b/src/mbgl/layer/background_layer.cpp
@@ -1,38 +1,55 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/background_layer.hpp>
-#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/layer/background_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> BackgroundLayer::clone() const {
- return std::make_unique<BackgroundLayer>(*this);
+BackgroundLayer::BackgroundLayer(const std::string& layerID)
+ : Layer(Type::Background, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
}
-void BackgroundLayer::parsePaints(const JSValue& layer) {
- paint.backgroundOpacity.parse("background-opacity", layer);
- paint.backgroundColor.parse("background-color", layer);
- paint.backgroundPattern.parse("background-pattern", layer);
+BackgroundLayer::BackgroundLayer(const Impl& other)
+ : Layer(Type::Background, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
}
-void BackgroundLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.backgroundOpacity.cascade(parameters);
- paint.backgroundColor.cascade(parameters);
- paint.backgroundPattern.cascade(parameters);
+BackgroundLayer::~BackgroundLayer() = default;
+
+std::unique_ptr<Layer> BackgroundLayer::Impl::clone() const {
+ return std::make_unique<BackgroundLayer>(*this);
}
-bool BackgroundLayer::recalculate(const StyleCalculationParameters& parameters) {
- bool hasTransitions = false;
- hasTransitions |= paint.backgroundOpacity.calculate(parameters);
- hasTransitions |= paint.backgroundColor.calculate(parameters);
- hasTransitions |= paint.backgroundPattern.calculate(parameters);
+// Layout properties
- passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+// Paint properties
+
+Function<Color> BackgroundLayer::getBackgroundColor() const {
+ return impl->paint.backgroundColor.values.at(ClassID::Default);
+}
+
+void BackgroundLayer::setBackgroundColor(Function<Color> value) {
+ impl->paint.backgroundColor.values.emplace(ClassID::Default, value);
+}
+
+Function<std::string> BackgroundLayer::getBackgroundPattern() const {
+ return impl->paint.backgroundPattern.values.at(ClassID::Default);
+}
+
+void BackgroundLayer::setBackgroundPattern(Function<std::string> value) {
+ impl->paint.backgroundPattern.values.emplace(ClassID::Default, value);
+}
+
+Function<float> BackgroundLayer::getBackgroundOpacity() const {
+ return impl->paint.backgroundOpacity.values.at(ClassID::Default);
}
-std::unique_ptr<Bucket> BackgroundLayer::createBucket(StyleBucketParameters&) const {
- return nullptr;
+void BackgroundLayer::setBackgroundOpacity(Function<float> value) {
+ impl->paint.backgroundOpacity.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/background_layer.hpp b/src/mbgl/layer/background_layer.hpp
deleted file mode 100644
index 39142a3bd3..0000000000
--- a/src/mbgl/layer/background_layer.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/paint_property.hpp>
-
-namespace mbgl {
-
-class BackgroundPaintProperties {
-public:
- PaintProperty<float> backgroundOpacity { 1.0f };
- PaintProperty<Color> backgroundColor { {{ 0, 0, 0, 1 }} };
- PaintProperty<std::string, CrossFadedFunctionEvaluator> backgroundPattern { "" };
-};
-
-class BackgroundLayer : public StyleLayer {
-public:
- BackgroundLayer() : StyleLayer(Type::Background) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override {};
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- BackgroundPaintProperties paint;
-};
-
-template <>
-inline bool StyleLayer::is<BackgroundLayer>() const {
- return type == Type::Background;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/layer/background_layer_impl.cpp b/src/mbgl/layer/background_layer_impl.cpp
new file mode 100644
index 0000000000..626c8fc805
--- /dev/null
+++ b/src/mbgl/layer/background_layer_impl.cpp
@@ -0,0 +1,26 @@
+#include <mbgl/layer/background_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+
+void BackgroundLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void BackgroundLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool BackgroundLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(StyleBucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/background_layer_impl.hpp b/src/mbgl/layer/background_layer_impl.hpp
new file mode 100644
index 0000000000..6af31dd921
--- /dev/null
+++ b/src/mbgl/layer/background_layer_impl.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/background_layer.hpp>
+#include <mbgl/layer/background_layer_properties.hpp>
+
+namespace mbgl {
+
+class BackgroundLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override {};
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ BackgroundPaintProperties paint;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/background_layer_properties.cpp b/src/mbgl/layer/background_layer_properties.cpp
new file mode 100644
index 0000000000..d866df7eee
--- /dev/null
+++ b/src/mbgl/layer/background_layer_properties.cpp
@@ -0,0 +1,29 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/background_layer_properties.hpp>
+
+namespace mbgl {
+
+void BackgroundPaintProperties::parse(const JSValue& value) {
+ backgroundColor.parse("background-color", value);
+ backgroundPattern.parse("background-pattern", value);
+ backgroundOpacity.parse("background-opacity", value);
+}
+
+void BackgroundPaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ backgroundColor.cascade(parameters);
+ backgroundPattern.cascade(parameters);
+ backgroundOpacity.cascade(parameters);
+}
+
+bool BackgroundPaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= backgroundColor.calculate(parameters);
+ hasTransitions |= backgroundPattern.calculate(parameters);
+ hasTransitions |= backgroundOpacity.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/background_layer_properties.hpp b/src/mbgl/layer/background_layer_properties.hpp
new file mode 100644
index 0000000000..5e388a7928
--- /dev/null
+++ b/src/mbgl/layer/background_layer_properties.hpp
@@ -0,0 +1,25 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+
+class BackgroundPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<Color> backgroundColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<std::string, CrossFadedFunctionEvaluator> backgroundPattern { "" };
+ PaintProperty<float> backgroundOpacity { 1 };
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer.cpp b/src/mbgl/layer/circle_layer.cpp
index 839d1282a9..bf385c997c 100644
--- a/src/mbgl/layer/circle_layer.cpp
+++ b/src/mbgl/layer/circle_layer.cpp
@@ -1,81 +1,93 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/circle_layer.hpp>
-#include <mbgl/style/style_bucket_parameters.hpp>
-#include <mbgl/renderer/circle_bucket.hpp>
-#include <mbgl/geometry/feature_index.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/intersection_tests.hpp>
+#include <mbgl/layer/circle_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> CircleLayer::clone() const {
+CircleLayer::CircleLayer(const std::string& layerID)
+ : Layer(Type::Circle, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+CircleLayer::CircleLayer(const Impl& other)
+ : Layer(Type::Circle, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+CircleLayer::~CircleLayer() = default;
+
+std::unique_ptr<Layer> CircleLayer::Impl::clone() const {
return std::make_unique<CircleLayer>(*this);
}
-void CircleLayer::parsePaints(const JSValue& layer) {
- paint.circleRadius.parse("circle-radius", layer);
- paint.circleColor.parse("circle-color", layer);
- paint.circleOpacity.parse("circle-opacity", layer);
- paint.circleTranslate.parse("circle-translate", layer);
- paint.circleTranslateAnchor.parse("circle-translate-anchor", layer);
- paint.circleBlur.parse("circle-blur", layer);
+// Source
+
+void CircleLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
}
-void CircleLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.circleRadius.cascade(parameters);
- paint.circleColor.cascade(parameters);
- paint.circleOpacity.cascade(parameters);
- paint.circleTranslate.cascade(parameters);
- paint.circleTranslateAnchor.cascade(parameters);
- paint.circleBlur.cascade(parameters);
+const std::string& CircleLayer::getSourceID() const {
+ return impl->source;
}
-bool CircleLayer::recalculate(const StyleCalculationParameters& parameters) {
- bool hasTransitions = false;
+const std::string& CircleLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Layout properties
+
- hasTransitions |= paint.circleRadius.calculate(parameters);
- hasTransitions |= paint.circleColor.calculate(parameters);
- hasTransitions |= paint.circleOpacity.calculate(parameters);
- hasTransitions |= paint.circleTranslate.calculate(parameters);
- hasTransitions |= paint.circleTranslateAnchor.calculate(parameters);
- hasTransitions |= paint.circleBlur.calculate(parameters);
+// Paint properties
- passes = (paint.circleRadius > 0 && paint.circleColor.value[3] > 0 && paint.circleOpacity > 0)
- ? RenderPass::Translucent : RenderPass::None;
+Function<float> CircleLayer::getCircleRadius() const {
+ return impl->paint.circleRadius.values.at(ClassID::Default);
+}
+
+void CircleLayer::setCircleRadius(Function<float> value) {
+ impl->paint.circleRadius.values.emplace(ClassID::Default, value);
+}
+
+Function<Color> CircleLayer::getCircleColor() const {
+ return impl->paint.circleColor.values.at(ClassID::Default);
+}
- return hasTransitions;
+void CircleLayer::setCircleColor(Function<Color> value) {
+ impl->paint.circleColor.values.emplace(ClassID::Default, value);
}
-std::unique_ptr<Bucket> CircleLayer::createBucket(StyleBucketParameters& parameters) const {
- auto bucket = std::make_unique<CircleBucket>(parameters.mode);
+Function<float> CircleLayer::getCircleBlur() const {
+ return impl->paint.circleBlur.values.at(ClassID::Default);
+}
- auto& name = bucketName();
- parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, name);
- });
+void CircleLayer::setCircleBlur(Function<float> value) {
+ impl->paint.circleBlur.values.emplace(ClassID::Default, value);
+}
- return std::move(bucket);
+Function<float> CircleLayer::getCircleOpacity() const {
+ return impl->paint.circleOpacity.values.at(ClassID::Default);
}
-float CircleLayer::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.circleTranslate;
- return paint.circleRadius + util::length(translate[0], translate[1]);
+void CircleLayer::setCircleOpacity(Function<float> value) {
+ impl->paint.circleOpacity.values.emplace(ClassID::Default, value);
}
-bool CircleLayer::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const {
+Function<std::array<float, 2>> CircleLayer::getCircleTranslate() const {
+ return impl->paint.circleTranslate.values.at(ClassID::Default);
+}
- auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.circleTranslate, paint.circleTranslateAnchor, bearing, pixelsToTileUnits);
+void CircleLayer::setCircleTranslate(Function<std::array<float, 2>> value) {
+ impl->paint.circleTranslate.values.emplace(ClassID::Default, value);
+}
- auto circleRadius = paint.circleRadius * pixelsToTileUnits;
+Function<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor() const {
+ return impl->paint.circleTranslateAnchor.values.at(ClassID::Default);
+}
- return util::multiPolygonIntersectsBufferedMultiPoint(
- translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
+void CircleLayer::setCircleTranslateAnchor(Function<TranslateAnchorType> value) {
+ impl->paint.circleTranslateAnchor.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer.hpp b/src/mbgl/layer/circle_layer.hpp
deleted file mode 100644
index 543bae8f19..0000000000
--- a/src/mbgl/layer/circle_layer.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/paint_property.hpp>
-
-namespace mbgl {
-
-class CirclePaintProperties {
-public:
- PaintProperty<float> circleRadius { 5.0f };
- PaintProperty<Color> circleColor { {{ 0, 0, 0, 1 }} };
- PaintProperty<float> circleOpacity { 1.0f };
- PaintProperty<std::array<float, 2>> circleTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> circleTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<float> circleBlur { 0 };
-};
-
-class CircleLayer : public StyleLayer {
-public:
- CircleLayer() : StyleLayer(Type::Circle) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override {};
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- float getQueryRadius() const override;
- bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const override;
-
- CirclePaintProperties paint;
-};
-
-template <>
-inline bool StyleLayer::is<CircleLayer>() const {
- return type == Type::Circle;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer_impl.cpp b/src/mbgl/layer/circle_layer_impl.cpp
new file mode 100644
index 0000000000..b1ba778cd6
--- /dev/null
+++ b/src/mbgl/layer/circle_layer_impl.cpp
@@ -0,0 +1,60 @@
+#include <mbgl/layer/circle_layer_impl.hpp>
+#include <mbgl/style/style_bucket_parameters.hpp>
+#include <mbgl/renderer/circle_bucket.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+void CircleLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void CircleLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool CircleLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = (paint.circleRadius > 0 && paint.circleColor.value[3] > 0 && paint.circleOpacity > 0)
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(StyleBucketParameters& parameters) const {
+ auto bucket = std::make_unique<CircleBucket>(parameters.mode);
+
+ auto& name = bucketName();
+ parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
+ auto geometries = feature.getGeometries();
+ bucket->addGeometry(geometries);
+ parameters.featureIndex.insert(geometries, index, layerName, name);
+ });
+
+ return std::move(bucket);
+}
+
+float CircleLayer::Impl::getQueryRadius() const {
+ const std::array<float, 2>& translate = paint.circleTranslate;
+ return paint.circleRadius + util::length(translate[0], translate[1]);
+}
+
+bool CircleLayer::Impl::queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry, paint.circleTranslate, paint.circleTranslateAnchor, bearing, pixelsToTileUnits);
+
+ auto circleRadius = paint.circleRadius * pixelsToTileUnits;
+
+ return util::multiPolygonIntersectsBufferedMultiPoint(
+ translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer_impl.hpp b/src/mbgl/layer/circle_layer_impl.hpp
new file mode 100644
index 0000000000..1cb19a6205
--- /dev/null
+++ b/src/mbgl/layer/circle_layer_impl.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/circle_layer.hpp>
+#include <mbgl/layer/circle_layer_properties.hpp>
+
+namespace mbgl {
+
+class CircleLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override {};
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ float getQueryRadius() const override;
+ bool queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const override;
+
+ CirclePaintProperties paint;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer_properties.cpp b/src/mbgl/layer/circle_layer_properties.cpp
new file mode 100644
index 0000000000..48d99b579e
--- /dev/null
+++ b/src/mbgl/layer/circle_layer_properties.cpp
@@ -0,0 +1,38 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/circle_layer_properties.hpp>
+
+namespace mbgl {
+
+void CirclePaintProperties::parse(const JSValue& value) {
+ circleRadius.parse("circle-radius", value);
+ circleColor.parse("circle-color", value);
+ circleBlur.parse("circle-blur", value);
+ circleOpacity.parse("circle-opacity", value);
+ circleTranslate.parse("circle-translate", value);
+ circleTranslateAnchor.parse("circle-translate-anchor", value);
+}
+
+void CirclePaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ circleRadius.cascade(parameters);
+ circleColor.cascade(parameters);
+ circleBlur.cascade(parameters);
+ circleOpacity.cascade(parameters);
+ circleTranslate.cascade(parameters);
+ circleTranslateAnchor.cascade(parameters);
+}
+
+bool CirclePaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= circleRadius.calculate(parameters);
+ hasTransitions |= circleColor.calculate(parameters);
+ hasTransitions |= circleBlur.calculate(parameters);
+ hasTransitions |= circleOpacity.calculate(parameters);
+ hasTransitions |= circleTranslate.calculate(parameters);
+ hasTransitions |= circleTranslateAnchor.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/circle_layer_properties.hpp b/src/mbgl/layer/circle_layer_properties.hpp
new file mode 100644
index 0000000000..a88db27605
--- /dev/null
+++ b/src/mbgl/layer/circle_layer_properties.hpp
@@ -0,0 +1,28 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+
+class CirclePaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<float> circleRadius { 5 };
+ PaintProperty<Color> circleColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<float> circleBlur { 0 };
+ PaintProperty<float> circleOpacity { 1 };
+ PaintProperty<std::array<float, 2>> circleTranslate { {{ 0, 0 }} };
+ PaintProperty<TranslateAnchorType> circleTranslateAnchor { TranslateAnchorType::Map };
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/custom_layer.cpp b/src/mbgl/layer/custom_layer.cpp
index 3b683bf833..a33176e7f9 100644
--- a/src/mbgl/layer/custom_layer.cpp
+++ b/src/mbgl/layer/custom_layer.cpp
@@ -1,67 +1,22 @@
#include <mbgl/layer/custom_layer.hpp>
-#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/map/transform_state.hpp>
+#include <mbgl/layer/custom_layer_impl.hpp>
namespace mbgl {
-CustomLayer::CustomLayer(const std::string& id_,
- CustomLayerInitializeFunction initializeFn_,
- CustomLayerRenderFunction renderFn_,
- CustomLayerDeinitializeFunction deinitializeFn_,
- void* context_)
- : StyleLayer(Type::Custom) {
- id = id_;
- initializeFn = initializeFn_;
- renderFn = renderFn_;
- deinitializeFn = deinitializeFn_;
- context = context_;
+CustomLayer::CustomLayer(const std::string& layerID,
+ CustomLayerInitializeFunction init,
+ CustomLayerRenderFunction render,
+ CustomLayerDeinitializeFunction deinit,
+ void* context)
+ : Layer(Type::Custom, std::make_unique<Impl>(layerID, init, render, deinit, context))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
}
-CustomLayer::CustomLayer(const CustomLayer& other)
- : StyleLayer(other) {
- id = other.id;
- // Don't copy anything else.
+CustomLayer::CustomLayer(const Impl& other)
+ : Layer(Type::Custom, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
}
-CustomLayer::~CustomLayer() {
- if (deinitializeFn) {
- deinitializeFn(context);
- }
-}
-
-void CustomLayer::initialize() {
- assert(initializeFn);
- initializeFn(context);
-}
-
-void CustomLayer::render(const TransformState& state) const {
- assert(renderFn);
-
- CustomLayerRenderParameters parameters;
-
- parameters.width = state.getWidth();
- parameters.height = state.getHeight();
- parameters.latitude = state.getLatLng().latitude;
- parameters.longitude = state.getLatLng().longitude;
- parameters.zoom = state.getZoom();
- parameters.bearing = -state.getAngle() * util::RAD2DEG;
- parameters.pitch = state.getPitch();
- parameters.altitude = state.getAltitude();
-
- renderFn(context, parameters);
-}
-
-bool CustomLayer::recalculate(const StyleCalculationParameters&) {
- passes = RenderPass::Translucent;
- return false;
-}
-
-std::unique_ptr<StyleLayer> CustomLayer::clone() const {
- return std::make_unique<CustomLayer>(*this);
-}
-
-std::unique_ptr<Bucket> CustomLayer::createBucket(StyleBucketParameters&) const {
- return nullptr;
-}
+CustomLayer::~CustomLayer() = default;
} // namespace mbgl
diff --git a/src/mbgl/layer/custom_layer_impl.cpp b/src/mbgl/layer/custom_layer_impl.cpp
new file mode 100644
index 0000000000..8a08c804ed
--- /dev/null
+++ b/src/mbgl/layer/custom_layer_impl.cpp
@@ -0,0 +1,66 @@
+#include <mbgl/layer/custom_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/map/transform_state.hpp>
+
+namespace mbgl {
+
+CustomLayer::Impl::Impl(const std::string& id_,
+ CustomLayerInitializeFunction initializeFn_,
+ CustomLayerRenderFunction renderFn_,
+ CustomLayerDeinitializeFunction deinitializeFn_,
+ void* context_) {
+ id = id_;
+ initializeFn = initializeFn_;
+ renderFn = renderFn_;
+ deinitializeFn = deinitializeFn_;
+ context = context_;
+}
+
+CustomLayer::Impl::Impl(const CustomLayer::Impl& other)
+ : Layer::Impl(other) {
+ id = other.id;
+ // Don't copy anything else.
+}
+
+CustomLayer::Impl::~Impl() {
+ if (deinitializeFn) {
+ deinitializeFn(context);
+ }
+}
+
+std::unique_ptr<Layer> CustomLayer::Impl::clone() const {
+ return std::make_unique<CustomLayer>(*this);
+}
+
+void CustomLayer::Impl::initialize() {
+ assert(initializeFn);
+ initializeFn(context);
+}
+
+void CustomLayer::Impl::render(const TransformState& state) const {
+ assert(renderFn);
+
+ CustomLayerRenderParameters parameters;
+
+ parameters.width = state.getWidth();
+ parameters.height = state.getHeight();
+ parameters.latitude = state.getLatLng().latitude;
+ parameters.longitude = state.getLatLng().longitude;
+ parameters.zoom = state.getZoom();
+ parameters.bearing = -state.getAngle() * util::RAD2DEG;
+ parameters.pitch = state.getPitch();
+ parameters.altitude = state.getAltitude();
+
+ renderFn(context, parameters);
+}
+
+bool CustomLayer::Impl::recalculate(const StyleCalculationParameters&) {
+ passes = RenderPass::Translucent;
+ return false;
+}
+
+std::unique_ptr<Bucket> CustomLayer::Impl::createBucket(StyleBucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/custom_layer.hpp b/src/mbgl/layer/custom_layer_impl.hpp
index 93d9c85e6c..09709a2f9d 100644
--- a/src/mbgl/layer/custom_layer.hpp
+++ b/src/mbgl/layer/custom_layer_impl.hpp
@@ -1,27 +1,28 @@
#pragma once
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/custom_layer.hpp>
namespace mbgl {
class TransformState;
-class CustomLayer : public StyleLayer {
+class CustomLayer::Impl : public Layer::Impl {
public:
- CustomLayer(const std::string& id,
- CustomLayerInitializeFunction,
- CustomLayerRenderFunction,
- CustomLayerDeinitializeFunction,
- void* context);
+ Impl(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
+ CustomLayerDeinitializeFunction,
+ void* context);
- CustomLayer(const CustomLayer&);
- ~CustomLayer();
+ Impl(const Impl&);
+ ~Impl() final;
void initialize();
void render(const TransformState&) const;
private:
- std::unique_ptr<StyleLayer> clone() const final;
+ std::unique_ptr<Layer> clone() const override;
void parseLayout(const JSValue&) final {}
void parsePaints(const JSValue&) final {}
@@ -37,9 +38,4 @@ private:
void* context = nullptr;
};
-template <>
-inline bool StyleLayer::is<CustomLayer>() const {
- return type == Type::Custom;
-}
-
} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer.cpp b/src/mbgl/layer/fill_layer.cpp
index 850bac4ab4..9a376089df 100644
--- a/src/mbgl/layer/fill_layer.cpp
+++ b/src/mbgl/layer/fill_layer.cpp
@@ -1,90 +1,101 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/fill_layer.hpp>
-#include <mbgl/style/style_bucket_parameters.hpp>
-#include <mbgl/renderer/fill_bucket.hpp>
-#include <mbgl/geometry/feature_index.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/intersection_tests.hpp>
+#include <mbgl/layer/fill_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> FillLayer::clone() const {
+FillLayer::FillLayer(const std::string& layerID)
+ : Layer(Type::Fill, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+FillLayer::FillLayer(const Impl& other)
+ : Layer(Type::Fill, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+FillLayer::~FillLayer() = default;
+
+std::unique_ptr<Layer> FillLayer::Impl::clone() const {
return std::make_unique<FillLayer>(*this);
}
-void FillLayer::parsePaints(const JSValue& layer) {
- paint.fillAntialias.parse("fill-antialias", layer);
- paint.fillOpacity.parse("fill-opacity", layer);
- paint.fillColor.parse("fill-color", layer);
- paint.fillOutlineColor.parse("fill-outline-color", layer);
- paint.fillTranslate.parse("fill-translate", layer);
- paint.fillTranslateAnchor.parse("fill-translate-anchor", layer);
- paint.fillPattern.parse("fill-pattern", layer);
+// Source
+
+void FillLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
}
-void FillLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.fillAntialias.cascade(parameters);
- paint.fillOpacity.cascade(parameters);
- paint.fillColor.cascade(parameters);
- paint.fillOutlineColor.cascade(parameters);
- paint.fillTranslate.cascade(parameters);
- paint.fillTranslateAnchor.cascade(parameters);
- paint.fillPattern.cascade(parameters);
+const std::string& FillLayer::getSourceID() const {
+ return impl->source;
}
-bool FillLayer::recalculate(const StyleCalculationParameters& parameters) {
- bool hasTransitions = false;
+const std::string& FillLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
- hasTransitions |= paint.fillAntialias.calculate(parameters);
- hasTransitions |= paint.fillOpacity.calculate(parameters);
- hasTransitions |= paint.fillColor.calculate(parameters);
- hasTransitions |= paint.fillOutlineColor.calculate(parameters);
- hasTransitions |= paint.fillTranslate.calculate(parameters);
- hasTransitions |= paint.fillTranslateAnchor.calculate(parameters);
- hasTransitions |= paint.fillPattern.calculate(parameters);
+// Layout properties
- passes = RenderPass::None;
- if (paint.fillAntialias) {
- passes |= RenderPass::Translucent;
- }
+// Paint properties
- if (!paint.fillPattern.value.from.empty() || (paint.fillColor.value[3] * paint.fillOpacity) < 1.0f) {
- passes |= RenderPass::Translucent;
- } else {
- passes |= RenderPass::Opaque;
- }
+Function<bool> FillLayer::getFillAntialias() const {
+ return impl->paint.fillAntialias.values.at(ClassID::Default);
+}
- return hasTransitions;
+void FillLayer::setFillAntialias(Function<bool> value) {
+ impl->paint.fillAntialias.values.emplace(ClassID::Default, value);
}
-std::unique_ptr<Bucket> FillLayer::createBucket(StyleBucketParameters& parameters) const {
- auto bucket = std::make_unique<FillBucket>();
+Function<float> FillLayer::getFillOpacity() const {
+ return impl->paint.fillOpacity.values.at(ClassID::Default);
+}
- auto& name = bucketName();
- parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, name);
- });
+void FillLayer::setFillOpacity(Function<float> value) {
+ impl->paint.fillOpacity.values.emplace(ClassID::Default, value);
+}
- return std::move(bucket);
+Function<Color> FillLayer::getFillColor() const {
+ return impl->paint.fillColor.values.at(ClassID::Default);
}
-float FillLayer::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.fillTranslate;
- return util::length(translate[0], translate[1]);
+void FillLayer::setFillColor(Function<Color> value) {
+ impl->paint.fillColor.values.emplace(ClassID::Default, value);
}
-bool FillLayer::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const {
+Function<Color> FillLayer::getFillOutlineColor() const {
+ return impl->paint.fillOutlineColor.values.at(ClassID::Default);
+}
- auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
+void FillLayer::setFillOutlineColor(Function<Color> value) {
+ impl->paint.fillOutlineColor.values.emplace(ClassID::Default, value);
+}
+
+Function<std::array<float, 2>> FillLayer::getFillTranslate() const {
+ return impl->paint.fillTranslate.values.at(ClassID::Default);
+}
+
+void FillLayer::setFillTranslate(Function<std::array<float, 2>> value) {
+ impl->paint.fillTranslate.values.emplace(ClassID::Default, value);
+}
+
+Function<TranslateAnchorType> FillLayer::getFillTranslateAnchor() const {
+ return impl->paint.fillTranslateAnchor.values.at(ClassID::Default);
+}
+
+void FillLayer::setFillTranslateAnchor(Function<TranslateAnchorType> value) {
+ impl->paint.fillTranslateAnchor.values.emplace(ClassID::Default, value);
+}
+
+Function<std::string> FillLayer::getFillPattern() const {
+ return impl->paint.fillPattern.values.at(ClassID::Default);
+}
- return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
+void FillLayer::setFillPattern(Function<std::string> value) {
+ impl->paint.fillPattern.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer.hpp b/src/mbgl/layer/fill_layer.hpp
deleted file mode 100644
index eb8a507239..0000000000
--- a/src/mbgl/layer/fill_layer.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/paint_property.hpp>
-
-namespace mbgl {
-
-class FillPaintProperties {
-public:
- PaintProperty<bool> fillAntialias { true };
- PaintProperty<float> fillOpacity { 1.0f };
- PaintProperty<Color> fillColor { {{ 0, 0, 0, 1 }} };
- PaintProperty<Color> fillOutlineColor { {{ 0, 0, 0, -1 }} };
- PaintProperty<std::array<float, 2>> fillTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> fillTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<std::string, CrossFadedFunctionEvaluator> fillPattern { "" };
-};
-
-class FillLayer : public StyleLayer {
-public:
- FillLayer() : StyleLayer(Type::Fill) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override {};
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- float getQueryRadius() const override;
- bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const override;
-
- FillPaintProperties paint;
-};
-
-template <>
-inline bool StyleLayer::is<FillLayer>() const {
- return type == Type::Fill;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer_impl.cpp b/src/mbgl/layer/fill_layer_impl.cpp
new file mode 100644
index 0000000000..21f482922d
--- /dev/null
+++ b/src/mbgl/layer/fill_layer_impl.cpp
@@ -0,0 +1,66 @@
+#include <mbgl/layer/fill_layer_impl.hpp>
+#include <mbgl/style/style_bucket_parameters.hpp>
+#include <mbgl/renderer/fill_bucket.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+void FillLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void FillLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool FillLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = RenderPass::None;
+
+ if (paint.fillAntialias) {
+ passes |= RenderPass::Translucent;
+ }
+
+ if (!paint.fillPattern.value.from.empty() || (paint.fillColor.value[3] * paint.fillOpacity) < 1.0f) {
+ passes |= RenderPass::Translucent;
+ } else {
+ passes |= RenderPass::Opaque;
+ }
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> FillLayer::Impl::createBucket(StyleBucketParameters& parameters) const {
+ auto bucket = std::make_unique<FillBucket>();
+
+ auto& name = bucketName();
+ parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
+ auto geometries = feature.getGeometries();
+ bucket->addGeometry(geometries);
+ parameters.featureIndex.insert(geometries, index, layerName, name);
+ });
+
+ return std::move(bucket);
+}
+
+float FillLayer::Impl::getQueryRadius() const {
+ const std::array<float, 2>& translate = paint.fillTranslate;
+ return util::length(translate[0], translate[1]);
+}
+
+bool FillLayer::Impl::queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
+
+ return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer_impl.hpp b/src/mbgl/layer/fill_layer_impl.hpp
new file mode 100644
index 0000000000..2af0d6491d
--- /dev/null
+++ b/src/mbgl/layer/fill_layer_impl.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/fill_layer.hpp>
+#include <mbgl/layer/fill_layer_properties.hpp>
+
+namespace mbgl {
+
+class FillLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override {};
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ float getQueryRadius() const override;
+ bool queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const override;
+
+ FillPaintProperties paint;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer_properties.cpp b/src/mbgl/layer/fill_layer_properties.cpp
new file mode 100644
index 0000000000..e0d4f10bc9
--- /dev/null
+++ b/src/mbgl/layer/fill_layer_properties.cpp
@@ -0,0 +1,41 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/fill_layer_properties.hpp>
+
+namespace mbgl {
+
+void FillPaintProperties::parse(const JSValue& value) {
+ fillAntialias.parse("fill-antialias", value);
+ fillOpacity.parse("fill-opacity", value);
+ fillColor.parse("fill-color", value);
+ fillOutlineColor.parse("fill-outline-color", value);
+ fillTranslate.parse("fill-translate", value);
+ fillTranslateAnchor.parse("fill-translate-anchor", value);
+ fillPattern.parse("fill-pattern", value);
+}
+
+void FillPaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ fillAntialias.cascade(parameters);
+ fillOpacity.cascade(parameters);
+ fillColor.cascade(parameters);
+ fillOutlineColor.cascade(parameters);
+ fillTranslate.cascade(parameters);
+ fillTranslateAnchor.cascade(parameters);
+ fillPattern.cascade(parameters);
+}
+
+bool FillPaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= fillAntialias.calculate(parameters);
+ hasTransitions |= fillOpacity.calculate(parameters);
+ hasTransitions |= fillColor.calculate(parameters);
+ hasTransitions |= fillOutlineColor.calculate(parameters);
+ hasTransitions |= fillTranslate.calculate(parameters);
+ hasTransitions |= fillTranslateAnchor.calculate(parameters);
+ hasTransitions |= fillPattern.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/fill_layer_properties.hpp b/src/mbgl/layer/fill_layer_properties.hpp
new file mode 100644
index 0000000000..fb327a2d6c
--- /dev/null
+++ b/src/mbgl/layer/fill_layer_properties.hpp
@@ -0,0 +1,29 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+
+class FillPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<bool> fillAntialias { true };
+ PaintProperty<float> fillOpacity { 1 };
+ PaintProperty<Color> fillColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<Color> fillOutlineColor { {{ 0, 0, 0, -1 }} };
+ PaintProperty<std::array<float, 2>> fillTranslate { {{ 0, 0 }} };
+ PaintProperty<TranslateAnchorType> fillTranslateAnchor { TranslateAnchorType::Map };
+ PaintProperty<std::string, CrossFadedFunctionEvaluator> fillPattern { "" };
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/layer.cpp b/src/mbgl/layer/layer.cpp
new file mode 100644
index 0000000000..154fbfe31f
--- /dev/null
+++ b/src/mbgl/layer/layer.cpp
@@ -0,0 +1,32 @@
+#include <mbgl/style/layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
+
+namespace mbgl {
+
+Layer::Layer(Type type_, std::unique_ptr<Impl> baseImpl_)
+ : baseImpl(std::move(baseImpl_)), type(type_) {
+}
+
+Layer::~Layer() = default;
+
+const std::string& Layer::getID() const {
+ return baseImpl->id;
+}
+
+VisibilityType Layer::getVisibility() const {
+ return baseImpl->visibility;
+}
+
+void Layer::setVisibility(VisibilityType value) {
+ baseImpl->visibility = value;
+}
+
+std::unique_ptr<Layer> Layer::copy(const std::string& id,
+ const std::string& ref) const {
+ std::unique_ptr<Layer> result = baseImpl->clone();
+ result->baseImpl->id = id;
+ result->baseImpl->ref = ref;
+ return result;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/layer_impl.cpp b/src/mbgl/layer/layer_impl.cpp
new file mode 100644
index 0000000000..315a1cb1b1
--- /dev/null
+++ b/src/mbgl/layer/layer_impl.cpp
@@ -0,0 +1,17 @@
+#include <mbgl/layer/layer_impl.hpp>
+
+namespace mbgl {
+
+const std::string& Layer::Impl::bucketName() const {
+ return ref.empty() ? id : ref;
+}
+
+bool Layer::Impl::hasRenderPass(RenderPass pass) const {
+ return bool(passes & pass);
+}
+
+bool Layer::Impl::needsRendering() const {
+ return passes != RenderPass::None && visibility != VisibilityType::None;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/layer_impl.hpp b/src/mbgl/layer/layer_impl.hpp
new file mode 100644
index 0000000000..3d6b5cccfd
--- /dev/null
+++ b/src/mbgl/layer/layer_impl.hpp
@@ -0,0 +1,88 @@
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+#include <mbgl/style/types.hpp>
+#include <mbgl/style/filter.hpp>
+#include <mbgl/renderer/render_pass.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/rapidjson.hpp>
+#include <mbgl/tile/geometry_tile.hpp>
+
+#include <memory>
+#include <string>
+#include <limits>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+class StyleBucketParameters;
+class Bucket;
+
+/**
+ * `Layer::Impl` contains the internal implementation of `Layer`: the details that need to be accessible to other parts
+ * of the code, but hidden from the public API. Like `Layer`, it is an abstract base class, with derived classes for
+ * each layer type.
+ *
+ * Members that are public in `Layer` are part of the public API for all layers.
+ * Members that are public in `FooLayer` are part of the public API for "foo" layers.
+ * Members that are public in `Layer::Impl` are part of the internal API for all layers.
+ * Members that are public in `FooLayer::Impl` are part of the internal API for "foo" layers.
+ * Members that are private in `FooLayer::Impl` are internal to "foo" layers.
+ */
+class Layer::Impl {
+public:
+ virtual ~Impl() = default;
+
+ // Create an identical copy of this layer.
+ virtual std::unique_ptr<Layer> clone() const = 0;
+
+ virtual void parseLayout(const JSValue& value) = 0;
+ virtual void parsePaints(const JSValue& value) = 0;
+
+ // If the layer has a ref, the ref. Otherwise, the id.
+ const std::string& bucketName() const;
+
+ // Partially evaluate paint properties based on a set of classes.
+ virtual void cascade(const StyleCascadeParameters&) = 0;
+
+ // Fully evaluate cascaded paint properties based on a zoom level.
+ // Returns true if any paint properties have active transitions.
+ virtual bool recalculate(const StyleCalculationParameters&) = 0;
+
+ virtual std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const = 0;
+
+ // Checks whether this layer needs to be rendered in the given render pass.
+ bool hasRenderPass(RenderPass) const;
+
+ // Checks whether this layer can be rendered.
+ bool needsRendering() const;
+
+ virtual float getQueryRadius() const { return 0; }
+ virtual bool queryIntersectsGeometry(
+ const GeometryCollection&,
+ const GeometryCollection&,
+ const float,
+ const float) const { return false; };
+
+public:
+ std::string id;
+ std::string ref;
+ std::string source;
+ std::string sourceLayer;
+ Filter filter;
+ float minZoom = -std::numeric_limits<float>::infinity();
+ float maxZoom = std::numeric_limits<float>::infinity();
+ VisibilityType visibility = VisibilityType::Visible;
+
+protected:
+ Impl() = default;
+ Impl(const Impl&) = default;
+ Impl& operator=(const Impl&) = delete;
+
+ // Stores what render passes this layer is currently enabled for. This depends on the
+ // evaluated StyleProperties object and is updated accordingly.
+ RenderPass passes = RenderPass::None;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer.cpp b/src/mbgl/layer/line_layer.cpp
index d1d377462a..0064a0b8da 100644
--- a/src/mbgl/layer/line_layer.cpp
+++ b/src/mbgl/layer/line_layer.cpp
@@ -1,156 +1,153 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/line_layer.hpp>
-#include <mbgl/style/style_bucket_parameters.hpp>
-#include <mbgl/renderer/line_bucket.hpp>
-#include <mbgl/geometry/feature_index.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/intersection_tests.hpp>
+#include <mbgl/layer/line_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> LineLayer::clone() const {
+LineLayer::LineLayer(const std::string& layerID)
+ : Layer(Type::Line, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+LineLayer::LineLayer(const Impl& other)
+ : Layer(Type::Line, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+LineLayer::~LineLayer() = default;
+
+std::unique_ptr<Layer> LineLayer::Impl::clone() const {
return std::make_unique<LineLayer>(*this);
}
-void LineLayer::parseLayout(const JSValue& value) {
- layout.lineCap.parse("line-cap", value);
- layout.lineJoin.parse("line-join", value);
- layout.lineMiterLimit.parse("line-miter-limit", value);
- layout.lineRoundLimit.parse("line-round-limit", value);
-}
-
-void LineLayer::parsePaints(const JSValue& layer) {
- paint.lineOpacity.parse("line-opacity", layer);
- paint.lineColor.parse("line-color", layer);
- paint.lineTranslate.parse("line-translate", layer);
- paint.lineTranslateAnchor.parse("line-translate-anchor", layer);
- paint.lineWidth.parse("line-width", layer);
- paint.lineGapWidth.parse("line-gap-width", layer);
- paint.lineOffset.parse("line-offset", layer);
- paint.lineBlur.parse("line-blur", layer);
- paint.lineDasharray.parse("line-dasharray", layer);
- paint.linePattern.parse("line-pattern", layer);
+// Source
+
+void LineLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& LineLayer::getSourceID() const {
+ return impl->source;
+}
+
+const std::string& LineLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Layout properties
+
+Function<LineCapType> LineLayer::getLineCap() const {
+ return *impl->layout.lineCap.parsedValue;
+}
+
+void LineLayer::setLineCap(Function<LineCapType> value) {
+ impl->layout.lineCap.parsedValue = value;
+}
+Function<LineJoinType> LineLayer::getLineJoin() const {
+ return *impl->layout.lineJoin.parsedValue;
+}
+
+void LineLayer::setLineJoin(Function<LineJoinType> value) {
+ impl->layout.lineJoin.parsedValue = value;
+}
+Function<float> LineLayer::getLineMiterLimit() const {
+ return *impl->layout.lineMiterLimit.parsedValue;
}
-void LineLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.lineOpacity.cascade(parameters);
- paint.lineColor.cascade(parameters);
- paint.lineTranslate.cascade(parameters);
- paint.lineTranslateAnchor.cascade(parameters);
- paint.lineWidth.cascade(parameters);
- paint.lineGapWidth.cascade(parameters);
- paint.lineOffset.cascade(parameters);
- paint.lineBlur.cascade(parameters);
- paint.lineDasharray.cascade(parameters);
- paint.linePattern.cascade(parameters);
+void LineLayer::setLineMiterLimit(Function<float> value) {
+ impl->layout.lineMiterLimit.parsedValue = value;
+}
+Function<float> LineLayer::getLineRoundLimit() const {
+ return *impl->layout.lineRoundLimit.parsedValue;
}
-bool LineLayer::recalculate(const StyleCalculationParameters& parameters) {
- // for scaling dasharrays
- StyleCalculationParameters dashArrayParams = parameters;
- dashArrayParams.z = std::floor(dashArrayParams.z);
- paint.lineWidth.calculate(dashArrayParams);
- dashLineWidth = paint.lineWidth;
+void LineLayer::setLineRoundLimit(Function<float> value) {
+ impl->layout.lineRoundLimit.parsedValue = value;
+}
- bool hasTransitions = false;
+// Paint properties
- hasTransitions |= paint.lineOpacity.calculate(parameters);
- hasTransitions |= paint.lineColor.calculate(parameters);
- hasTransitions |= paint.lineTranslate.calculate(parameters);
- hasTransitions |= paint.lineTranslateAnchor.calculate(parameters);
- hasTransitions |= paint.lineWidth.calculate(parameters);
- hasTransitions |= paint.lineGapWidth.calculate(parameters);
- hasTransitions |= paint.lineOffset.calculate(parameters);
- hasTransitions |= paint.lineBlur.calculate(parameters);
- hasTransitions |= paint.lineDasharray.calculate(parameters);
- hasTransitions |= paint.linePattern.calculate(parameters);
+Function<float> LineLayer::getLineOpacity() const {
+ return impl->paint.lineOpacity.values.at(ClassID::Default);
+}
- passes = (paint.lineOpacity > 0 && paint.lineColor.value[3] > 0 && paint.lineWidth > 0)
- ? RenderPass::Translucent : RenderPass::None;
+void LineLayer::setLineOpacity(Function<float> value) {
+ impl->paint.lineOpacity.values.emplace(ClassID::Default, value);
+}
- return hasTransitions;
+Function<Color> LineLayer::getLineColor() const {
+ return impl->paint.lineColor.values.at(ClassID::Default);
}
-std::unique_ptr<Bucket> LineLayer::createBucket(StyleBucketParameters& parameters) const {
- auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor());
+void LineLayer::setLineColor(Function<Color> value) {
+ impl->paint.lineColor.values.emplace(ClassID::Default, value);
+}
- bucket->layout = layout;
+Function<std::array<float, 2>> LineLayer::getLineTranslate() const {
+ return impl->paint.lineTranslate.values.at(ClassID::Default);
+}
- StyleCalculationParameters p(parameters.tileID.overscaledZ);
- bucket->layout.lineCap.calculate(p);
- bucket->layout.lineJoin.calculate(p);
- bucket->layout.lineMiterLimit.calculate(p);
- bucket->layout.lineRoundLimit.calculate(p);
+void LineLayer::setLineTranslate(Function<std::array<float, 2>> value) {
+ impl->paint.lineTranslate.values.emplace(ClassID::Default, value);
+}
- auto& name = bucketName();
- parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, name);
- });
+Function<TranslateAnchorType> LineLayer::getLineTranslateAnchor() const {
+ return impl->paint.lineTranslateAnchor.values.at(ClassID::Default);
+}
- return std::move(bucket);
+void LineLayer::setLineTranslateAnchor(Function<TranslateAnchorType> value) {
+ impl->paint.lineTranslateAnchor.values.emplace(ClassID::Default, value);
}
+Function<float> LineLayer::getLineWidth() const {
+ return impl->paint.lineWidth.values.at(ClassID::Default);
+}
-float LineLayer::getLineWidth() const {
- if (paint.lineGapWidth > 0) {
- return paint.lineGapWidth + 2 * paint.lineWidth;
- } else {
- return paint.lineWidth;
- }
+void LineLayer::setLineWidth(Function<float> value) {
+ impl->paint.lineWidth.values.emplace(ClassID::Default, value);
}
-optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const double offset) {
- if (offset == 0) return {};
+Function<float> LineLayer::getLineGapWidth() const {
+ return impl->paint.lineGapWidth.values.at(ClassID::Default);
+}
- GeometryCollection newRings;
- Point<double> zero(0, 0);
- for (const auto& ring : rings) {
- newRings.emplace_back();
- auto& newRing = newRings.back();
+void LineLayer::setLineGapWidth(Function<float> value) {
+ impl->paint.lineGapWidth.values.emplace(ClassID::Default, value);
+}
- for (auto i = ring.begin(); i != ring.end(); i++) {
- auto& p = *i;
-
- Point<double> aToB = i == ring.begin() ?
- zero :
- util::perp(util::unit(convertPoint<double>(p - *(i - 1))));
- Point<double> bToC = i + 1 == ring.end() ?
- zero :
- util::perp(util::unit(convertPoint<double>(*(i + 1) - p)));
- Point<double> extrude = util::unit(aToB + bToC);
-
- const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
- extrude *= (1.0 / cosHalfAngle);
+Function<float> LineLayer::getLineOffset() const {
+ return impl->paint.lineOffset.values.at(ClassID::Default);
+}
- newRing.push_back(convertPoint<int16_t>(extrude * offset) + p);
- }
- }
+void LineLayer::setLineOffset(Function<float> value) {
+ impl->paint.lineOffset.values.emplace(ClassID::Default, value);
+}
- return newRings;
+Function<float> LineLayer::getLineBlur() const {
+ return impl->paint.lineBlur.values.at(ClassID::Default);
}
-float LineLayer::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.lineTranslate;
- return getLineWidth() / 2.0 + std::abs(paint.lineOffset) + util::length(translate[0], translate[1]);
+void LineLayer::setLineBlur(Function<float> value) {
+ impl->paint.lineBlur.values.emplace(ClassID::Default, value);
}
-bool LineLayer::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const {
+Function<std::vector<float>> LineLayer::getLineDasharray() const {
+ return impl->paint.lineDasharray.values.at(ClassID::Default);
+}
- const float halfWidth = getLineWidth() / 2.0 * pixelsToTileUnits;
+void LineLayer::setLineDasharray(Function<std::vector<float>> value) {
+ impl->paint.lineDasharray.values.emplace(ClassID::Default, value);
+}
- auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
- auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
+Function<std::string> LineLayer::getLinePattern() const {
+ return impl->paint.linePattern.values.at(ClassID::Default);
+}
- return util::multiPolygonIntersectsBufferedMultiLine(
- translatedQueryGeometry.value_or(queryGeometry),
- offsetGeometry.value_or(geometry),
- halfWidth);
+void LineLayer::setLinePattern(Function<std::string> value) {
+ impl->paint.linePattern.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer.hpp b/src/mbgl/layer/line_layer.hpp
deleted file mode 100644
index 60bd9fad55..0000000000
--- a/src/mbgl/layer/line_layer.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/layout_property.hpp>
-#include <mbgl/style/paint_property.hpp>
-
-namespace mbgl {
-
-class LineLayoutProperties {
-public:
- LayoutProperty<LineCapType> lineCap { LineCapType::Butt };
- LayoutProperty<LineJoinType> lineJoin { LineJoinType::Miter };
- LayoutProperty<float> lineMiterLimit { 2.0f };
- LayoutProperty<float> lineRoundLimit { 1.0f };
-};
-
-class LinePaintProperties {
-public:
- PaintProperty<float> lineOpacity { 1.0f };
- PaintProperty<Color> lineColor { {{ 0, 0, 0, 1 }} };
- PaintProperty<std::array<float, 2>> lineTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> lineTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<float> lineWidth { 1 };
- PaintProperty<float> lineGapWidth { 0 };
- PaintProperty<float> lineBlur { 0 };
- PaintProperty<float> lineOffset { 0 };
- PaintProperty<std::vector<float>, CrossFadedFunctionEvaluator> lineDasharray { {} };
- PaintProperty<std::string, CrossFadedFunctionEvaluator> linePattern { "" };
-};
-
-class LineLayer : public StyleLayer {
-public:
- LineLayer() : StyleLayer(Type::Line) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override;
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- float getQueryRadius() const override;
- bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
- const GeometryCollection& geometry,
- const float bearing,
- const float pixelsToTileUnits) const override;
-
- LineLayoutProperties layout;
- LinePaintProperties paint;
-
- float dashLineWidth = 1;
-private:
- float getLineWidth() const;
-};
-
-template <>
-inline bool StyleLayer::is<LineLayer>() const {
- return type == Type::Line;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer_impl.cpp b/src/mbgl/layer/line_layer_impl.cpp
new file mode 100644
index 0000000000..aee1687046
--- /dev/null
+++ b/src/mbgl/layer/line_layer_impl.cpp
@@ -0,0 +1,114 @@
+#include <mbgl/layer/line_layer_impl.hpp>
+#include <mbgl/style/style_bucket_parameters.hpp>
+#include <mbgl/renderer/line_bucket.hpp>
+#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/util/math.hpp>
+#include <mbgl/util/intersection_tests.hpp>
+
+namespace mbgl {
+
+void LineLayer::Impl::parseLayout(const JSValue& value) {
+ layout.parse(value);
+}
+
+void LineLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void LineLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool LineLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ // for scaling dasharrays
+ StyleCalculationParameters dashArrayParams = parameters;
+ dashArrayParams.z = std::floor(dashArrayParams.z);
+ paint.lineWidth.calculate(dashArrayParams);
+ dashLineWidth = paint.lineWidth;
+
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = (paint.lineOpacity > 0 && paint.lineColor.value[3] > 0 && paint.lineWidth > 0)
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> LineLayer::Impl::createBucket(StyleBucketParameters& parameters) const {
+ auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor());
+
+ bucket->layout = layout;
+ bucket->layout.recalculate(StyleCalculationParameters(parameters.tileID.overscaledZ));
+
+ auto& name = bucketName();
+ parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
+ auto geometries = feature.getGeometries();
+ bucket->addGeometry(geometries);
+ parameters.featureIndex.insert(geometries, index, layerName, name);
+ });
+
+ return std::move(bucket);
+}
+
+float LineLayer::Impl::getLineWidth() const {
+ if (paint.lineGapWidth > 0) {
+ return paint.lineGapWidth + 2 * paint.lineWidth;
+ } else {
+ return paint.lineWidth;
+ }
+}
+
+optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const double offset) {
+ if (offset == 0) return {};
+
+ GeometryCollection newRings;
+ Point<double> zero(0, 0);
+ for (const auto& ring : rings) {
+ newRings.emplace_back();
+ auto& newRing = newRings.back();
+
+ for (auto i = ring.begin(); i != ring.end(); i++) {
+ auto& p = *i;
+
+ Point<double> aToB = i == ring.begin() ?
+ zero :
+ util::perp(util::unit(convertPoint<double>(p - *(i - 1))));
+ Point<double> bToC = i + 1 == ring.end() ?
+ zero :
+ util::perp(util::unit(convertPoint<double>(*(i + 1) - p)));
+ Point<double> extrude = util::unit(aToB + bToC);
+
+ const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
+ extrude *= (1.0 / cosHalfAngle);
+
+ newRing.push_back(convertPoint<int16_t>(extrude * offset) + p);
+ }
+ }
+
+ return newRings;
+}
+
+float LineLayer::Impl::getQueryRadius() const {
+ const std::array<float, 2>& translate = paint.lineTranslate;
+ return getLineWidth() / 2.0 + std::abs(paint.lineOffset) + util::length(translate[0], translate[1]);
+}
+
+bool LineLayer::Impl::queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const {
+
+ const float halfWidth = getLineWidth() / 2.0 * pixelsToTileUnits;
+
+ auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
+ queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
+ auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
+
+ return util::multiPolygonIntersectsBufferedMultiLine(
+ translatedQueryGeometry.value_or(queryGeometry),
+ offsetGeometry.value_or(geometry),
+ halfWidth);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer_impl.hpp b/src/mbgl/layer/line_layer_impl.hpp
new file mode 100644
index 0000000000..b602df52fa
--- /dev/null
+++ b/src/mbgl/layer/line_layer_impl.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/line_layer.hpp>
+#include <mbgl/layer/line_layer_properties.hpp>
+
+namespace mbgl {
+
+class LineLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override;
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ float getQueryRadius() const override;
+ bool queryIntersectsGeometry(
+ const GeometryCollection& queryGeometry,
+ const GeometryCollection& geometry,
+ const float bearing,
+ const float pixelsToTileUnits) const override;
+
+ LineLayoutProperties layout;
+ LinePaintProperties paint;
+
+ // Special case
+ float dashLineWidth = 1;
+
+private:
+ float getLineWidth() const;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer_properties.cpp b/src/mbgl/layer/line_layer_properties.cpp
new file mode 100644
index 0000000000..4941a1ecd2
--- /dev/null
+++ b/src/mbgl/layer/line_layer_properties.cpp
@@ -0,0 +1,64 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/line_layer_properties.hpp>
+
+namespace mbgl {
+
+void LineLayoutProperties::parse(const JSValue& value) {
+ lineCap.parse("line-cap", value);
+ lineJoin.parse("line-join", value);
+ lineMiterLimit.parse("line-miter-limit", value);
+ lineRoundLimit.parse("line-round-limit", value);
+}
+
+void LineLayoutProperties::recalculate(const StyleCalculationParameters& parameters) {
+ lineCap.calculate(parameters);
+ lineJoin.calculate(parameters);
+ lineMiterLimit.calculate(parameters);
+ lineRoundLimit.calculate(parameters);
+}
+
+void LinePaintProperties::parse(const JSValue& value) {
+ lineOpacity.parse("line-opacity", value);
+ lineColor.parse("line-color", value);
+ lineTranslate.parse("line-translate", value);
+ lineTranslateAnchor.parse("line-translate-anchor", value);
+ lineWidth.parse("line-width", value);
+ lineGapWidth.parse("line-gap-width", value);
+ lineOffset.parse("line-offset", value);
+ lineBlur.parse("line-blur", value);
+ lineDasharray.parse("line-dasharray", value);
+ linePattern.parse("line-pattern", value);
+}
+
+void LinePaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ lineOpacity.cascade(parameters);
+ lineColor.cascade(parameters);
+ lineTranslate.cascade(parameters);
+ lineTranslateAnchor.cascade(parameters);
+ lineWidth.cascade(parameters);
+ lineGapWidth.cascade(parameters);
+ lineOffset.cascade(parameters);
+ lineBlur.cascade(parameters);
+ lineDasharray.cascade(parameters);
+ linePattern.cascade(parameters);
+}
+
+bool LinePaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= lineOpacity.calculate(parameters);
+ hasTransitions |= lineColor.calculate(parameters);
+ hasTransitions |= lineTranslate.calculate(parameters);
+ hasTransitions |= lineTranslateAnchor.calculate(parameters);
+ hasTransitions |= lineWidth.calculate(parameters);
+ hasTransitions |= lineGapWidth.calculate(parameters);
+ hasTransitions |= lineOffset.calculate(parameters);
+ hasTransitions |= lineBlur.calculate(parameters);
+ hasTransitions |= lineDasharray.calculate(parameters);
+ hasTransitions |= linePattern.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/line_layer_properties.hpp b/src/mbgl/layer/line_layer_properties.hpp
new file mode 100644
index 0000000000..ae87d6da5e
--- /dev/null
+++ b/src/mbgl/layer/line_layer_properties.hpp
@@ -0,0 +1,43 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+
+class LineLayoutProperties {
+public:
+ void parse(const JSValue&);
+ void recalculate(const StyleCalculationParameters&);
+
+ LayoutProperty<LineCapType> lineCap { LineCapType::Butt };
+ LayoutProperty<LineJoinType> lineJoin { LineJoinType::Miter };
+ LayoutProperty<float> lineMiterLimit { 2 };
+ LayoutProperty<float> lineRoundLimit { 1.05 };
+};
+
+class LinePaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<float> lineOpacity { 1 };
+ PaintProperty<Color> lineColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<std::array<float, 2>> lineTranslate { {{ 0, 0 }} };
+ PaintProperty<TranslateAnchorType> lineTranslateAnchor { TranslateAnchorType::Map };
+ PaintProperty<float> lineWidth { 1 };
+ PaintProperty<float> lineGapWidth { 0 };
+ PaintProperty<float> lineOffset { 0 };
+ PaintProperty<float> lineBlur { 0 };
+ PaintProperty<std::vector<float>, CrossFadedFunctionEvaluator> lineDasharray { { } };
+ PaintProperty<std::string, CrossFadedFunctionEvaluator> linePattern { "" };
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer.cpp b/src/mbgl/layer/raster_layer.cpp
index fa41609039..1ec2e4c0d4 100644
--- a/src/mbgl/layer/raster_layer.cpp
+++ b/src/mbgl/layer/raster_layer.cpp
@@ -1,50 +1,96 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/raster_layer.hpp>
-#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/layer/raster_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> RasterLayer::clone() const {
+RasterLayer::RasterLayer(const std::string& layerID)
+ : Layer(Type::Raster, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+RasterLayer::RasterLayer(const Impl& other)
+ : Layer(Type::Raster, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+RasterLayer::~RasterLayer() = default;
+
+std::unique_ptr<Layer> RasterLayer::Impl::clone() const {
return std::make_unique<RasterLayer>(*this);
}
-void RasterLayer::parsePaints(const JSValue& layer) {
- paint.rasterOpacity.parse("raster-opacity", layer);
- paint.rasterHueRotate.parse("raster-hue-rotate", layer);
- paint.rasterBrightnessMin.parse("raster-brightness-min", layer);
- paint.rasterBrightnessMax.parse("raster-brightness-max", layer);
- paint.rasterSaturation.parse("raster-saturation", layer);
- paint.rasterContrast.parse("raster-contrast", layer);
- paint.rasterFadeDuration.parse("raster-fade-duration", layer);
+// Source
+
+void RasterLayer::setSource(const std::string& sourceID) {
+ impl->source = sourceID;
+}
+
+const std::string& RasterLayer::getSourceID() const {
+ return impl->source;
+}
+
+// Layout properties
+
+
+// Paint properties
+
+Function<float> RasterLayer::getRasterOpacity() const {
+ return impl->paint.rasterOpacity.values.at(ClassID::Default);
}
-void RasterLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.rasterOpacity.cascade(parameters);
- paint.rasterHueRotate.cascade(parameters);
- paint.rasterBrightnessMin.cascade(parameters);
- paint.rasterBrightnessMax.cascade(parameters);
- paint.rasterSaturation.cascade(parameters);
- paint.rasterContrast.cascade(parameters);
- paint.rasterFadeDuration.cascade(parameters);
+void RasterLayer::setRasterOpacity(Function<float> value) {
+ impl->paint.rasterOpacity.values.emplace(ClassID::Default, value);
}
-bool RasterLayer::recalculate(const StyleCalculationParameters& parameters) {
- bool hasTransitions = false;
+Function<float> RasterLayer::getRasterHueRotate() const {
+ return impl->paint.rasterHueRotate.values.at(ClassID::Default);
+}
- hasTransitions |= paint.rasterOpacity.calculate(parameters);
- hasTransitions |= paint.rasterHueRotate.calculate(parameters);
- hasTransitions |= paint.rasterBrightnessMin.calculate(parameters);
- hasTransitions |= paint.rasterBrightnessMax.calculate(parameters);
- hasTransitions |= paint.rasterSaturation.calculate(parameters);
- hasTransitions |= paint.rasterContrast.calculate(parameters);
- hasTransitions |= paint.rasterFadeDuration.calculate(parameters);
+void RasterLayer::setRasterHueRotate(Function<float> value) {
+ impl->paint.rasterHueRotate.values.emplace(ClassID::Default, value);
+}
- passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+Function<float> RasterLayer::getRasterBrightnessMin() const {
+ return impl->paint.rasterBrightnessMin.values.at(ClassID::Default);
+}
+
+void RasterLayer::setRasterBrightnessMin(Function<float> value) {
+ impl->paint.rasterBrightnessMin.values.emplace(ClassID::Default, value);
+}
+
+Function<float> RasterLayer::getRasterBrightnessMax() const {
+ return impl->paint.rasterBrightnessMax.values.at(ClassID::Default);
+}
+
+void RasterLayer::setRasterBrightnessMax(Function<float> value) {
+ impl->paint.rasterBrightnessMax.values.emplace(ClassID::Default, value);
+}
+
+Function<float> RasterLayer::getRasterSaturation() const {
+ return impl->paint.rasterSaturation.values.at(ClassID::Default);
+}
+
+void RasterLayer::setRasterSaturation(Function<float> value) {
+ impl->paint.rasterSaturation.values.emplace(ClassID::Default, value);
+}
+
+Function<float> RasterLayer::getRasterContrast() const {
+ return impl->paint.rasterContrast.values.at(ClassID::Default);
+}
+
+void RasterLayer::setRasterContrast(Function<float> value) {
+ impl->paint.rasterContrast.values.emplace(ClassID::Default, value);
+}
- return hasTransitions;
+Function<float> RasterLayer::getRasterFadeDuration() const {
+ return impl->paint.rasterFadeDuration.values.at(ClassID::Default);
}
-std::unique_ptr<Bucket> RasterLayer::createBucket(StyleBucketParameters&) const {
- return nullptr;
+void RasterLayer::setRasterFadeDuration(Function<float> value) {
+ impl->paint.rasterFadeDuration.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer.hpp b/src/mbgl/layer/raster_layer.hpp
deleted file mode 100644
index d473505d56..0000000000
--- a/src/mbgl/layer/raster_layer.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <mbgl/style/style_layer.hpp>
-#include <mbgl/style/paint_property.hpp>
-
-namespace mbgl {
-
-class RasterPaintProperties {
-public:
- PaintProperty<float> rasterOpacity { 1.0f };
- PaintProperty<float> rasterHueRotate { 0.0f };
- PaintProperty<float> rasterBrightnessMin { 0.0f };
- PaintProperty<float> rasterBrightnessMax { 1.0f };
- PaintProperty<float> rasterSaturation { 0.0f };
- PaintProperty<float> rasterContrast { 0.0f };
- PaintProperty<float> rasterFadeDuration { 0.0f };
-};
-
-class RasterLayer : public StyleLayer {
-public:
- RasterLayer() : StyleLayer(Type::Raster) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override {};
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- RasterPaintProperties paint;
-};
-
-template <>
-inline bool StyleLayer::is<RasterLayer>() const {
- return type == Type::Raster;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer_impl.cpp b/src/mbgl/layer/raster_layer_impl.cpp
new file mode 100644
index 0000000000..f44a424f99
--- /dev/null
+++ b/src/mbgl/layer/raster_layer_impl.cpp
@@ -0,0 +1,26 @@
+#include <mbgl/layer/raster_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+
+void RasterLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void RasterLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool RasterLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(StyleBucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer_impl.hpp b/src/mbgl/layer/raster_layer_impl.hpp
new file mode 100644
index 0000000000..a83c7f259e
--- /dev/null
+++ b/src/mbgl/layer/raster_layer_impl.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/raster_layer.hpp>
+#include <mbgl/layer/raster_layer_properties.hpp>
+
+namespace mbgl {
+
+class RasterLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override {};
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ RasterPaintProperties paint;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer_properties.cpp b/src/mbgl/layer/raster_layer_properties.cpp
new file mode 100644
index 0000000000..898188bc83
--- /dev/null
+++ b/src/mbgl/layer/raster_layer_properties.cpp
@@ -0,0 +1,41 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/raster_layer_properties.hpp>
+
+namespace mbgl {
+
+void RasterPaintProperties::parse(const JSValue& value) {
+ rasterOpacity.parse("raster-opacity", value);
+ rasterHueRotate.parse("raster-hue-rotate", value);
+ rasterBrightnessMin.parse("raster-brightness-min", value);
+ rasterBrightnessMax.parse("raster-brightness-max", value);
+ rasterSaturation.parse("raster-saturation", value);
+ rasterContrast.parse("raster-contrast", value);
+ rasterFadeDuration.parse("raster-fade-duration", value);
+}
+
+void RasterPaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ rasterOpacity.cascade(parameters);
+ rasterHueRotate.cascade(parameters);
+ rasterBrightnessMin.cascade(parameters);
+ rasterBrightnessMax.cascade(parameters);
+ rasterSaturation.cascade(parameters);
+ rasterContrast.cascade(parameters);
+ rasterFadeDuration.cascade(parameters);
+}
+
+bool RasterPaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= rasterOpacity.calculate(parameters);
+ hasTransitions |= rasterHueRotate.calculate(parameters);
+ hasTransitions |= rasterBrightnessMin.calculate(parameters);
+ hasTransitions |= rasterBrightnessMax.calculate(parameters);
+ hasTransitions |= rasterSaturation.calculate(parameters);
+ hasTransitions |= rasterContrast.calculate(parameters);
+ hasTransitions |= rasterFadeDuration.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/raster_layer_properties.hpp b/src/mbgl/layer/raster_layer_properties.hpp
new file mode 100644
index 0000000000..46bd00ff2e
--- /dev/null
+++ b/src/mbgl/layer/raster_layer_properties.hpp
@@ -0,0 +1,29 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+
+class StyleCascadeParameters;
+class StyleCalculationParameters;
+
+class RasterPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<float> rasterOpacity { 1 };
+ PaintProperty<float> rasterHueRotate { 0 };
+ PaintProperty<float> rasterBrightnessMin { 0 };
+ PaintProperty<float> rasterBrightnessMax { 1 };
+ PaintProperty<float> rasterSaturation { 0 };
+ PaintProperty<float> rasterContrast { 0 };
+ PaintProperty<float> rasterFadeDuration { 300 };
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/symbol_layer.cpp b/src/mbgl/layer/symbol_layer.cpp
index b3222f9368..de2428fd25 100644
--- a/src/mbgl/layer/symbol_layer.cpp
+++ b/src/mbgl/layer/symbol_layer.cpp
@@ -1,188 +1,374 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#include <mbgl/layer/symbol_layer.hpp>
-#include <mbgl/renderer/symbol_bucket.hpp>
-#include <mbgl/style/style_bucket_parameters.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
namespace mbgl {
-std::unique_ptr<StyleLayer> SymbolLayer::clone() const {
+SymbolLayer::SymbolLayer(const std::string& layerID)
+ : Layer(Type::Symbol, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+SymbolLayer::SymbolLayer(const Impl& other)
+ : Layer(Type::Symbol, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+SymbolLayer::~SymbolLayer() = default;
+
+std::unique_ptr<Layer> SymbolLayer::Impl::clone() const {
return std::make_unique<SymbolLayer>(*this);
}
-void SymbolLayer::parseLayout(const JSValue& value) {
- layout.symbolPlacement.parse("symbol-placement", value);
- layout.symbolSpacing.parse("symbol-spacing", value);
- layout.symbolAvoidEdges.parse("symbol-avoid-edges", value);
-
- layout.iconAllowOverlap.parse("icon-allow-overlap", value);
- layout.iconIgnorePlacement.parse("icon-ignore-placement", value);
- layout.iconOptional.parse("icon-optional", value);
- layout.iconRotationAlignment.parse("icon-rotation-alignment", value);
- layout.iconSize.parse("icon-size", value);
- layout.iconImage.parse("icon-image", value);
- layout.iconRotate.parse("icon-rotate", value);
- layout.iconPadding.parse("icon-padding", value);
- layout.iconKeepUpright.parse("icon-keep-upright", value);
- layout.iconOffset.parse("icon-offset", value);
-
- layout.textRotationAlignment.parse("text-rotation-alignment", value);
- layout.textField.parse("text-field", value);
- layout.textFont.parse("text-font", value);
- layout.textSize.parse("text-size", value);
- layout.textMaxWidth.parse("text-max-width", value);
- layout.textLineHeight.parse("text-line-height", value);
- layout.textLetterSpacing.parse("text-letter-spacing", value);
- layout.textJustify.parse("text-justify", value);
- layout.textAnchor.parse("text-anchor", value);
- layout.textMaxAngle.parse("text-max-angle", value);
- layout.textRotate.parse("text-rotate", value);
- layout.textPadding.parse("text-padding", value);
- layout.textKeepUpright.parse("text-keep-upright", value);
- layout.textTransform.parse("text-transform", value);
- layout.textOffset.parse("text-offset", value);
- layout.textAllowOverlap.parse("text-allow-overlap", value);
- layout.textIgnorePlacement.parse("text-ignore-placement", value);
- layout.textOptional.parse("text-optional", value);
-}
-
-void SymbolLayer::parsePaints(const JSValue& layer) {
- paint.iconOpacity.parse("icon-opacity", layer);
- paint.iconColor.parse("icon-color", layer);
- paint.iconHaloColor.parse("icon-halo-color", layer);
- paint.iconHaloWidth.parse("icon-halo-width", layer);
- paint.iconHaloBlur.parse("icon-halo-blur", layer);
- paint.iconTranslate.parse("icon-translate", layer);
- paint.iconTranslateAnchor.parse("icon-translate-anchor", layer);
-
- paint.textOpacity.parse("text-opacity", layer);
- paint.textColor.parse("text-color", layer);
- paint.textHaloColor.parse("text-halo-color", layer);
- paint.textHaloWidth.parse("text-halo-width", layer);
- paint.textHaloBlur.parse("text-halo-blur", layer);
- paint.textTranslate.parse("text-translate", layer);
- paint.textTranslateAnchor.parse("text-translate-anchor", layer);
-}
-
-void SymbolLayer::cascade(const StyleCascadeParameters& parameters) {
- paint.iconOpacity.cascade(parameters);
- paint.iconColor.cascade(parameters);
- paint.iconHaloColor.cascade(parameters);
- paint.iconHaloWidth.cascade(parameters);
- paint.iconHaloBlur.cascade(parameters);
- paint.iconTranslate.cascade(parameters);
- paint.iconTranslateAnchor.cascade(parameters);
-
- paint.textOpacity.cascade(parameters);
- paint.textColor.cascade(parameters);
- paint.textHaloColor.cascade(parameters);
- paint.textHaloWidth.cascade(parameters);
- paint.textHaloBlur.cascade(parameters);
- paint.textTranslate.cascade(parameters);
- paint.textTranslateAnchor.cascade(parameters);
-}
-
-bool SymbolLayer::recalculate(const StyleCalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= paint.iconOpacity.calculate(parameters);
- hasTransitions |= paint.iconColor.calculate(parameters);
- hasTransitions |= paint.iconHaloColor.calculate(parameters);
- hasTransitions |= paint.iconHaloWidth.calculate(parameters);
- hasTransitions |= paint.iconHaloBlur.calculate(parameters);
- hasTransitions |= paint.iconTranslate.calculate(parameters);
- hasTransitions |= paint.iconTranslateAnchor.calculate(parameters);
-
- hasTransitions |= paint.textOpacity.calculate(parameters);
- hasTransitions |= paint.textColor.calculate(parameters);
- hasTransitions |= paint.textHaloColor.calculate(parameters);
- hasTransitions |= paint.textHaloWidth.calculate(parameters);
- hasTransitions |= paint.textHaloBlur.calculate(parameters);
- hasTransitions |= paint.textTranslate.calculate(parameters);
- hasTransitions |= paint.textTranslateAnchor.calculate(parameters);
-
- // text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
- layout.iconSize.calculate(parameters);
- layout.textSize.calculate(parameters);
- iconSize = layout.iconSize;
- textSize = layout.textSize;
-
- passes = ((paint.iconOpacity > 0 && (paint.iconColor.value[3] > 0 || paint.iconHaloColor.value[3] > 0) && iconSize > 0)
- || (paint.textOpacity > 0 && (paint.textColor.value[3] > 0 || paint.textHaloColor.value[3] > 0) && textSize > 0))
- ? RenderPass::Translucent : RenderPass::None;
-
- return hasTransitions;
-}
-
-std::unique_ptr<Bucket> SymbolLayer::createBucket(StyleBucketParameters& parameters) const {
- auto bucket = std::make_unique<SymbolBucket>(parameters.tileID.overscaleFactor(),
- parameters.tileID.overscaledZ,
- parameters.mode,
- id,
- parameters.layer.getName());
-
- bucket->layout = layout;
-
- StyleCalculationParameters p(parameters.tileID.overscaledZ);
- bucket->layout.symbolPlacement.calculate(p);
- if (bucket->layout.symbolPlacement.value == SymbolPlacementType::Line) {
- bucket->layout.iconRotationAlignment.value = RotationAlignmentType::Map;
- bucket->layout.textRotationAlignment.value = RotationAlignmentType::Map;
- };
- bucket->layout.symbolSpacing.calculate(p);
- bucket->layout.symbolAvoidEdges.calculate(p);
-
- bucket->layout.iconAllowOverlap.calculate(p);
- bucket->layout.iconIgnorePlacement.calculate(p);
- bucket->layout.iconOptional.calculate(p);
- bucket->layout.iconRotationAlignment.calculate(p);
- bucket->layout.iconImage.calculate(p);
- bucket->layout.iconPadding.calculate(p);
- bucket->layout.iconRotate.calculate(p);
- bucket->layout.iconKeepUpright.calculate(p);
- bucket->layout.iconOffset.calculate(p);
-
- bucket->layout.textRotationAlignment.calculate(p);
- bucket->layout.textField.calculate(p);
- bucket->layout.textFont.calculate(p);
- bucket->layout.textMaxWidth.calculate(p);
- bucket->layout.textLineHeight.calculate(p);
- bucket->layout.textLetterSpacing.calculate(p);
- bucket->layout.textMaxAngle.calculate(p);
- bucket->layout.textRotate.calculate(p);
- bucket->layout.textPadding.calculate(p);
- bucket->layout.textIgnorePlacement.calculate(p);
- bucket->layout.textOptional.calculate(p);
- bucket->layout.textJustify.calculate(p);
- bucket->layout.textAnchor.calculate(p);
- bucket->layout.textKeepUpright.calculate(p);
- bucket->layout.textTransform.calculate(p);
- bucket->layout.textOffset.calculate(p);
- bucket->layout.textAllowOverlap.calculate(p);
-
- bucket->layout.iconSize.calculate(StyleCalculationParameters(18));
- bucket->layout.textSize.calculate(StyleCalculationParameters(18));
- bucket->iconMaxSize = bucket->layout.iconSize;
- bucket->textMaxSize = bucket->layout.textSize;
- bucket->layout.iconSize.calculate(StyleCalculationParameters(p.z + 1));
- bucket->layout.textSize.calculate(StyleCalculationParameters(p.z + 1));
-
- bucket->parseFeatures(parameters.layer, filter);
-
- if (bucket->needsDependencies(parameters.glyphStore, parameters.spriteStore)) {
- parameters.partialParse = true;
- }
-
- // We do not add features if the parser is in a "partial" state because
- // the layer ordering needs to be respected when calculating text
- // collisions. Although, at this point, we requested all the resources
- // needed by this tile.
- if (!parameters.partialParse) {
- bucket->addFeatures(parameters.tileUID,
- *spriteAtlas,
- parameters.glyphAtlas,
- parameters.glyphStore);
- }
-
- return std::move(bucket);
+// Source
+
+void SymbolLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& SymbolLayer::getSourceID() const {
+ return impl->source;
+}
+
+const std::string& SymbolLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Layout properties
+
+Function<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const {
+ return *impl->layout.symbolPlacement.parsedValue;
+}
+
+void SymbolLayer::setSymbolPlacement(Function<SymbolPlacementType> value) {
+ impl->layout.symbolPlacement.parsedValue = value;
+}
+Function<float> SymbolLayer::getSymbolSpacing() const {
+ return *impl->layout.symbolSpacing.parsedValue;
+}
+
+void SymbolLayer::setSymbolSpacing(Function<float> value) {
+ impl->layout.symbolSpacing.parsedValue = value;
+}
+Function<bool> SymbolLayer::getSymbolAvoidEdges() const {
+ return *impl->layout.symbolAvoidEdges.parsedValue;
+}
+
+void SymbolLayer::setSymbolAvoidEdges(Function<bool> value) {
+ impl->layout.symbolAvoidEdges.parsedValue = value;
+}
+Function<bool> SymbolLayer::getIconAllowOverlap() const {
+ return *impl->layout.iconAllowOverlap.parsedValue;
+}
+
+void SymbolLayer::setIconAllowOverlap(Function<bool> value) {
+ impl->layout.iconAllowOverlap.parsedValue = value;
+}
+Function<bool> SymbolLayer::getIconIgnorePlacement() const {
+ return *impl->layout.iconIgnorePlacement.parsedValue;
+}
+
+void SymbolLayer::setIconIgnorePlacement(Function<bool> value) {
+ impl->layout.iconIgnorePlacement.parsedValue = value;
+}
+Function<bool> SymbolLayer::getIconOptional() const {
+ return *impl->layout.iconOptional.parsedValue;
+}
+
+void SymbolLayer::setIconOptional(Function<bool> value) {
+ impl->layout.iconOptional.parsedValue = value;
+}
+Function<RotationAlignmentType> SymbolLayer::getIconRotationAlignment() const {
+ return *impl->layout.iconRotationAlignment.parsedValue;
+}
+
+void SymbolLayer::setIconRotationAlignment(Function<RotationAlignmentType> value) {
+ impl->layout.iconRotationAlignment.parsedValue = value;
+}
+Function<float> SymbolLayer::getIconSize() const {
+ return *impl->layout.iconSize.parsedValue;
+}
+
+void SymbolLayer::setIconSize(Function<float> value) {
+ impl->layout.iconSize.parsedValue = value;
+}
+Function<std::string> SymbolLayer::getIconImage() const {
+ return *impl->layout.iconImage.parsedValue;
+}
+
+void SymbolLayer::setIconImage(Function<std::string> value) {
+ impl->layout.iconImage.parsedValue = value;
+}
+Function<float> SymbolLayer::getIconRotate() const {
+ return *impl->layout.iconRotate.parsedValue;
+}
+
+void SymbolLayer::setIconRotate(Function<float> value) {
+ impl->layout.iconRotate.parsedValue = value;
+}
+Function<float> SymbolLayer::getIconPadding() const {
+ return *impl->layout.iconPadding.parsedValue;
+}
+
+void SymbolLayer::setIconPadding(Function<float> value) {
+ impl->layout.iconPadding.parsedValue = value;
+}
+Function<bool> SymbolLayer::getIconKeepUpright() const {
+ return *impl->layout.iconKeepUpright.parsedValue;
+}
+
+void SymbolLayer::setIconKeepUpright(Function<bool> value) {
+ impl->layout.iconKeepUpright.parsedValue = value;
+}
+Function<std::array<float, 2>> SymbolLayer::getIconOffset() const {
+ return *impl->layout.iconOffset.parsedValue;
+}
+
+void SymbolLayer::setIconOffset(Function<std::array<float, 2>> value) {
+ impl->layout.iconOffset.parsedValue = value;
+}
+Function<RotationAlignmentType> SymbolLayer::getTextRotationAlignment() const {
+ return *impl->layout.textRotationAlignment.parsedValue;
+}
+
+void SymbolLayer::setTextRotationAlignment(Function<RotationAlignmentType> value) {
+ impl->layout.textRotationAlignment.parsedValue = value;
+}
+Function<std::string> SymbolLayer::getTextField() const {
+ return *impl->layout.textField.parsedValue;
+}
+
+void SymbolLayer::setTextField(Function<std::string> value) {
+ impl->layout.textField.parsedValue = value;
+}
+Function<std::vector<std::string>> SymbolLayer::getTextFont() const {
+ return *impl->layout.textFont.parsedValue;
+}
+
+void SymbolLayer::setTextFont(Function<std::vector<std::string>> value) {
+ impl->layout.textFont.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextSize() const {
+ return *impl->layout.textSize.parsedValue;
+}
+
+void SymbolLayer::setTextSize(Function<float> value) {
+ impl->layout.textSize.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextMaxWidth() const {
+ return *impl->layout.textMaxWidth.parsedValue;
+}
+
+void SymbolLayer::setTextMaxWidth(Function<float> value) {
+ impl->layout.textMaxWidth.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextLineHeight() const {
+ return *impl->layout.textLineHeight.parsedValue;
+}
+
+void SymbolLayer::setTextLineHeight(Function<float> value) {
+ impl->layout.textLineHeight.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextLetterSpacing() const {
+ return *impl->layout.textLetterSpacing.parsedValue;
+}
+
+void SymbolLayer::setTextLetterSpacing(Function<float> value) {
+ impl->layout.textLetterSpacing.parsedValue = value;
+}
+Function<TextJustifyType> SymbolLayer::getTextJustify() const {
+ return *impl->layout.textJustify.parsedValue;
+}
+
+void SymbolLayer::setTextJustify(Function<TextJustifyType> value) {
+ impl->layout.textJustify.parsedValue = value;
+}
+Function<TextAnchorType> SymbolLayer::getTextAnchor() const {
+ return *impl->layout.textAnchor.parsedValue;
+}
+
+void SymbolLayer::setTextAnchor(Function<TextAnchorType> value) {
+ impl->layout.textAnchor.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextMaxAngle() const {
+ return *impl->layout.textMaxAngle.parsedValue;
+}
+
+void SymbolLayer::setTextMaxAngle(Function<float> value) {
+ impl->layout.textMaxAngle.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextRotate() const {
+ return *impl->layout.textRotate.parsedValue;
+}
+
+void SymbolLayer::setTextRotate(Function<float> value) {
+ impl->layout.textRotate.parsedValue = value;
+}
+Function<float> SymbolLayer::getTextPadding() const {
+ return *impl->layout.textPadding.parsedValue;
+}
+
+void SymbolLayer::setTextPadding(Function<float> value) {
+ impl->layout.textPadding.parsedValue = value;
+}
+Function<bool> SymbolLayer::getTextKeepUpright() const {
+ return *impl->layout.textKeepUpright.parsedValue;
+}
+
+void SymbolLayer::setTextKeepUpright(Function<bool> value) {
+ impl->layout.textKeepUpright.parsedValue = value;
+}
+Function<TextTransformType> SymbolLayer::getTextTransform() const {
+ return *impl->layout.textTransform.parsedValue;
+}
+
+void SymbolLayer::setTextTransform(Function<TextTransformType> value) {
+ impl->layout.textTransform.parsedValue = value;
+}
+Function<std::array<float, 2>> SymbolLayer::getTextOffset() const {
+ return *impl->layout.textOffset.parsedValue;
+}
+
+void SymbolLayer::setTextOffset(Function<std::array<float, 2>> value) {
+ impl->layout.textOffset.parsedValue = value;
+}
+Function<bool> SymbolLayer::getTextAllowOverlap() const {
+ return *impl->layout.textAllowOverlap.parsedValue;
+}
+
+void SymbolLayer::setTextAllowOverlap(Function<bool> value) {
+ impl->layout.textAllowOverlap.parsedValue = value;
+}
+Function<bool> SymbolLayer::getTextIgnorePlacement() const {
+ return *impl->layout.textIgnorePlacement.parsedValue;
+}
+
+void SymbolLayer::setTextIgnorePlacement(Function<bool> value) {
+ impl->layout.textIgnorePlacement.parsedValue = value;
+}
+Function<bool> SymbolLayer::getTextOptional() const {
+ return *impl->layout.textOptional.parsedValue;
+}
+
+void SymbolLayer::setTextOptional(Function<bool> value) {
+ impl->layout.textOptional.parsedValue = value;
+}
+
+// Paint properties
+
+Function<float> SymbolLayer::getIconOpacity() const {
+ return impl->paint.iconOpacity.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconOpacity(Function<float> value) {
+ impl->paint.iconOpacity.values.emplace(ClassID::Default, value);
+}
+
+Function<Color> SymbolLayer::getIconColor() const {
+ return impl->paint.iconColor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconColor(Function<Color> value) {
+ impl->paint.iconColor.values.emplace(ClassID::Default, value);
+}
+
+Function<Color> SymbolLayer::getIconHaloColor() const {
+ return impl->paint.iconHaloColor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconHaloColor(Function<Color> value) {
+ impl->paint.iconHaloColor.values.emplace(ClassID::Default, value);
+}
+
+Function<float> SymbolLayer::getIconHaloWidth() const {
+ return impl->paint.iconHaloWidth.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconHaloWidth(Function<float> value) {
+ impl->paint.iconHaloWidth.values.emplace(ClassID::Default, value);
+}
+
+Function<float> SymbolLayer::getIconHaloBlur() const {
+ return impl->paint.iconHaloBlur.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconHaloBlur(Function<float> value) {
+ impl->paint.iconHaloBlur.values.emplace(ClassID::Default, value);
+}
+
+Function<std::array<float, 2>> SymbolLayer::getIconTranslate() const {
+ return impl->paint.iconTranslate.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconTranslate(Function<std::array<float, 2>> value) {
+ impl->paint.iconTranslate.values.emplace(ClassID::Default, value);
+}
+
+Function<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor() const {
+ return impl->paint.iconTranslateAnchor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setIconTranslateAnchor(Function<TranslateAnchorType> value) {
+ impl->paint.iconTranslateAnchor.values.emplace(ClassID::Default, value);
+}
+
+Function<float> SymbolLayer::getTextOpacity() const {
+ return impl->paint.textOpacity.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextOpacity(Function<float> value) {
+ impl->paint.textOpacity.values.emplace(ClassID::Default, value);
+}
+
+Function<Color> SymbolLayer::getTextColor() const {
+ return impl->paint.textColor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextColor(Function<Color> value) {
+ impl->paint.textColor.values.emplace(ClassID::Default, value);
+}
+
+Function<Color> SymbolLayer::getTextHaloColor() const {
+ return impl->paint.textHaloColor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextHaloColor(Function<Color> value) {
+ impl->paint.textHaloColor.values.emplace(ClassID::Default, value);
+}
+
+Function<float> SymbolLayer::getTextHaloWidth() const {
+ return impl->paint.textHaloWidth.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextHaloWidth(Function<float> value) {
+ impl->paint.textHaloWidth.values.emplace(ClassID::Default, value);
+}
+
+Function<float> SymbolLayer::getTextHaloBlur() const {
+ return impl->paint.textHaloBlur.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextHaloBlur(Function<float> value) {
+ impl->paint.textHaloBlur.values.emplace(ClassID::Default, value);
+}
+
+Function<std::array<float, 2>> SymbolLayer::getTextTranslate() const {
+ return impl->paint.textTranslate.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextTranslate(Function<std::array<float, 2>> value) {
+ impl->paint.textTranslate.values.emplace(ClassID::Default, value);
+}
+
+Function<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor() const {
+ return impl->paint.textTranslateAnchor.values.at(ClassID::Default);
+}
+
+void SymbolLayer::setTextTranslateAnchor(Function<TranslateAnchorType> value) {
+ impl->paint.textTranslateAnchor.values.emplace(ClassID::Default, value);
}
} // namespace mbgl
diff --git a/src/mbgl/layer/symbol_layer_impl.cpp b/src/mbgl/layer/symbol_layer_impl.cpp
new file mode 100644
index 0000000000..3a0e0dceca
--- /dev/null
+++ b/src/mbgl/layer/symbol_layer_impl.cpp
@@ -0,0 +1,80 @@
+#include <mbgl/layer/symbol_layer_impl.hpp>
+#include <mbgl/renderer/symbol_bucket.hpp>
+#include <mbgl/style/style_bucket_parameters.hpp>
+
+namespace mbgl {
+
+void SymbolLayer::Impl::parseLayout(const JSValue& value) {
+ layout.parse(value);
+}
+
+void SymbolLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void SymbolLayer::Impl::cascade(const StyleCascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool SymbolLayer::Impl::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ // text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
+ layout.iconSize.calculate(parameters);
+ layout.textSize.calculate(parameters);
+ iconSize = layout.iconSize;
+ textSize = layout.textSize;
+
+ passes = ((paint.iconOpacity > 0 && (paint.iconColor.value[3] > 0 || paint.iconHaloColor.value[3] > 0) && iconSize > 0)
+ || (paint.textOpacity > 0 && (paint.textColor.value[3] > 0 || paint.textHaloColor.value[3] > 0) && textSize > 0))
+ ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(StyleBucketParameters& parameters) const {
+ auto bucket = std::make_unique<SymbolBucket>(parameters.tileID.overscaleFactor(),
+ parameters.tileID.overscaledZ,
+ parameters.mode,
+ id,
+ parameters.layer.getName());
+
+ bucket->layout = layout;
+
+ StyleCalculationParameters p(parameters.tileID.overscaledZ);
+ bucket->layout.symbolPlacement.calculate(p);
+ if (bucket->layout.symbolPlacement.value == SymbolPlacementType::Line) {
+ bucket->layout.iconRotationAlignment.value = RotationAlignmentType::Map;
+ bucket->layout.textRotationAlignment.value = RotationAlignmentType::Map;
+ };
+
+ bucket->layout.recalculate(p);
+
+ bucket->layout.iconSize.calculate(StyleCalculationParameters(18));
+ bucket->layout.textSize.calculate(StyleCalculationParameters(18));
+ bucket->iconMaxSize = bucket->layout.iconSize;
+ bucket->textMaxSize = bucket->layout.textSize;
+ bucket->layout.iconSize.calculate(StyleCalculationParameters(p.z + 1));
+ bucket->layout.textSize.calculate(StyleCalculationParameters(p.z + 1));
+
+ bucket->parseFeatures(parameters.layer, filter);
+
+ if (bucket->needsDependencies(parameters.glyphStore, parameters.spriteStore)) {
+ parameters.partialParse = true;
+ }
+
+ // We do not add features if the parser is in a "partial" state because
+ // the layer ordering needs to be respected when calculating text
+ // collisions. Although, at this point, we requested all the resources
+ // needed by this tile.
+ if (!parameters.partialParse) {
+ bucket->addFeatures(parameters.tileUID,
+ *spriteAtlas,
+ parameters.glyphAtlas,
+ parameters.glyphStore);
+ }
+
+ return std::move(bucket);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/symbol_layer_impl.hpp b/src/mbgl/layer/symbol_layer_impl.hpp
new file mode 100644
index 0000000000..46503ab916
--- /dev/null
+++ b/src/mbgl/layer/symbol_layer_impl.hpp
@@ -0,0 +1,35 @@
+#ifndef MBGL_SYMBOL_LAYER
+#define MBGL_SYMBOL_LAYER
+
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_properties.hpp>
+
+namespace mbgl {
+
+class SpriteAtlas;
+
+class SymbolLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) override;
+ void parsePaints(const JSValue&) override;
+
+ void cascade(const StyleCascadeParameters&) override;
+ bool recalculate(const StyleCalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
+
+ SymbolLayoutProperties layout;
+ SymbolPaintProperties paint;
+
+ float iconSize = 1.0f;
+ float textSize = 16.0f;
+
+ SpriteAtlas* spriteAtlas = nullptr;
+};
+
+} // namespace mbgl
+
+#endif
diff --git a/src/mbgl/layer/symbol_layer_properties.cpp b/src/mbgl/layer/symbol_layer_properties.cpp
new file mode 100644
index 0000000000..4b9e9a5fb6
--- /dev/null
+++ b/src/mbgl/layer/symbol_layer_properties.cpp
@@ -0,0 +1,130 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/layer/symbol_layer_properties.hpp>
+
+namespace mbgl {
+
+void SymbolLayoutProperties::parse(const JSValue& value) {
+ symbolPlacement.parse("symbol-placement", value);
+ symbolSpacing.parse("symbol-spacing", value);
+ symbolAvoidEdges.parse("symbol-avoid-edges", value);
+ iconAllowOverlap.parse("icon-allow-overlap", value);
+ iconIgnorePlacement.parse("icon-ignore-placement", value);
+ iconOptional.parse("icon-optional", value);
+ iconRotationAlignment.parse("icon-rotation-alignment", value);
+ iconSize.parse("icon-size", value);
+ iconImage.parse("icon-image", value);
+ iconRotate.parse("icon-rotate", value);
+ iconPadding.parse("icon-padding", value);
+ iconKeepUpright.parse("icon-keep-upright", value);
+ iconOffset.parse("icon-offset", value);
+ textRotationAlignment.parse("text-rotation-alignment", value);
+ textField.parse("text-field", value);
+ textFont.parse("text-font", value);
+ textSize.parse("text-size", value);
+ textMaxWidth.parse("text-max-width", value);
+ textLineHeight.parse("text-line-height", value);
+ textLetterSpacing.parse("text-letter-spacing", value);
+ textJustify.parse("text-justify", value);
+ textAnchor.parse("text-anchor", value);
+ textMaxAngle.parse("text-max-angle", value);
+ textRotate.parse("text-rotate", value);
+ textPadding.parse("text-padding", value);
+ textKeepUpright.parse("text-keep-upright", value);
+ textTransform.parse("text-transform", value);
+ textOffset.parse("text-offset", value);
+ textAllowOverlap.parse("text-allow-overlap", value);
+ textIgnorePlacement.parse("text-ignore-placement", value);
+ textOptional.parse("text-optional", value);
+}
+
+void SymbolLayoutProperties::recalculate(const StyleCalculationParameters& parameters) {
+ symbolPlacement.calculate(parameters);
+ symbolSpacing.calculate(parameters);
+ symbolAvoidEdges.calculate(parameters);
+ iconAllowOverlap.calculate(parameters);
+ iconIgnorePlacement.calculate(parameters);
+ iconOptional.calculate(parameters);
+ iconRotationAlignment.calculate(parameters);
+ iconSize.calculate(parameters);
+ iconImage.calculate(parameters);
+ iconRotate.calculate(parameters);
+ iconPadding.calculate(parameters);
+ iconKeepUpright.calculate(parameters);
+ iconOffset.calculate(parameters);
+ textRotationAlignment.calculate(parameters);
+ textField.calculate(parameters);
+ textFont.calculate(parameters);
+ textSize.calculate(parameters);
+ textMaxWidth.calculate(parameters);
+ textLineHeight.calculate(parameters);
+ textLetterSpacing.calculate(parameters);
+ textJustify.calculate(parameters);
+ textAnchor.calculate(parameters);
+ textMaxAngle.calculate(parameters);
+ textRotate.calculate(parameters);
+ textPadding.calculate(parameters);
+ textKeepUpright.calculate(parameters);
+ textTransform.calculate(parameters);
+ textOffset.calculate(parameters);
+ textAllowOverlap.calculate(parameters);
+ textIgnorePlacement.calculate(parameters);
+ textOptional.calculate(parameters);
+}
+
+void SymbolPaintProperties::parse(const JSValue& value) {
+ iconOpacity.parse("icon-opacity", value);
+ iconColor.parse("icon-color", value);
+ iconHaloColor.parse("icon-halo-color", value);
+ iconHaloWidth.parse("icon-halo-width", value);
+ iconHaloBlur.parse("icon-halo-blur", value);
+ iconTranslate.parse("icon-translate", value);
+ iconTranslateAnchor.parse("icon-translate-anchor", value);
+ textOpacity.parse("text-opacity", value);
+ textColor.parse("text-color", value);
+ textHaloColor.parse("text-halo-color", value);
+ textHaloWidth.parse("text-halo-width", value);
+ textHaloBlur.parse("text-halo-blur", value);
+ textTranslate.parse("text-translate", value);
+ textTranslateAnchor.parse("text-translate-anchor", value);
+}
+
+void SymbolPaintProperties::cascade(const StyleCascadeParameters& parameters) {
+ iconOpacity.cascade(parameters);
+ iconColor.cascade(parameters);
+ iconHaloColor.cascade(parameters);
+ iconHaloWidth.cascade(parameters);
+ iconHaloBlur.cascade(parameters);
+ iconTranslate.cascade(parameters);
+ iconTranslateAnchor.cascade(parameters);
+ textOpacity.cascade(parameters);
+ textColor.cascade(parameters);
+ textHaloColor.cascade(parameters);
+ textHaloWidth.cascade(parameters);
+ textHaloBlur.cascade(parameters);
+ textTranslate.cascade(parameters);
+ textTranslateAnchor.cascade(parameters);
+}
+
+bool SymbolPaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= iconOpacity.calculate(parameters);
+ hasTransitions |= iconColor.calculate(parameters);
+ hasTransitions |= iconHaloColor.calculate(parameters);
+ hasTransitions |= iconHaloWidth.calculate(parameters);
+ hasTransitions |= iconHaloBlur.calculate(parameters);
+ hasTransitions |= iconTranslate.calculate(parameters);
+ hasTransitions |= iconTranslateAnchor.calculate(parameters);
+ hasTransitions |= textOpacity.calculate(parameters);
+ hasTransitions |= textColor.calculate(parameters);
+ hasTransitions |= textHaloColor.calculate(parameters);
+ hasTransitions |= textHaloWidth.calculate(parameters);
+ hasTransitions |= textHaloBlur.calculate(parameters);
+ hasTransitions |= textTranslate.calculate(parameters);
+ hasTransitions |= textTranslateAnchor.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/layer/symbol_layer.hpp b/src/mbgl/layer/symbol_layer_properties.hpp
index 3119ee1f03..ccbecef00e 100644
--- a/src/mbgl/layer/symbol_layer.hpp
+++ b/src/mbgl/layer/symbol_layer_properties.hpp
@@ -1,42 +1,46 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
#pragma once
-#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/util/rapidjson.hpp>
namespace mbgl {
-class SpriteAtlas;
+class StyleCascadeParameters;
+class StyleCalculationParameters;
class SymbolLayoutProperties {
public:
+ void parse(const JSValue&);
+ void recalculate(const StyleCalculationParameters&);
+
LayoutProperty<SymbolPlacementType> symbolPlacement { SymbolPlacementType::Point };
- LayoutProperty<float> symbolSpacing { 250.0f };
+ LayoutProperty<float> symbolSpacing { 250 };
LayoutProperty<bool> symbolAvoidEdges { false };
-
LayoutProperty<bool> iconAllowOverlap { false };
LayoutProperty<bool> iconIgnorePlacement { false };
LayoutProperty<bool> iconOptional { false };
LayoutProperty<RotationAlignmentType> iconRotationAlignment { RotationAlignmentType::Viewport };
- LayoutProperty<float> iconSize { 1.0f };
+ LayoutProperty<float> iconSize { 1 };
LayoutProperty<std::string> iconImage { "" };
- LayoutProperty<float> iconRotate { 0.0f };
- LayoutProperty<float> iconPadding { 2.0f };
+ LayoutProperty<float> iconRotate { 0 };
+ LayoutProperty<float> iconPadding { 2 };
LayoutProperty<bool> iconKeepUpright { false };
LayoutProperty<std::array<float, 2>> iconOffset { {{ 0, 0 }} };
-
LayoutProperty<RotationAlignmentType> textRotationAlignment { RotationAlignmentType::Viewport };
LayoutProperty<std::string> textField { "" };
LayoutProperty<std::vector<std::string>> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } };
- LayoutProperty<float> textSize { 16.0f };
- LayoutProperty<float> textMaxWidth { 10.0f /* em */ };
- LayoutProperty<float> textLineHeight { 1.2f /* em */ };
- LayoutProperty<float> textLetterSpacing { 0.0f /* em */ };
+ LayoutProperty<float> textSize { 16 };
+ LayoutProperty<float> textMaxWidth { 10 };
+ LayoutProperty<float> textLineHeight { 1.2 };
+ LayoutProperty<float> textLetterSpacing { 0 };
LayoutProperty<TextJustifyType> textJustify { TextJustifyType::Center };
LayoutProperty<TextAnchorType> textAnchor { TextAnchorType::Center };
- LayoutProperty<float> textMaxAngle { 45.0f /* degrees */ };
- LayoutProperty<float> textRotate { 0.0f };
- LayoutProperty<float> textPadding { 2.0f };
+ LayoutProperty<float> textMaxAngle { 45 };
+ LayoutProperty<float> textRotate { 0 };
+ LayoutProperty<float> textPadding { 2 };
LayoutProperty<bool> textKeepUpright { true };
LayoutProperty<TextTransformType> textTransform { TextTransformType::None };
LayoutProperty<std::array<float, 2>> textOffset { {{ 0, 0 }} };
@@ -47,48 +51,24 @@ public:
class SymbolPaintProperties {
public:
- PaintProperty<float> iconOpacity { 1.0f };
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+ PaintProperty<float> iconOpacity { 1 };
PaintProperty<Color> iconColor { {{ 0, 0, 0, 1 }} };
PaintProperty<Color> iconHaloColor { {{ 0, 0, 0, 0 }} };
- PaintProperty<float> iconHaloWidth { 0.0f };
- PaintProperty<float> iconHaloBlur { 0.0f };
+ PaintProperty<float> iconHaloWidth { 0 };
+ PaintProperty<float> iconHaloBlur { 0 };
PaintProperty<std::array<float, 2>> iconTranslate { {{ 0, 0 }} };
PaintProperty<TranslateAnchorType> iconTranslateAnchor { TranslateAnchorType::Map };
-
- PaintProperty<float> textOpacity { 1.0f };
+ PaintProperty<float> textOpacity { 1 };
PaintProperty<Color> textColor { {{ 0, 0, 0, 1 }} };
PaintProperty<Color> textHaloColor { {{ 0, 0, 0, 0 }} };
- PaintProperty<float> textHaloWidth { 0.0f };
- PaintProperty<float> textHaloBlur { 0.0f };
+ PaintProperty<float> textHaloWidth { 0 };
+ PaintProperty<float> textHaloBlur { 0 };
PaintProperty<std::array<float, 2>> textTranslate { {{ 0, 0 }} };
PaintProperty<TranslateAnchorType> textTranslateAnchor { TranslateAnchorType::Map };
};
-class SymbolLayer : public StyleLayer {
-public:
- SymbolLayer() : StyleLayer(Type::Symbol) {}
- std::unique_ptr<StyleLayer> clone() const override;
-
- void parseLayout(const JSValue&) override;
- void parsePaints(const JSValue&) override;
-
- void cascade(const StyleCascadeParameters&) override;
- bool recalculate(const StyleCalculationParameters&) override;
-
- std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const override;
-
- SymbolLayoutProperties layout;
- SymbolPaintProperties paint;
-
- float iconSize = 1.0f;
- float textSize = 16.0f;
-
- SpriteAtlas* spriteAtlas = nullptr;
-};
-
-template <>
-inline bool StyleLayer::is<SymbolLayer>() const {
- return type == Type::Symbol;
-}
-
} // namespace mbgl