summaryrefslogtreecommitdiff
path: root/src/mbgl/style/layers
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/layers')
-rw-r--r--src/mbgl/style/layers/background_layer.cpp57
-rw-r--r--src/mbgl/style/layers/background_layer_impl.cpp28
-rw-r--r--src/mbgl/style/layers/background_layer_impl.hpp26
-rw-r--r--src/mbgl/style/layers/background_layer_properties.cpp31
-rw-r--r--src/mbgl/style/layers/background_layer_properties.hpp27
-rw-r--r--src/mbgl/style/layers/circle_layer.cpp105
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp62
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp33
-rw-r--r--src/mbgl/style/layers/circle_layer_properties.cpp40
-rw-r--r--src/mbgl/style/layers/circle_layer_properties.hpp30
-rw-r--r--src/mbgl/style/layers/custom_layer.cpp24
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.cpp68
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.hpp44
-rw-r--r--src/mbgl/style/layers/fill_layer.cpp113
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp68
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp33
-rw-r--r--src/mbgl/style/layers/fill_layer_properties.cpp43
-rw-r--r--src/mbgl/style/layers/fill_layer_properties.hpp31
-rw-r--r--src/mbgl/style/layers/line_layer.cpp165
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp116
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp40
-rw-r--r--src/mbgl/style/layers/line_layer_properties.cpp66
-rw-r--r--src/mbgl/style/layers/line_layer_properties.hpp45
-rw-r--r--src/mbgl/style/layers/raster_layer.cpp98
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.cpp28
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.hpp26
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.cpp43
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.hpp31
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp386
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp82
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp35
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.cpp132
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp76
33 files changed, 2232 insertions, 0 deletions
diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp
new file mode 100644
index 0000000000..aeb4067503
--- /dev/null
+++ b/src/mbgl/style/layers/background_layer.cpp
@@ -0,0 +1,57 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/background_layer.hpp>
+#include <mbgl/style/layers/background_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+BackgroundLayer::BackgroundLayer(const std::string& layerID)
+ : Layer(Type::Background, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+BackgroundLayer::BackgroundLayer(const Impl& other)
+ : Layer(Type::Background, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+BackgroundLayer::~BackgroundLayer() = default;
+
+std::unique_ptr<Layer> BackgroundLayer::Impl::clone() const {
+ return std::make_unique<BackgroundLayer>(*this);
+}
+
+
+// Layout properties
+
+
+// Paint properties
+
+PropertyValue<Color> BackgroundLayer::getBackgroundColor() const {
+ return impl->paint.backgroundColor.get();
+}
+
+void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value) {
+ impl->paint.backgroundColor.set(value);
+}
+
+PropertyValue<std::string> BackgroundLayer::getBackgroundPattern() const {
+ return impl->paint.backgroundPattern.get();
+}
+
+void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value) {
+ impl->paint.backgroundPattern.set(value);
+}
+
+PropertyValue<float> BackgroundLayer::getBackgroundOpacity() const {
+ return impl->paint.backgroundOpacity.get();
+}
+
+void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value) {
+ impl->paint.backgroundOpacity.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp
new file mode 100644
index 0000000000..0c09c5d158
--- /dev/null
+++ b/src/mbgl/style/layers/background_layer_impl.cpp
@@ -0,0 +1,28 @@
+#include <mbgl/style/layers/background_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+namespace style {
+
+void BackgroundLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void BackgroundLayer::Impl::cascade(const CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool BackgroundLayer::Impl::recalculate(const CalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(BucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp
new file mode 100644
index 0000000000..19e2a062a4
--- /dev/null
+++ b/src/mbgl/style/layers/background_layer_impl.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/background_layer.hpp>
+#include <mbgl/style/layers/background_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
+
+ BackgroundPaintProperties paint;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp
new file mode 100644
index 0000000000..a20cedf12c
--- /dev/null
+++ b/src/mbgl/style/layers/background_layer_properties.cpp
@@ -0,0 +1,31 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/background_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters& parameters) {
+ backgroundColor.cascade(parameters);
+ backgroundPattern.cascade(parameters);
+ backgroundOpacity.cascade(parameters);
+}
+
+bool BackgroundPaintProperties::recalculate(const CalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+ hasTransitions |= backgroundColor.calculate(parameters);
+ hasTransitions |= backgroundPattern.calculate(parameters);
+ hasTransitions |= backgroundOpacity.calculate(parameters);
+
+ return hasTransitions;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp
new file mode 100644
index 0000000000..a1a1a3a5a7
--- /dev/null
+++ b/src/mbgl/style/layers/background_layer_properties.hpp
@@ -0,0 +1,27 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class BackgroundPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ PaintProperty<Color> backgroundColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<std::string, CrossFadedPropertyEvaluator> backgroundPattern { "" };
+ PaintProperty<float> backgroundOpacity { 1 };
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp
new file mode 100644
index 0000000000..bdfbf629e6
--- /dev/null
+++ b/src/mbgl/style/layers/circle_layer.cpp
@@ -0,0 +1,105 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/style/layers/circle_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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);
+}
+
+// Source
+
+void CircleLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& CircleLayer::getSourceID() const {
+ return impl->source;
+}
+
+const std::string& CircleLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Filter
+
+void CircleLayer::setFilter(const Filter& filter) {
+ impl->filter = filter;
+}
+
+const Filter& CircleLayer::getFilter() const {
+ return impl->filter;
+}
+
+// Layout properties
+
+
+// Paint properties
+
+PropertyValue<float> CircleLayer::getCircleRadius() const {
+ return impl->paint.circleRadius.get();
+}
+
+void CircleLayer::setCircleRadius(PropertyValue<float> value) {
+ impl->paint.circleRadius.set(value);
+}
+
+PropertyValue<Color> CircleLayer::getCircleColor() const {
+ return impl->paint.circleColor.get();
+}
+
+void CircleLayer::setCircleColor(PropertyValue<Color> value) {
+ impl->paint.circleColor.set(value);
+}
+
+PropertyValue<float> CircleLayer::getCircleBlur() const {
+ return impl->paint.circleBlur.get();
+}
+
+void CircleLayer::setCircleBlur(PropertyValue<float> value) {
+ impl->paint.circleBlur.set(value);
+}
+
+PropertyValue<float> CircleLayer::getCircleOpacity() const {
+ return impl->paint.circleOpacity.get();
+}
+
+void CircleLayer::setCircleOpacity(PropertyValue<float> value) {
+ impl->paint.circleOpacity.set(value);
+}
+
+PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate() const {
+ return impl->paint.circleTranslate.get();
+}
+
+void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value) {
+ impl->paint.circleTranslate.set(value);
+}
+
+PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor() const {
+ return impl->paint.circleTranslateAnchor.get();
+}
+
+void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value) {
+ impl->paint.circleTranslateAnchor.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
new file mode 100644
index 0000000000..c2efac5cef
--- /dev/null
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -0,0 +1,62 @@
+#include <mbgl/style/layers/circle_layer_impl.hpp>
+#include <mbgl/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 {
+namespace style {
+
+void CircleLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void CircleLayer::Impl::cascade(const CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool CircleLayer::Impl::recalculate(const CalculationParameters& 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(BucketParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp
new file mode 100644
index 0000000000..463f3ca18d
--- /dev/null
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/style/layers/circle_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp
new file mode 100644
index 0000000000..b21df1e2d0
--- /dev/null
+++ b/src/mbgl/style/layers/circle_layer_properties.cpp
@@ -0,0 +1,40 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/circle_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters& parameters) {
+ circleRadius.cascade(parameters);
+ circleColor.cascade(parameters);
+ circleBlur.cascade(parameters);
+ circleOpacity.cascade(parameters);
+ circleTranslate.cascade(parameters);
+ circleTranslateAnchor.cascade(parameters);
+}
+
+bool CirclePaintProperties::recalculate(const CalculationParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp
new file mode 100644
index 0000000000..956e423c45
--- /dev/null
+++ b/src/mbgl/style/layers/circle_layer_properties.hpp
@@ -0,0 +1,30 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class CirclePaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/custom_layer.cpp b/src/mbgl/style/layers/custom_layer.cpp
new file mode 100644
index 0000000000..3407a7f5a5
--- /dev/null
+++ b/src/mbgl/style/layers/custom_layer.cpp
@@ -0,0 +1,24 @@
+#include <mbgl/style/layers/custom_layer.hpp>
+#include <mbgl/style/layers/custom_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 Impl& other)
+ : Layer(Type::Custom, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+CustomLayer::~CustomLayer() = default;
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp
new file mode 100644
index 0000000000..214d4ce663
--- /dev/null
+++ b/src/mbgl/style/layers/custom_layer_impl.cpp
@@ -0,0 +1,68 @@
+#include <mbgl/style/layers/custom_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/map/transform_state.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CalculationParameters&) {
+ passes = RenderPass::Translucent;
+ return false;
+}
+
+std::unique_ptr<Bucket> CustomLayer::Impl::createBucket(BucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp
new file mode 100644
index 0000000000..00e576b6a3
--- /dev/null
+++ b/src/mbgl/style/layers/custom_layer_impl.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/custom_layer.hpp>
+
+namespace mbgl {
+
+class TransformState;
+
+namespace style {
+
+class CustomLayer::Impl : public Layer::Impl {
+public:
+ Impl(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
+ CustomLayerDeinitializeFunction,
+ void* context);
+
+ Impl(const Impl&);
+ ~Impl() final;
+
+ void initialize();
+ void render(const TransformState&) const;
+
+private:
+ std::unique_ptr<Layer> clone() const override;
+
+ void parseLayout(const JSValue&) final {}
+ void parsePaints(const JSValue&) final {}
+
+ void cascade(const CascadeParameters&) final {}
+ bool recalculate(const CalculationParameters&) final;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) const final;
+
+ CustomLayerInitializeFunction initializeFn = nullptr;
+ CustomLayerRenderFunction renderFn = nullptr;
+ CustomLayerDeinitializeFunction deinitializeFn = nullptr;
+ void* context = nullptr;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp
new file mode 100644
index 0000000000..1deaabb5ef
--- /dev/null
+++ b/src/mbgl/style/layers/fill_layer.cpp
@@ -0,0 +1,113 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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);
+}
+
+// Source
+
+void FillLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& FillLayer::getSourceID() const {
+ return impl->source;
+}
+
+const std::string& FillLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Filter
+
+void FillLayer::setFilter(const Filter& filter) {
+ impl->filter = filter;
+}
+
+const Filter& FillLayer::getFilter() const {
+ return impl->filter;
+}
+
+// Layout properties
+
+
+// Paint properties
+
+PropertyValue<bool> FillLayer::getFillAntialias() const {
+ return impl->paint.fillAntialias.get();
+}
+
+void FillLayer::setFillAntialias(PropertyValue<bool> value) {
+ impl->paint.fillAntialias.set(value);
+}
+
+PropertyValue<float> FillLayer::getFillOpacity() const {
+ return impl->paint.fillOpacity.get();
+}
+
+void FillLayer::setFillOpacity(PropertyValue<float> value) {
+ impl->paint.fillOpacity.set(value);
+}
+
+PropertyValue<Color> FillLayer::getFillColor() const {
+ return impl->paint.fillColor.get();
+}
+
+void FillLayer::setFillColor(PropertyValue<Color> value) {
+ impl->paint.fillColor.set(value);
+}
+
+PropertyValue<Color> FillLayer::getFillOutlineColor() const {
+ return impl->paint.fillOutlineColor.get();
+}
+
+void FillLayer::setFillOutlineColor(PropertyValue<Color> value) {
+ impl->paint.fillOutlineColor.set(value);
+}
+
+PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate() const {
+ return impl->paint.fillTranslate.get();
+}
+
+void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value) {
+ impl->paint.fillTranslate.set(value);
+}
+
+PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor() const {
+ return impl->paint.fillTranslateAnchor.get();
+}
+
+void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value) {
+ impl->paint.fillTranslateAnchor.set(value);
+}
+
+PropertyValue<std::string> FillLayer::getFillPattern() const {
+ return impl->paint.fillPattern.get();
+}
+
+void FillLayer::setFillPattern(PropertyValue<std::string> value) {
+ impl->paint.fillPattern.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
new file mode 100644
index 0000000000..c183617482
--- /dev/null
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -0,0 +1,68 @@
+#include <mbgl/style/layers/fill_layer_impl.hpp>
+#include <mbgl/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 {
+namespace style {
+
+void FillLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void FillLayer::Impl::cascade(const CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool FillLayer::Impl::recalculate(const CalculationParameters& 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(BucketParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
new file mode 100644
index 0000000000..a37dd76ace
--- /dev/null
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp
new file mode 100644
index 0000000000..a4714689f9
--- /dev/null
+++ b/src/mbgl/style/layers/fill_layer_properties.cpp
@@ -0,0 +1,43 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/fill_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters& 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 CalculationParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp
new file mode 100644
index 0000000000..43396f45d2
--- /dev/null
+++ b/src/mbgl/style/layers/fill_layer_properties.hpp
@@ -0,0 +1,31 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class FillPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ 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, CrossFadedPropertyEvaluator> fillPattern { "" };
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp
new file mode 100644
index 0000000000..abe326a672
--- /dev/null
+++ b/src/mbgl/style/layers/line_layer.cpp
@@ -0,0 +1,165 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/line_layer.hpp>
+#include <mbgl/style/layers/line_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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);
+}
+
+// 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;
+}
+
+// Filter
+
+void LineLayer::setFilter(const Filter& filter) {
+ impl->filter = filter;
+}
+
+const Filter& LineLayer::getFilter() const {
+ return impl->filter;
+}
+
+// Layout properties
+
+PropertyValue<LineCapType> LineLayer::getLineCap() const {
+ return impl->layout.lineCap.get();
+}
+
+void LineLayer::setLineCap(PropertyValue<LineCapType> value) {
+ impl->layout.lineCap.set(value);
+}
+PropertyValue<LineJoinType> LineLayer::getLineJoin() const {
+ return impl->layout.lineJoin.get();
+}
+
+void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) {
+ impl->layout.lineJoin.set(value);
+}
+PropertyValue<float> LineLayer::getLineMiterLimit() const {
+ return impl->layout.lineMiterLimit.get();
+}
+
+void LineLayer::setLineMiterLimit(PropertyValue<float> value) {
+ impl->layout.lineMiterLimit.set(value);
+}
+PropertyValue<float> LineLayer::getLineRoundLimit() const {
+ return impl->layout.lineRoundLimit.get();
+}
+
+void LineLayer::setLineRoundLimit(PropertyValue<float> value) {
+ impl->layout.lineRoundLimit.set(value);
+}
+
+// Paint properties
+
+PropertyValue<float> LineLayer::getLineOpacity() const {
+ return impl->paint.lineOpacity.get();
+}
+
+void LineLayer::setLineOpacity(PropertyValue<float> value) {
+ impl->paint.lineOpacity.set(value);
+}
+
+PropertyValue<Color> LineLayer::getLineColor() const {
+ return impl->paint.lineColor.get();
+}
+
+void LineLayer::setLineColor(PropertyValue<Color> value) {
+ impl->paint.lineColor.set(value);
+}
+
+PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate() const {
+ return impl->paint.lineTranslate.get();
+}
+
+void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value) {
+ impl->paint.lineTranslate.set(value);
+}
+
+PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor() const {
+ return impl->paint.lineTranslateAnchor.get();
+}
+
+void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value) {
+ impl->paint.lineTranslateAnchor.set(value);
+}
+
+PropertyValue<float> LineLayer::getLineWidth() const {
+ return impl->paint.lineWidth.get();
+}
+
+void LineLayer::setLineWidth(PropertyValue<float> value) {
+ impl->paint.lineWidth.set(value);
+}
+
+PropertyValue<float> LineLayer::getLineGapWidth() const {
+ return impl->paint.lineGapWidth.get();
+}
+
+void LineLayer::setLineGapWidth(PropertyValue<float> value) {
+ impl->paint.lineGapWidth.set(value);
+}
+
+PropertyValue<float> LineLayer::getLineOffset() const {
+ return impl->paint.lineOffset.get();
+}
+
+void LineLayer::setLineOffset(PropertyValue<float> value) {
+ impl->paint.lineOffset.set(value);
+}
+
+PropertyValue<float> LineLayer::getLineBlur() const {
+ return impl->paint.lineBlur.get();
+}
+
+void LineLayer::setLineBlur(PropertyValue<float> value) {
+ impl->paint.lineBlur.set(value);
+}
+
+PropertyValue<std::vector<float>> LineLayer::getLineDasharray() const {
+ return impl->paint.lineDasharray.get();
+}
+
+void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value) {
+ impl->paint.lineDasharray.set(value);
+}
+
+PropertyValue<std::string> LineLayer::getLinePattern() const {
+ return impl->paint.linePattern.get();
+}
+
+void LineLayer::setLinePattern(PropertyValue<std::string> value) {
+ impl->paint.linePattern.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
new file mode 100644
index 0000000000..b7ee9dc5bf
--- /dev/null
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -0,0 +1,116 @@
+#include <mbgl/style/layers/line_layer_impl.hpp>
+#include <mbgl/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 {
+namespace style {
+
+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 CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool LineLayer::Impl::recalculate(const CalculationParameters& parameters) {
+ // for scaling dasharrays
+ CalculationParameters 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(BucketParameters& parameters) const {
+ auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor());
+
+ bucket->layout = layout;
+ bucket->layout.recalculate(CalculationParameters(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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
new file mode 100644
index 0000000000..3356dc2ceb
--- /dev/null
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/line_layer.hpp>
+#include <mbgl/style/layers/line_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp
new file mode 100644
index 0000000000..7c74f6de04
--- /dev/null
+++ b/src/mbgl/style/layers/line_layer_properties.cpp
@@ -0,0 +1,66 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/line_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CalculationParameters& 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 CascadeParameters& 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 CalculationParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp
new file mode 100644
index 0000000000..e0c63b516b
--- /dev/null
+++ b/src/mbgl/style/layers/line_layer_properties.hpp
@@ -0,0 +1,45 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class LineLayoutProperties {
+public:
+ void parse(const JSValue&);
+ void recalculate(const CalculationParameters&);
+
+ 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 CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ 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>, CrossFadedPropertyEvaluator> lineDasharray { { } };
+ PaintProperty<std::string, CrossFadedPropertyEvaluator> linePattern { "" };
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp
new file mode 100644
index 0000000000..fb7f08fbe9
--- /dev/null
+++ b/src/mbgl/style/layers/raster_layer.cpp
@@ -0,0 +1,98 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/style/layers/raster_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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);
+}
+
+// Source
+
+void RasterLayer::setSource(const std::string& sourceID) {
+ impl->source = sourceID;
+}
+
+const std::string& RasterLayer::getSourceID() const {
+ return impl->source;
+}
+
+// Layout properties
+
+
+// Paint properties
+
+PropertyValue<float> RasterLayer::getRasterOpacity() const {
+ return impl->paint.rasterOpacity.get();
+}
+
+void RasterLayer::setRasterOpacity(PropertyValue<float> value) {
+ impl->paint.rasterOpacity.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterHueRotate() const {
+ return impl->paint.rasterHueRotate.get();
+}
+
+void RasterLayer::setRasterHueRotate(PropertyValue<float> value) {
+ impl->paint.rasterHueRotate.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterBrightnessMin() const {
+ return impl->paint.rasterBrightnessMin.get();
+}
+
+void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value) {
+ impl->paint.rasterBrightnessMin.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterBrightnessMax() const {
+ return impl->paint.rasterBrightnessMax.get();
+}
+
+void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value) {
+ impl->paint.rasterBrightnessMax.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterSaturation() const {
+ return impl->paint.rasterSaturation.get();
+}
+
+void RasterLayer::setRasterSaturation(PropertyValue<float> value) {
+ impl->paint.rasterSaturation.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterContrast() const {
+ return impl->paint.rasterContrast.get();
+}
+
+void RasterLayer::setRasterContrast(PropertyValue<float> value) {
+ impl->paint.rasterContrast.set(value);
+}
+
+PropertyValue<float> RasterLayer::getRasterFadeDuration() const {
+ return impl->paint.rasterFadeDuration.get();
+}
+
+void RasterLayer::setRasterFadeDuration(PropertyValue<float> value) {
+ impl->paint.rasterFadeDuration.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp
new file mode 100644
index 0000000000..4854ec041d
--- /dev/null
+++ b/src/mbgl/style/layers/raster_layer_impl.cpp
@@ -0,0 +1,28 @@
+#include <mbgl/style/layers/raster_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+namespace style {
+
+void RasterLayer::Impl::parsePaints(const JSValue& layer) {
+ paint.parse(layer);
+}
+
+void RasterLayer::Impl::cascade(const CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool RasterLayer::Impl::recalculate(const CalculationParameters& parameters) {
+ bool hasTransitions = paint.recalculate(parameters);
+
+ passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+
+ return hasTransitions;
+}
+
+std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(BucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp
new file mode 100644
index 0000000000..6812b469a6
--- /dev/null
+++ b/src/mbgl/style/layers/raster_layer_impl.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/style/layers/raster_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
+
+ RasterPaintProperties paint;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp
new file mode 100644
index 0000000000..0e6afc5e9c
--- /dev/null
+++ b/src/mbgl/style/layers/raster_layer_properties.cpp
@@ -0,0 +1,43 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/raster_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters& 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 CalculationParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp
new file mode 100644
index 0000000000..049da87312
--- /dev/null
+++ b/src/mbgl/style/layers/raster_layer_properties.hpp
@@ -0,0 +1,31 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class RasterPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
new file mode 100644
index 0000000000..d7d6a02ace
--- /dev/null
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -0,0 +1,386 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/style/layers/symbol_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+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);
+}
+
+// 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;
+}
+
+// Filter
+
+void SymbolLayer::setFilter(const Filter& filter) {
+ impl->filter = filter;
+}
+
+const Filter& SymbolLayer::getFilter() const {
+ return impl->filter;
+}
+
+// Layout properties
+
+PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const {
+ return impl->layout.symbolPlacement.get();
+}
+
+void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) {
+ impl->layout.symbolPlacement.set(value);
+}
+PropertyValue<float> SymbolLayer::getSymbolSpacing() const {
+ return impl->layout.symbolSpacing.get();
+}
+
+void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) {
+ impl->layout.symbolSpacing.set(value);
+}
+PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const {
+ return impl->layout.symbolAvoidEdges.get();
+}
+
+void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) {
+ impl->layout.symbolAvoidEdges.set(value);
+}
+PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const {
+ return impl->layout.iconAllowOverlap.get();
+}
+
+void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) {
+ impl->layout.iconAllowOverlap.set(value);
+}
+PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const {
+ return impl->layout.iconIgnorePlacement.get();
+}
+
+void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) {
+ impl->layout.iconIgnorePlacement.set(value);
+}
+PropertyValue<bool> SymbolLayer::getIconOptional() const {
+ return impl->layout.iconOptional.get();
+}
+
+void SymbolLayer::setIconOptional(PropertyValue<bool> value) {
+ impl->layout.iconOptional.set(value);
+}
+PropertyValue<RotationAlignmentType> SymbolLayer::getIconRotationAlignment() const {
+ return impl->layout.iconRotationAlignment.get();
+}
+
+void SymbolLayer::setIconRotationAlignment(PropertyValue<RotationAlignmentType> value) {
+ impl->layout.iconRotationAlignment.set(value);
+}
+PropertyValue<float> SymbolLayer::getIconSize() const {
+ return impl->layout.iconSize.get();
+}
+
+void SymbolLayer::setIconSize(PropertyValue<float> value) {
+ impl->layout.iconSize.set(value);
+}
+PropertyValue<std::string> SymbolLayer::getIconImage() const {
+ return impl->layout.iconImage.get();
+}
+
+void SymbolLayer::setIconImage(PropertyValue<std::string> value) {
+ impl->layout.iconImage.set(value);
+}
+PropertyValue<float> SymbolLayer::getIconRotate() const {
+ return impl->layout.iconRotate.get();
+}
+
+void SymbolLayer::setIconRotate(PropertyValue<float> value) {
+ impl->layout.iconRotate.set(value);
+}
+PropertyValue<float> SymbolLayer::getIconPadding() const {
+ return impl->layout.iconPadding.get();
+}
+
+void SymbolLayer::setIconPadding(PropertyValue<float> value) {
+ impl->layout.iconPadding.set(value);
+}
+PropertyValue<bool> SymbolLayer::getIconKeepUpright() const {
+ return impl->layout.iconKeepUpright.get();
+}
+
+void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) {
+ impl->layout.iconKeepUpright.set(value);
+}
+PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
+ return impl->layout.iconOffset.get();
+}
+
+void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) {
+ impl->layout.iconOffset.set(value);
+}
+PropertyValue<RotationAlignmentType> SymbolLayer::getTextRotationAlignment() const {
+ return impl->layout.textRotationAlignment.get();
+}
+
+void SymbolLayer::setTextRotationAlignment(PropertyValue<RotationAlignmentType> value) {
+ impl->layout.textRotationAlignment.set(value);
+}
+PropertyValue<std::string> SymbolLayer::getTextField() const {
+ return impl->layout.textField.get();
+}
+
+void SymbolLayer::setTextField(PropertyValue<std::string> value) {
+ impl->layout.textField.set(value);
+}
+PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const {
+ return impl->layout.textFont.get();
+}
+
+void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) {
+ impl->layout.textFont.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextSize() const {
+ return impl->layout.textSize.get();
+}
+
+void SymbolLayer::setTextSize(PropertyValue<float> value) {
+ impl->layout.textSize.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextMaxWidth() const {
+ return impl->layout.textMaxWidth.get();
+}
+
+void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) {
+ impl->layout.textMaxWidth.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextLineHeight() const {
+ return impl->layout.textLineHeight.get();
+}
+
+void SymbolLayer::setTextLineHeight(PropertyValue<float> value) {
+ impl->layout.textLineHeight.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextLetterSpacing() const {
+ return impl->layout.textLetterSpacing.get();
+}
+
+void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) {
+ impl->layout.textLetterSpacing.set(value);
+}
+PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const {
+ return impl->layout.textJustify.get();
+}
+
+void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) {
+ impl->layout.textJustify.set(value);
+}
+PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const {
+ return impl->layout.textAnchor.get();
+}
+
+void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) {
+ impl->layout.textAnchor.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextMaxAngle() const {
+ return impl->layout.textMaxAngle.get();
+}
+
+void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) {
+ impl->layout.textMaxAngle.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextRotate() const {
+ return impl->layout.textRotate.get();
+}
+
+void SymbolLayer::setTextRotate(PropertyValue<float> value) {
+ impl->layout.textRotate.set(value);
+}
+PropertyValue<float> SymbolLayer::getTextPadding() const {
+ return impl->layout.textPadding.get();
+}
+
+void SymbolLayer::setTextPadding(PropertyValue<float> value) {
+ impl->layout.textPadding.set(value);
+}
+PropertyValue<bool> SymbolLayer::getTextKeepUpright() const {
+ return impl->layout.textKeepUpright.get();
+}
+
+void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) {
+ impl->layout.textKeepUpright.set(value);
+}
+PropertyValue<TextTransformType> SymbolLayer::getTextTransform() const {
+ return impl->layout.textTransform.get();
+}
+
+void SymbolLayer::setTextTransform(PropertyValue<TextTransformType> value) {
+ impl->layout.textTransform.set(value);
+}
+PropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const {
+ return impl->layout.textOffset.get();
+}
+
+void SymbolLayer::setTextOffset(PropertyValue<std::array<float, 2>> value) {
+ impl->layout.textOffset.set(value);
+}
+PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const {
+ return impl->layout.textAllowOverlap.get();
+}
+
+void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) {
+ impl->layout.textAllowOverlap.set(value);
+}
+PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const {
+ return impl->layout.textIgnorePlacement.get();
+}
+
+void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) {
+ impl->layout.textIgnorePlacement.set(value);
+}
+PropertyValue<bool> SymbolLayer::getTextOptional() const {
+ return impl->layout.textOptional.get();
+}
+
+void SymbolLayer::setTextOptional(PropertyValue<bool> value) {
+ impl->layout.textOptional.set(value);
+}
+
+// Paint properties
+
+PropertyValue<float> SymbolLayer::getIconOpacity() const {
+ return impl->paint.iconOpacity.get();
+}
+
+void SymbolLayer::setIconOpacity(PropertyValue<float> value) {
+ impl->paint.iconOpacity.set(value);
+}
+
+PropertyValue<Color> SymbolLayer::getIconColor() const {
+ return impl->paint.iconColor.get();
+}
+
+void SymbolLayer::setIconColor(PropertyValue<Color> value) {
+ impl->paint.iconColor.set(value);
+}
+
+PropertyValue<Color> SymbolLayer::getIconHaloColor() const {
+ return impl->paint.iconHaloColor.get();
+}
+
+void SymbolLayer::setIconHaloColor(PropertyValue<Color> value) {
+ impl->paint.iconHaloColor.set(value);
+}
+
+PropertyValue<float> SymbolLayer::getIconHaloWidth() const {
+ return impl->paint.iconHaloWidth.get();
+}
+
+void SymbolLayer::setIconHaloWidth(PropertyValue<float> value) {
+ impl->paint.iconHaloWidth.set(value);
+}
+
+PropertyValue<float> SymbolLayer::getIconHaloBlur() const {
+ return impl->paint.iconHaloBlur.get();
+}
+
+void SymbolLayer::setIconHaloBlur(PropertyValue<float> value) {
+ impl->paint.iconHaloBlur.set(value);
+}
+
+PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate() const {
+ return impl->paint.iconTranslate.get();
+}
+
+void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value) {
+ impl->paint.iconTranslate.set(value);
+}
+
+PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor() const {
+ return impl->paint.iconTranslateAnchor.get();
+}
+
+void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value) {
+ impl->paint.iconTranslateAnchor.set(value);
+}
+
+PropertyValue<float> SymbolLayer::getTextOpacity() const {
+ return impl->paint.textOpacity.get();
+}
+
+void SymbolLayer::setTextOpacity(PropertyValue<float> value) {
+ impl->paint.textOpacity.set(value);
+}
+
+PropertyValue<Color> SymbolLayer::getTextColor() const {
+ return impl->paint.textColor.get();
+}
+
+void SymbolLayer::setTextColor(PropertyValue<Color> value) {
+ impl->paint.textColor.set(value);
+}
+
+PropertyValue<Color> SymbolLayer::getTextHaloColor() const {
+ return impl->paint.textHaloColor.get();
+}
+
+void SymbolLayer::setTextHaloColor(PropertyValue<Color> value) {
+ impl->paint.textHaloColor.set(value);
+}
+
+PropertyValue<float> SymbolLayer::getTextHaloWidth() const {
+ return impl->paint.textHaloWidth.get();
+}
+
+void SymbolLayer::setTextHaloWidth(PropertyValue<float> value) {
+ impl->paint.textHaloWidth.set(value);
+}
+
+PropertyValue<float> SymbolLayer::getTextHaloBlur() const {
+ return impl->paint.textHaloBlur.get();
+}
+
+void SymbolLayer::setTextHaloBlur(PropertyValue<float> value) {
+ impl->paint.textHaloBlur.set(value);
+}
+
+PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate() const {
+ return impl->paint.textTranslate.get();
+}
+
+void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value) {
+ impl->paint.textTranslate.set(value);
+}
+
+PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor() const {
+ return impl->paint.textTranslateAnchor.get();
+}
+
+void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value) {
+ impl->paint.textTranslateAnchor.set(value);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
new file mode 100644
index 0000000000..a4dc264ed2
--- /dev/null
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -0,0 +1,82 @@
+#include <mbgl/style/layers/symbol_layer_impl.hpp>
+#include <mbgl/renderer/symbol_bucket.hpp>
+#include <mbgl/style/bucket_parameters.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CascadeParameters& parameters) {
+ paint.cascade(parameters);
+}
+
+bool SymbolLayer::Impl::recalculate(const CalculationParameters& 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(BucketParameters& parameters) const {
+ auto bucket = std::make_unique<SymbolBucket>(parameters.tileID.overscaleFactor(),
+ parameters.tileID.overscaledZ,
+ parameters.mode,
+ id,
+ parameters.layer.getName());
+
+ bucket->layout = layout;
+
+ CalculationParameters 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(CalculationParameters(18));
+ bucket->layout.textSize.calculate(CalculationParameters(18));
+ bucket->iconMaxSize = bucket->layout.iconSize;
+ bucket->textMaxSize = bucket->layout.textSize;
+ bucket->layout.iconSize.calculate(CalculationParameters(p.z + 1));
+ bucket->layout.textSize.calculate(CalculationParameters(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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
new file mode 100644
index 0000000000..9727cc6480
--- /dev/null
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/symbol_layer.hpp>
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
+
+namespace mbgl {
+
+class SpriteAtlas;
+
+namespace style {
+
+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 CascadeParameters&) override;
+ bool recalculate(const CalculationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
+
+ SymbolLayoutProperties layout;
+ SymbolPaintProperties paint;
+
+ float iconSize = 1.0f;
+ float textSize = 16.0f;
+
+ SpriteAtlas* spriteAtlas = nullptr;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp
new file mode 100644
index 0000000000..ce16ae2e50
--- /dev/null
+++ b/src/mbgl/style/layers/symbol_layer_properties.cpp
@@ -0,0 +1,132 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+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 CalculationParameters& 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 CascadeParameters& 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 CalculationParameters& 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 style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp
new file mode 100644
index 0000000000..38455b5cac
--- /dev/null
+++ b/src/mbgl/style/layers/symbol_layer_properties.hpp
@@ -0,0 +1,76 @@
+// 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 {
+namespace style {
+
+class CascadeParameters;
+class CalculationParameters;
+
+class SymbolLayoutProperties {
+public:
+ void parse(const JSValue&);
+ void recalculate(const CalculationParameters&);
+
+ LayoutProperty<SymbolPlacementType> symbolPlacement { SymbolPlacementType::Point };
+ 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 };
+ LayoutProperty<std::string> iconImage { "" };
+ 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 };
+ 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 };
+ 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 }} };
+ LayoutProperty<bool> textAllowOverlap { false };
+ LayoutProperty<bool> textIgnorePlacement { false };
+ LayoutProperty<bool> textOptional { false };
+};
+
+class SymbolPaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const CascadeParameters&);
+ bool recalculate(const CalculationParameters&);
+
+ PaintProperty<float> iconOpacity { 1 };
+ PaintProperty<Color> iconColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<Color> iconHaloColor { {{ 0, 0, 0, 0 }} };
+ 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 };
+ PaintProperty<Color> textColor { {{ 0, 0, 0, 1 }} };
+ PaintProperty<Color> textHaloColor { {{ 0, 0, 0, 0 }} };
+ PaintProperty<float> textHaloWidth { 0 };
+ PaintProperty<float> textHaloBlur { 0 };
+ PaintProperty<std::array<float, 2>> textTranslate { {{ 0, 0 }} };
+ PaintProperty<TranslateAnchorType> textTranslateAnchor { TranslateAnchorType::Map };
+};
+
+} // namespace style
+} // namespace mbgl