summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-04-25 13:15:44 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-02 14:51:39 -0700
commita43940afb2208c61b487bfd8729bbde1bd674794 (patch)
tree53d192ea899be1d88f99aeef3d1b3255f9cb5104
parent27baa34d44f0006c05ba7c417bf11e184b0bd22b (diff)
downloadqtlocation-mapboxgl-a43940afb2208c61b487bfd8729bbde1bd674794.tar.gz
[core] Runtime style layer API
-rw-r--r--Makefile3
-rw-r--r--include/mbgl/layer/background_layer.hpp39
-rw-r--r--include/mbgl/layer/circle_layer.hpp54
-rw-r--r--include/mbgl/layer/custom_layer.hpp30
-rw-r--r--include/mbgl/layer/fill_layer.hpp57
-rw-r--r--include/mbgl/layer/line_layer.hpp82
-rw-r--r--include/mbgl/layer/raster_layer.hpp56
-rw-r--r--include/mbgl/layer/symbol_layer.hpp175
-rw-r--r--include/mbgl/style/layer.hpp78
-rw-r--r--include/mbgl/style/types.hpp21
-rw-r--r--package.json3
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp1
-rw-r--r--scripts/generate-style-code.js346
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp15
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.cpp13
-rw-r--r--src/mbgl/annotation/line_annotation_impl.cpp16
-rw-r--r--src/mbgl/annotation/style_sourced_annotation_impl.cpp26
-rw-r--r--src/mbgl/geometry/feature_index.cpp5
-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.cpp (renamed from src/mbgl/style/style_layer.cpp)8
-rw-r--r--src/mbgl/layer/layer_impl.hpp (renamed from src/mbgl/style/style_layer.hpp)52
-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
-rw-r--r--src/mbgl/map/map.cpp1
-rw-r--r--src/mbgl/renderer/bucket.hpp4
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp2
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp2
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp2
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp2
-rw-r--r--src/mbgl/renderer/line_bucket.cpp2
-rw-r--r--src/mbgl/renderer/line_bucket.hpp4
-rw-r--r--src/mbgl/renderer/painter.cpp13
-rw-r--r--src/mbgl/renderer/painter.hpp1
-rw-r--r--src/mbgl/renderer/painter_background.cpp3
-rw-r--r--src/mbgl/renderer/painter_circle.cpp3
-rw-r--r--src/mbgl/renderer/painter_fill.cpp3
-rw-r--r--src/mbgl/renderer/painter_line.cpp7
-rw-r--r--src/mbgl/renderer/painter_raster.cpp3
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp10
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp2
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp2
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp2
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp4
-rw-r--r--src/mbgl/source/source.cpp2
-rw-r--r--src/mbgl/style/function.hpp28
-rw-r--r--src/mbgl/style/function_evaluator.hpp2
-rw-r--r--src/mbgl/style/layout_property.hpp2
-rw-r--r--src/mbgl/style/paint_property.hpp2
-rw-r--r--src/mbgl/style/property_parsing.cpp3
-rw-r--r--src/mbgl/style/property_parsing.hpp1
-rw-r--r--src/mbgl/style/render_item.hpp6
-rw-r--r--src/mbgl/style/style.cpp58
-rw-r--r--src/mbgl/style/style.hpp10
-rw-r--r--src/mbgl/style/style_parser.cpp65
-rw-r--r--src/mbgl/style/style_parser.hpp13
-rw-r--r--src/mbgl/text/quads.cpp2
-rw-r--r--src/mbgl/text/shaping.cpp2
-rw-r--r--src/mbgl/tile/raster_tile_data.cpp2
-rw-r--r--src/mbgl/tile/raster_tile_data.hpp4
-rw-r--r--src/mbgl/tile/tile_data.hpp4
-rw-r--r--src/mbgl/tile/tile_worker.cpp53
-rw-r--r--src/mbgl/tile/tile_worker.hpp8
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp6
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp2
-rw-r--r--src/mbgl/util/worker.cpp6
-rw-r--r--src/mbgl/util/worker.hpp2
-rw-r--r--test/style/functions.cpp1
-rw-r--r--test/style/source.cpp5
-rw-r--r--test/style/style_layer.cpp24
105 files changed, 3110 insertions, 1098 deletions
diff --git a/Makefile b/Makefile
index 8911e0029e..49e9669195 100644
--- a/Makefile
+++ b/Makefile
@@ -296,6 +296,9 @@ tidy: compdb
#### Miscellaneous targets #####################################################
+style-code:
+ node scripts/generate-style-code.js
+
clean:
-find ./deps/gyp -name "*.pyc" -exec rm {} \;
-rm -rf ./build \
diff --git a/include/mbgl/layer/background_layer.hpp b/include/mbgl/layer/background_layer.hpp
new file mode 100644
index 0000000000..79f24990e6
--- /dev/null
+++ b/include/mbgl/layer/background_layer.hpp
@@ -0,0 +1,39 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+namespace mbgl {
+
+class BackgroundLayer : public Layer {
+public:
+ BackgroundLayer(const std::string& layerID);
+ ~BackgroundLayer() final;
+
+ // Paint properties
+
+ Function<Color> getBackgroundColor() const;
+ void setBackgroundColor(Function<Color>);
+
+ Function<std::string> getBackgroundPattern() const;
+ void setBackgroundPattern(Function<std::string>);
+
+ Function<float> getBackgroundOpacity() const;
+ void setBackgroundOpacity(Function<float>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ BackgroundLayer(const Impl&);
+ BackgroundLayer(const BackgroundLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<BackgroundLayer>() const {
+ return type == Type::Background;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/circle_layer.hpp b/include/mbgl/layer/circle_layer.hpp
new file mode 100644
index 0000000000..14b9da895f
--- /dev/null
+++ b/include/mbgl/layer/circle_layer.hpp
@@ -0,0 +1,54 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+namespace mbgl {
+
+class CircleLayer : public Layer {
+public:
+ CircleLayer(const std::string& layerID);
+ ~CircleLayer() final;
+
+ // Source
+
+ void setSource(const std::string& sourceID, const std::string& sourceLayer);
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+
+ // Paint properties
+
+ Function<float> getCircleRadius() const;
+ void setCircleRadius(Function<float>);
+
+ Function<Color> getCircleColor() const;
+ void setCircleColor(Function<Color>);
+
+ Function<float> getCircleBlur() const;
+ void setCircleBlur(Function<float>);
+
+ Function<float> getCircleOpacity() const;
+ void setCircleOpacity(Function<float>);
+
+ Function<std::array<float, 2>> getCircleTranslate() const;
+ void setCircleTranslate(Function<std::array<float, 2>>);
+
+ Function<TranslateAnchorType> getCircleTranslateAnchor() const;
+ void setCircleTranslateAnchor(Function<TranslateAnchorType>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ CircleLayer(const Impl&);
+ CircleLayer(const CircleLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<CircleLayer>() const {
+ return type == Type::Circle;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/custom_layer.hpp b/include/mbgl/layer/custom_layer.hpp
new file mode 100644
index 0000000000..81e91ddf50
--- /dev/null
+++ b/include/mbgl/layer/custom_layer.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+namespace mbgl {
+
+class CustomLayer : public Layer {
+public:
+ CustomLayer(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
+ CustomLayerDeinitializeFunction,
+ void* context);
+ ~CustomLayer() final;
+
+ // Private implementation
+
+ class Impl;
+ Impl* impl;
+
+ CustomLayer(const Impl&);
+ CustomLayer(const CustomLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<CustomLayer>() const {
+ return type == Type::Custom;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/fill_layer.hpp b/include/mbgl/layer/fill_layer.hpp
new file mode 100644
index 0000000000..dc0752f9e2
--- /dev/null
+++ b/include/mbgl/layer/fill_layer.hpp
@@ -0,0 +1,57 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+namespace mbgl {
+
+class FillLayer : public Layer {
+public:
+ FillLayer(const std::string& layerID);
+ ~FillLayer() final;
+
+ // Source
+
+ void setSource(const std::string& sourceID, const std::string& sourceLayer);
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+
+ // Paint properties
+
+ Function<bool> getFillAntialias() const;
+ void setFillAntialias(Function<bool>);
+
+ Function<float> getFillOpacity() const;
+ void setFillOpacity(Function<float>);
+
+ Function<Color> getFillColor() const;
+ void setFillColor(Function<Color>);
+
+ Function<Color> getFillOutlineColor() const;
+ void setFillOutlineColor(Function<Color>);
+
+ Function<std::array<float, 2>> getFillTranslate() const;
+ void setFillTranslate(Function<std::array<float, 2>>);
+
+ Function<TranslateAnchorType> getFillTranslateAnchor() const;
+ void setFillTranslateAnchor(Function<TranslateAnchorType>);
+
+ Function<std::string> getFillPattern() const;
+ void setFillPattern(Function<std::string>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ FillLayer(const Impl&);
+ FillLayer(const FillLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<FillLayer>() const {
+ return type == Type::Fill;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/line_layer.hpp b/include/mbgl/layer/line_layer.hpp
new file mode 100644
index 0000000000..0f898d3c69
--- /dev/null
+++ b/include/mbgl/layer/line_layer.hpp
@@ -0,0 +1,82 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+#include <vector>
+
+namespace mbgl {
+
+class LineLayer : public Layer {
+public:
+ LineLayer(const std::string& layerID);
+ ~LineLayer() final;
+
+ // Source
+
+ void setSource(const std::string& sourceID, const std::string& sourceLayer);
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+
+ // Layout properties
+
+ Function<LineCapType> getLineCap() const;
+ void setLineCap(Function<LineCapType>);
+
+ Function<LineJoinType> getLineJoin() const;
+ void setLineJoin(Function<LineJoinType>);
+
+ Function<float> getLineMiterLimit() const;
+ void setLineMiterLimit(Function<float>);
+
+ Function<float> getLineRoundLimit() const;
+ void setLineRoundLimit(Function<float>);
+
+ // Paint properties
+
+ Function<float> getLineOpacity() const;
+ void setLineOpacity(Function<float>);
+
+ Function<Color> getLineColor() const;
+ void setLineColor(Function<Color>);
+
+ Function<std::array<float, 2>> getLineTranslate() const;
+ void setLineTranslate(Function<std::array<float, 2>>);
+
+ Function<TranslateAnchorType> getLineTranslateAnchor() const;
+ void setLineTranslateAnchor(Function<TranslateAnchorType>);
+
+ Function<float> getLineWidth() const;
+ void setLineWidth(Function<float>);
+
+ Function<float> getLineGapWidth() const;
+ void setLineGapWidth(Function<float>);
+
+ Function<float> getLineOffset() const;
+ void setLineOffset(Function<float>);
+
+ Function<float> getLineBlur() const;
+ void setLineBlur(Function<float>);
+
+ Function<std::vector<float>> getLineDasharray() const;
+ void setLineDasharray(Function<std::vector<float>>);
+
+ Function<std::string> getLinePattern() const;
+ void setLinePattern(Function<std::string>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ LineLayer(const Impl&);
+ LineLayer(const LineLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<LineLayer>() const {
+ return type == Type::Line;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/raster_layer.hpp b/include/mbgl/layer/raster_layer.hpp
new file mode 100644
index 0000000000..9dc27a274a
--- /dev/null
+++ b/include/mbgl/layer/raster_layer.hpp
@@ -0,0 +1,56 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+namespace mbgl {
+
+class RasterLayer : public Layer {
+public:
+ RasterLayer(const std::string& layerID);
+ ~RasterLayer() final;
+
+ // Source
+
+ void setSource(const std::string& sourceID);
+ const std::string& getSourceID() const;
+
+ // Paint properties
+
+ Function<float> getRasterOpacity() const;
+ void setRasterOpacity(Function<float>);
+
+ Function<float> getRasterHueRotate() const;
+ void setRasterHueRotate(Function<float>);
+
+ Function<float> getRasterBrightnessMin() const;
+ void setRasterBrightnessMin(Function<float>);
+
+ Function<float> getRasterBrightnessMax() const;
+ void setRasterBrightnessMax(Function<float>);
+
+ Function<float> getRasterSaturation() const;
+ void setRasterSaturation(Function<float>);
+
+ Function<float> getRasterContrast() const;
+ void setRasterContrast(Function<float>);
+
+ Function<float> getRasterFadeDuration() const;
+ void setRasterFadeDuration(Function<float>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ RasterLayer(const Impl&);
+ RasterLayer(const RasterLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<RasterLayer>() const {
+ return type == Type::Raster;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/layer/symbol_layer.hpp b/include/mbgl/layer/symbol_layer.hpp
new file mode 100644
index 0000000000..f9b2956390
--- /dev/null
+++ b/include/mbgl/layer/symbol_layer.hpp
@@ -0,0 +1,175 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+
+#include <vector>
+
+namespace mbgl {
+
+class SymbolLayer : public Layer {
+public:
+ SymbolLayer(const std::string& layerID);
+ ~SymbolLayer() final;
+
+ // Source
+
+ void setSource(const std::string& sourceID, const std::string& sourceLayer);
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+
+ // Layout properties
+
+ Function<SymbolPlacementType> getSymbolPlacement() const;
+ void setSymbolPlacement(Function<SymbolPlacementType>);
+
+ Function<float> getSymbolSpacing() const;
+ void setSymbolSpacing(Function<float>);
+
+ Function<bool> getSymbolAvoidEdges() const;
+ void setSymbolAvoidEdges(Function<bool>);
+
+ Function<bool> getIconAllowOverlap() const;
+ void setIconAllowOverlap(Function<bool>);
+
+ Function<bool> getIconIgnorePlacement() const;
+ void setIconIgnorePlacement(Function<bool>);
+
+ Function<bool> getIconOptional() const;
+ void setIconOptional(Function<bool>);
+
+ Function<RotationAlignmentType> getIconRotationAlignment() const;
+ void setIconRotationAlignment(Function<RotationAlignmentType>);
+
+ Function<float> getIconSize() const;
+ void setIconSize(Function<float>);
+
+ Function<std::string> getIconImage() const;
+ void setIconImage(Function<std::string>);
+
+ Function<float> getIconRotate() const;
+ void setIconRotate(Function<float>);
+
+ Function<float> getIconPadding() const;
+ void setIconPadding(Function<float>);
+
+ Function<bool> getIconKeepUpright() const;
+ void setIconKeepUpright(Function<bool>);
+
+ Function<std::array<float, 2>> getIconOffset() const;
+ void setIconOffset(Function<std::array<float, 2>>);
+
+ Function<RotationAlignmentType> getTextRotationAlignment() const;
+ void setTextRotationAlignment(Function<RotationAlignmentType>);
+
+ Function<std::string> getTextField() const;
+ void setTextField(Function<std::string>);
+
+ Function<std::vector<std::string>> getTextFont() const;
+ void setTextFont(Function<std::vector<std::string>>);
+
+ Function<float> getTextSize() const;
+ void setTextSize(Function<float>);
+
+ Function<float> getTextMaxWidth() const;
+ void setTextMaxWidth(Function<float>);
+
+ Function<float> getTextLineHeight() const;
+ void setTextLineHeight(Function<float>);
+
+ Function<float> getTextLetterSpacing() const;
+ void setTextLetterSpacing(Function<float>);
+
+ Function<TextJustifyType> getTextJustify() const;
+ void setTextJustify(Function<TextJustifyType>);
+
+ Function<TextAnchorType> getTextAnchor() const;
+ void setTextAnchor(Function<TextAnchorType>);
+
+ Function<float> getTextMaxAngle() const;
+ void setTextMaxAngle(Function<float>);
+
+ Function<float> getTextRotate() const;
+ void setTextRotate(Function<float>);
+
+ Function<float> getTextPadding() const;
+ void setTextPadding(Function<float>);
+
+ Function<bool> getTextKeepUpright() const;
+ void setTextKeepUpright(Function<bool>);
+
+ Function<TextTransformType> getTextTransform() const;
+ void setTextTransform(Function<TextTransformType>);
+
+ Function<std::array<float, 2>> getTextOffset() const;
+ void setTextOffset(Function<std::array<float, 2>>);
+
+ Function<bool> getTextAllowOverlap() const;
+ void setTextAllowOverlap(Function<bool>);
+
+ Function<bool> getTextIgnorePlacement() const;
+ void setTextIgnorePlacement(Function<bool>);
+
+ Function<bool> getTextOptional() const;
+ void setTextOptional(Function<bool>);
+
+ // Paint properties
+
+ Function<float> getIconOpacity() const;
+ void setIconOpacity(Function<float>);
+
+ Function<Color> getIconColor() const;
+ void setIconColor(Function<Color>);
+
+ Function<Color> getIconHaloColor() const;
+ void setIconHaloColor(Function<Color>);
+
+ Function<float> getIconHaloWidth() const;
+ void setIconHaloWidth(Function<float>);
+
+ Function<float> getIconHaloBlur() const;
+ void setIconHaloBlur(Function<float>);
+
+ Function<std::array<float, 2>> getIconTranslate() const;
+ void setIconTranslate(Function<std::array<float, 2>>);
+
+ Function<TranslateAnchorType> getIconTranslateAnchor() const;
+ void setIconTranslateAnchor(Function<TranslateAnchorType>);
+
+ Function<float> getTextOpacity() const;
+ void setTextOpacity(Function<float>);
+
+ Function<Color> getTextColor() const;
+ void setTextColor(Function<Color>);
+
+ Function<Color> getTextHaloColor() const;
+ void setTextHaloColor(Function<Color>);
+
+ Function<float> getTextHaloWidth() const;
+ void setTextHaloWidth(Function<float>);
+
+ Function<float> getTextHaloBlur() const;
+ void setTextHaloBlur(Function<float>);
+
+ Function<std::array<float, 2>> getTextTranslate() const;
+ void setTextTranslate(Function<std::array<float, 2>>);
+
+ Function<TranslateAnchorType> getTextTranslateAnchor() const;
+ void setTextTranslateAnchor(Function<TranslateAnchorType>);
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ SymbolLayer(const Impl&);
+ SymbolLayer(const SymbolLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<SymbolLayer>() const {
+ return type == Type::Symbol;
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp
new file mode 100644
index 0000000000..e6c33a9784
--- /dev/null
+++ b/include/mbgl/style/layer.hpp
@@ -0,0 +1,78 @@
+#ifndef MBGL_LAYER
+#define MBGL_LAYER
+
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/style/types.hpp>
+
+#include <memory>
+
+namespace mbgl {
+
+/**
+ * The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style
+ * Specification.
+ *
+ * `Layer` is an abstract base class; concrete derived classes are provided for each layer type. `Layer` contains
+ * functionality that is common to all layer types:
+ *
+ * * Runtime type information: type predicates and casting
+ * * Accessors for properties common to all layer types: ID, visibility, etc.
+ * * Cloning and copying
+ *
+ * All other functionality lives in the derived classes. To instantiate a layer, create an instance of the desired
+ * type, passing the ID:
+ *
+ * auto circleLayer = std::make_unique<CircleLayer>("my-circle-layer");
+ */
+class Layer : public mbgl::util::noncopyable {
+public:
+ virtual ~Layer();
+
+ // Check whether this layer is of the given subtype.
+ template <class T>
+ bool is() const;
+
+ // Dynamically cast this layer to the given subtype.
+ template <class T>
+ T* as() {
+ return is<T>() ? reinterpret_cast<T*>(this) : nullptr;
+ }
+
+ template <class T>
+ const T* as() const {
+ return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
+ }
+
+ const std::string& getID() const;
+
+ // Visibility
+ VisibilityType getVisibility() const;
+ void setVisibility(VisibilityType);
+
+ // Create a new layer with the specified `id` and `ref`. All other properties
+ // are copied from this layer.
+ std::unique_ptr<Layer> copy(const std::string& id,
+ const std::string& ref) const;
+
+ // Private implementation
+ class Impl;
+ const std::unique_ptr<Impl> baseImpl;
+
+protected:
+ enum class Type {
+ Fill,
+ Line,
+ Circle,
+ Symbol,
+ Raster,
+ Background,
+ Custom,
+ };
+
+ const Type type;
+ Layer(Type, std::unique_ptr<Impl>);
+};
+
+} // namespace mbgl
+
+#endif
diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp
index 9b03ab8a2d..a852a09a14 100644
--- a/include/mbgl/style/types.hpp
+++ b/include/mbgl/style/types.hpp
@@ -5,6 +5,7 @@
#include <string>
#include <array>
#include <vector>
+#include <utility>
namespace mbgl {
@@ -20,6 +21,26 @@ struct FontStackHash {
std::size_t operator()(const FontStack&) const;
};
+template <typename T>
+class Function {
+public:
+ using Stop = std::pair<float, T>;
+ using Stops = std::vector<Stop>;
+
+ Function(const T& constant)
+ : stops({{ 0, constant }}) {}
+
+ explicit Function(const Stops& stops_, float base_)
+ : base(base_), stops(stops_) {}
+
+ float getBase() const { return base; }
+ const std::vector<std::pair<float, T>>& getStops() const { return stops; }
+
+private:
+ float base = 1;
+ std::vector<std::pair<float, T>> stops;
+};
+
// -------------------------------------------------------------------------------------------------
enum class SourceType : uint8_t {
diff --git a/package.json b/package.json
index 4c94cdd391..4fc0da158d 100644
--- a/package.json
+++ b/package.json
@@ -18,8 +18,11 @@
},
"devDependencies": {
"aws-sdk": "^2.3.5",
+ "csscolorparser": "^1.0.2",
+ "ejs": "^2.4.1",
"express": "^4.11.1",
"mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#e032997109c0ead5394ff64f2f0ea6b0f8efdc3f",
+ "mapbox-gl-style-spec": "^8.5.1",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#f45fd7aba98650c7f3bf778c9cbbfd3b548a4ee8",
"node-gyp": "^3.3.1",
"request": "^2.72.0",
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index d694235149..76a9c38c8b 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -4,7 +4,6 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/style/style_parser.hpp>
-#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/text/glyph.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/mapbox.hpp>
diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js
new file mode 100644
index 0000000000..2904a1429a
--- /dev/null
+++ b/scripts/generate-style-code.js
@@ -0,0 +1,346 @@
+'use strict';
+
+const fs = require('fs');
+const ejs = require('ejs');
+const spec = require('mapbox-gl-style-spec').latest;
+var parseCSSColor = require('csscolorparser').parseCSSColor;
+
+global.camelize = function (str) {
+ return str.replace(/(?:^|-)(.)/g, function (_, x) {
+ return x.toUpperCase();
+ });
+}
+
+global.camelizeWithLeadingLowercase = function (str) {
+ return str.replace(/-(.)/g, function (_, x) {
+ return x.toUpperCase();
+ });
+}
+
+global.propertyType = function (property) {
+ if (/-translate-anchor$/.test(property.name)) {
+ return 'TranslateAnchorType';
+ }
+ if (/-rotation-alignment$/.test(property.name)) {
+ return 'RotationAlignmentType';
+ }
+ switch (property.type) {
+ case 'boolean':
+ return 'bool';
+ case 'number':
+ return 'float';
+ case 'string':
+ return 'std::string';
+ case 'enum':
+ return `${camelize(property.name)}Type`;
+ case 'color':
+ return `Color`;
+ case 'array':
+ if (property.length) {
+ return `std::array<${propertyType({type: property.value})}, ${property.length}>`;
+ } else {
+ return `std::vector<${propertyType({type: property.value})}>`;
+ }
+ default: throw new Error(`unknown type for ${property.name}`)
+ }
+}
+
+global.defaultValue = function (property) {
+ switch (property.type) {
+ case 'number':
+ return property.default;
+ case 'string':
+ return JSON.stringify(property.default || "");
+ case 'enum':
+ return `${propertyType(property)}::${camelize(property.default)}`;
+ case 'color':
+ return `{{ ${parseCSSColor(property.default).join(', ')} }}`
+ case 'array':
+ const defaults = (property.default || []).map((e) => defaultValue({ type: property.value, default: e }));
+ if (property.length) {
+ return `{{ ${defaults.join(', ')} }}`;
+ } else {
+ return `{ ${defaults.join(', ')} }`;
+ }
+ default:
+ return property.default;
+ }
+}
+
+const layerHpp = ejs.compile(`<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+<% if (type === 'line' || type === 'symbol') { %>
+#include <vector>
+<% } -%>
+
+namespace mbgl {
+
+class <%- camelize(type) %>Layer : public Layer {
+public:
+ <%- camelize(type) %>Layer(const std::string& layerID);
+ ~<%- camelize(type) %>Layer() final;
+
+<% if (type === 'raster') { -%>
+ // Source
+
+ void setSource(const std::string& sourceID);
+ const std::string& getSourceID() const;
+
+<% } else if (type !== 'background') { -%>
+ // Source
+
+ void setSource(const std::string& sourceID, const std::string& sourceLayer);
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+
+<% } -%>
+<% if (layoutProperties.length) { -%>
+ // Layout properties
+
+<% for (const property of layoutProperties) { -%>
+ Function<<%- propertyType(property) %>> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(Function<<%- propertyType(property) %>>);
+
+<% } -%>
+<% } -%>
+ // Paint properties
+
+<% for (const property of paintProperties) { -%>
+ Function<<%- propertyType(property) %>> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(Function<<%- propertyType(property) %>>);
+
+<% } -%>
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ <%- camelize(type) %>Layer(const Impl&);
+ <%- camelize(type) %>Layer(const <%- camelize(type) %>Layer&) = delete;
+};
+
+template <>
+inline bool Layer::is<<%- camelize(type) %>Layer>() const {
+ return type == Type::<%- camelize(type) %>;
+}
+
+} // namespace mbgl
+`, {strict: true});
+
+const layerCpp = ejs.compile(`<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Edit scripts/generate-style-code.js, then run \`make style-code\`.
+
+#include <mbgl/layer/<%- type %>_layer.hpp>
+#include <mbgl/layer/<%- type %>_layer_impl.hpp>
+
+namespace mbgl {
+
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const std::string& layerID)
+ : Layer(Type::<%- camelize(type) %>, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+}
+
+<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(const Impl& other)
+ : Layer(Type::<%- camelize(type) %>, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+<%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default;
+
+std::unique_ptr<Layer> <%- camelize(type) %>Layer::Impl::clone() const {
+ return std::make_unique<<%- camelize(type) %>Layer>(*this);
+}
+
+<% if (type === 'raster') { -%>
+// Source
+
+void <%- camelize(type) %>Layer::setSource(const std::string& sourceID) {
+ impl->source = sourceID;
+}
+
+const std::string& <%- camelize(type) %>Layer::getSourceID() const {
+ return impl->source;
+}
+<% } else if (type !== 'background') { -%>
+// Source
+
+void <%- camelize(type) %>Layer::setSource(const std::string& sourceID, const std::string& sourceLayer) {
+ impl->source = sourceID;
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& <%- camelize(type) %>Layer::getSourceID() const {
+ return impl->source;
+}
+
+const std::string& <%- camelize(type) %>Layer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+<% } -%>
+
+// Layout properties
+
+<% for (const property of layoutProperties) { -%>
+Function<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
+ return *impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.parsedValue;
+}
+
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(Function<<%- propertyType(property) %>> value) {
+ impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.parsedValue = value;
+}
+<% } -%>
+
+// Paint properties
+<% for (const property of paintProperties) { %>
+Function<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
+ return impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.values.at(ClassID::Default);
+}
+
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(Function<<%- propertyType(property) %>> value) {
+ impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.values.emplace(ClassID::Default, value);
+}
+<% } -%>
+
+} // namespace mbgl
+`, {strict: true});
+
+const propertiesHpp = ejs.compile(`<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// 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;
+
+<% if (layoutProperties.length) { -%>
+class <%- camelize(type) %>LayoutProperties {
+public:
+ void parse(const JSValue&);
+ void recalculate(const StyleCalculationParameters&);
+
+<% for (const property of layoutProperties) { -%>
+ LayoutProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
+<% } -%>
+};
+
+<% } -%>
+class <%- camelize(type) %>PaintProperties {
+public:
+ void parse(const JSValue&);
+ void cascade(const StyleCascadeParameters&);
+ bool recalculate(const StyleCalculationParameters&);
+
+<% for (const property of paintProperties) { -%>
+<% if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') { -%>
+ PaintProperty<<%- propertyType(property) %>, CrossFadedFunctionEvaluator> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
+<% } else if (property.name === 'fill-outline-color') { -%>
+ PaintProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { {{ 0, 0, 0, -1 }} };
+<% } else { -%>
+ PaintProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
+<% } -%>
+<% } -%>
+};
+
+} // namespace mbgl
+`, {strict: true});
+
+const propertiesCpp = ejs.compile(`<%
+ const type = locals.type;
+ const layoutProperties = locals.layoutProperties;
+ const paintProperties = locals.paintProperties;
+-%>
+// This file is generated. Edit scripts/generate-style-code.js, then run \`make style-code\`.
+
+#include <mbgl/layer/<%- type %>_layer_properties.hpp>
+
+namespace mbgl {
+
+<% if (layoutProperties.length) { -%>
+void <%- camelize(type) %>LayoutProperties::parse(const JSValue& value) {
+<% for (const property of layoutProperties) { -%>
+ <%- camelizeWithLeadingLowercase(property.name) %>.parse(<%- JSON.stringify(property.name) %>, value);
+<% } -%>
+}
+
+void <%- camelize(type) %>LayoutProperties::recalculate(const StyleCalculationParameters& parameters) {
+<% for (const property of layoutProperties) { -%>
+ <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters);
+<% } -%>
+}
+
+<% } -%>
+void <%- camelize(type) %>PaintProperties::parse(const JSValue& value) {
+<% for (const property of paintProperties) { -%>
+ <%- camelizeWithLeadingLowercase(property.name) %>.parse(<%- JSON.stringify(property.name) %>, value);
+<% } -%>
+}
+
+void <%- camelize(type) %>PaintProperties::cascade(const StyleCascadeParameters& parameters) {
+<% for (const property of paintProperties) { -%>
+ <%- camelizeWithLeadingLowercase(property.name) %>.cascade(parameters);
+<% } -%>
+}
+
+bool <%- camelize(type) %>PaintProperties::recalculate(const StyleCalculationParameters& parameters) {
+ bool hasTransitions = false;
+
+<% for (const property of paintProperties) { -%>
+ hasTransitions |= <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters);
+<% } -%>
+
+ return hasTransitions;
+}
+
+} // namespace mbgl
+`, {strict: true});
+
+for (const type of spec.layer.type.values) {
+ const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => {
+ if (name !== 'visibility') {
+ spec[`layout_${type}`][name].name = name;
+ memo.push(spec[`layout_${type}`][name]);
+ }
+ return memo;
+ }, []);
+
+ const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => {
+ spec[`paint_${type}`][name].name = name;
+ memo.push(spec[`paint_${type}`][name]);
+ return memo;
+ }, []);
+
+ const layer = {
+ type: type,
+ layoutProperties: layoutProperties,
+ paintProperties: paintProperties,
+ };
+
+ fs.writeFileSync(`include/mbgl/layer/${type}_layer.hpp`, layerHpp(layer));
+ fs.writeFileSync(`src/mbgl/layer/${type}_layer.cpp`, layerCpp(layer));
+
+ fs.writeFileSync(`src/mbgl/layer/${type}_layer_properties.hpp`, propertiesHpp(layer));
+ fs.writeFileSync(`src/mbgl/layer/${type}_layer_properties.cpp`, propertiesCpp(layer));
+}
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 4d7059f80f..09442b165c 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -7,6 +7,7 @@
#include <mbgl/source/source.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
#include <boost/function_output_iterator.hpp>
@@ -108,13 +109,13 @@ void AnnotationManager::updateStyle(Style& style) {
source->enabled = true;
style.addSource(std::move(source));
- std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>();
- layer->id = PointLayerID;
- layer->source = SourceID;
- layer->sourceLayer = PointLayerID;
- layer->layout.iconImage = std::string("{sprite}");
- layer->layout.iconAllowOverlap = true;
- layer->spriteAtlas = &spriteAtlas;
+ std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>(PointLayerID);
+
+ layer->setSource(SourceID, PointLayerID);
+ layer->setIconImage({"{sprite}"});
+ layer->setIconAllowOverlap(true);
+
+ layer->impl->spriteAtlas = &spriteAtlas;
style.addLayer(std::move(layer));
}
diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp
index 093f53fb91..17bdd9c38e 100644
--- a/src/mbgl/annotation/fill_annotation_impl.cpp
+++ b/src/mbgl/annotation/fill_annotation_impl.cpp
@@ -16,15 +16,12 @@ void FillAnnotationImpl::updateStyle(Style& style) const {
if (style.getLayer(layerID))
return;
- std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>();
+ std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>(layerID);
+ layer->setSource(AnnotationManager::SourceID, layerID);
- layer->paint.fillOpacity = annotation.opacity;
- layer->paint.fillColor = annotation.color;
- layer->paint.fillOutlineColor = annotation.outlineColor;
-
- layer->id = layerID;
- layer->source = AnnotationManager::SourceID;
- layer->sourceLayer = layer->id;
+ layer->setFillOpacity(annotation.opacity);
+ layer->setFillColor(annotation.color);
+ layer->setFillOutlineColor(annotation.outlineColor);
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
}
diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp
index 5bcc142a5b..11febc7de7 100644
--- a/src/mbgl/annotation/line_annotation_impl.cpp
+++ b/src/mbgl/annotation/line_annotation_impl.cpp
@@ -16,16 +16,12 @@ void LineAnnotationImpl::updateStyle(Style& style) const {
if (style.getLayer(layerID))
return;
- std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>();
- layer->layout.lineJoin = LineJoinType::Round;
-
- layer->paint.lineOpacity = annotation.opacity;
- layer->paint.lineWidth = annotation.width;
- layer->paint.lineColor = annotation.color;
-
- layer->id = layerID;
- layer->source = AnnotationManager::SourceID;
- layer->sourceLayer = layer->id;
+ std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>(layerID);
+ layer->setSource(AnnotationManager::SourceID, layerID);
+ layer->setLineJoin(LineJoinType::Round);
+ layer->setLineOpacity(annotation.opacity);
+ layer->setLineWidth(annotation.width);
+ layer->setLineColor(annotation.color);
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
}
diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.cpp b/src/mbgl/annotation/style_sourced_annotation_impl.cpp
index ae92d917aa..e1e11a664a 100644
--- a/src/mbgl/annotation/style_sourced_annotation_impl.cpp
+++ b/src/mbgl/annotation/style_sourced_annotation_impl.cpp
@@ -1,7 +1,9 @@
#include <mbgl/annotation/style_sourced_annotation_impl.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/style/style.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/style/layer.hpp>
+#include <mbgl/layer/line_layer.hpp>
+#include <mbgl/layer/fill_layer.hpp>
namespace mbgl {
@@ -16,19 +18,21 @@ void StyleSourcedAnnotationImpl::updateStyle(Style& style) const {
if (style.getLayer(layerID))
return;
- const StyleLayer* sourceLayer = style.getLayer(annotation.layerID);
+ const Layer* sourceLayer = style.getLayer(annotation.layerID);
if (!sourceLayer)
return;
- std::unique_ptr<StyleLayer> layer = sourceLayer->clone();
-
- layer->id = layerID;
- layer->ref = "";
- layer->source = AnnotationManager::SourceID;
- layer->sourceLayer = layer->id;
- layer->visibility = VisibilityType::Visible;
-
- style.addLayer(std::move(layer), sourceLayer->id);
+ if (sourceLayer->is<LineLayer>()) {
+ std::unique_ptr<Layer> layer = sourceLayer->copy(layerID, "");
+ layer->as<LineLayer>()->setSource(AnnotationManager::SourceID, layerID);
+ layer->as<LineLayer>()->setVisibility(VisibilityType::Visible);
+ style.addLayer(std::move(layer), sourceLayer->getID());
+ } else if (sourceLayer->is<FillLayer>()) {
+ std::unique_ptr<Layer> layer = sourceLayer->copy(layerID, "");
+ layer->as<FillLayer>()->setSource(AnnotationManager::SourceID, layerID);
+ layer->as<FillLayer>()->setVisibility(VisibilityType::Visible);
+ style.addLayer(std::move(layer), sourceLayer->getID());
+ }
}
const ShapeAnnotationGeometry& StyleSourcedAnnotationImpl::geometry() const {
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index ab451bcd6a..e72aa344fa 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -1,6 +1,7 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/style/style.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/style/layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/util/constants.hpp>
@@ -116,7 +117,7 @@ void FeatureIndex::addFeature(
auto styleLayer = style.getLayer(layerID);
if (!styleLayer ||
(!styleLayer->is<SymbolLayer>() &&
- !styleLayer->queryIntersectsGeometry(queryGeometry, geometryTileFeature->getGeometries(), bearing, pixelsToTileUnits))) {
+ !styleLayer->baseImpl->queryIntersectsGeometry(queryGeometry, geometryTileFeature->getGeometries(), bearing, pixelsToTileUnits))) {
continue;
}
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/style/style_layer.cpp b/src/mbgl/layer/layer_impl.cpp
index defdfca110..315a1cb1b1 100644
--- a/src/mbgl/style/style_layer.cpp
+++ b/src/mbgl/layer/layer_impl.cpp
@@ -1,16 +1,16 @@
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
namespace mbgl {
-const std::string& StyleLayer::bucketName() const {
+const std::string& Layer::Impl::bucketName() const {
return ref.empty() ? id : ref;
}
-bool StyleLayer::hasRenderPass(RenderPass pass) const {
+bool Layer::Impl::hasRenderPass(RenderPass pass) const {
return bool(passes & pass);
}
-bool StyleLayer::needsRendering() const {
+bool Layer::Impl::needsRendering() const {
return passes != RenderPass::None && visibility != VisibilityType::None;
}
diff --git a/src/mbgl/style/style_layer.hpp b/src/mbgl/layer/layer_impl.hpp
index 1388cbcb5a..3d6b5cccfd 100644
--- a/src/mbgl/style/style_layer.hpp
+++ b/src/mbgl/layer/layer_impl.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/style/layer.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/renderer/render_pass.hpp>
@@ -18,26 +19,23 @@ class StyleCalculationParameters;
class StyleBucketParameters;
class Bucket;
-class StyleLayer {
+/**
+ * `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 ~StyleLayer() = default;
+ virtual ~Impl() = default;
- // Check whether this layer is of the given subtype.
- template <class T>
- bool is() const;
-
- // Dynamically cast this layer to the given subtype.
- template <class T>
- T* as() {
- return is<T>() ? reinterpret_cast<T*>(this) : nullptr;
- }
- template <class T>
- const T* as() const {
- return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
- }
-
- // Create a copy of this layer.
- virtual std::unique_ptr<StyleLayer> clone() const = 0;
+ // 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;
@@ -78,21 +76,9 @@ public:
VisibilityType visibility = VisibilityType::Visible;
protected:
- enum class Type {
- Fill,
- Line,
- Circle,
- Symbol,
- Raster,
- Background,
- Custom,
- };
-
- StyleLayer(Type type_) : type(type_) {}
- StyleLayer(const StyleLayer&) = default;
- StyleLayer& operator=(const StyleLayer&) = delete;
-
- const Type type;
+ 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.
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
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index f89fde1f03..aee6777525 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -6,7 +6,6 @@
#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/style_observer.hpp>
-#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/property_transition.hpp>
#include <mbgl/style/style_update_parameters.hpp>
#include <mbgl/style/style_query_parameters.hpp>
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index cffc0ba8df..89b0ceefb2 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -13,7 +13,7 @@
namespace mbgl {
class Painter;
-class StyleLayer;
+class Layer;
class UnwrappedTileID;
class CollisionTile;
@@ -31,7 +31,7 @@ public:
// Every time this bucket is getting rendered, this function is called. This happens either
// once or twice (for Opaque and Transparent render passes).
- virtual void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) = 0;
+ virtual void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) = 0;
virtual ~Bucket() = default;
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index 6df186f2d0..969e05131b 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -21,7 +21,7 @@ void CircleBucket::upload(gl::ObjectStore& store) {
}
void CircleBucket::render(Painter& painter,
- const StyleLayer& layer,
+ const Layer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
painter.renderCircle(*this, *layer.as<CircleLayer>(), tileID, matrix);
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index b0349c7426..9c95fce045 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -19,7 +19,7 @@ public:
~CircleBucket() override;
void upload(gl::ObjectStore&) override;
- void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override;
+ void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override;
bool hasData() const override;
bool needsClipping() const override;
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index 78d4c40a97..4a9709f4e8 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -104,7 +104,7 @@ void FillBucket::upload(gl::ObjectStore& store) {
}
void FillBucket::render(Painter& painter,
- const StyleLayer& layer,
+ const Layer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
painter.renderFill(*this, *layer.as<FillLayer>(), tileID, matrix);
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index f1b137893c..21e3239f29 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -21,7 +21,7 @@ public:
~FillBucket() override;
void upload(gl::ObjectStore&) override;
- void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override;
+ void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override;
bool hasData() const override;
bool needsClipping() const override;
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index c308f02588..8124a5daed 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -444,7 +444,7 @@ void LineBucket::upload(gl::ObjectStore& store) {
}
void LineBucket::render(Painter& painter,
- const StyleLayer& layer,
+ const Layer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
painter.renderLine(*this, *layer.as<LineLayer>(), tileID, matrix);
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 8b60be5f00..1093ec2a48 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -5,7 +5,7 @@
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
-#include <mbgl/layer/line_layer.hpp>
+#include <mbgl/layer/line_layer_impl.hpp>
#include <vector>
@@ -26,7 +26,7 @@ public:
~LineBucket() override;
void upload(gl::ObjectStore&) override;
- void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override;
+ void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override;
bool hasData() const override;
bool needsClipping() const override;
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 486865dc78..ccc6e23408 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -7,11 +7,12 @@
#include <mbgl/gl/debugging.hpp>
#include <mbgl/style/style.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
#include <mbgl/style/style_render_parameters.hpp>
#include <mbgl/layer/background_layer.hpp>
#include <mbgl/layer/custom_layer.hpp>
+#include <mbgl/layer/custom_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
@@ -239,9 +240,9 @@ void Painter::renderPass(RenderPass pass_,
currentLayer = i;
const auto& item = *it;
- const StyleLayer& layer = item.layer;
+ const Layer& layer = item.layer;
- if (!layer.hasRenderPass(pass))
+ if (!layer.baseImpl->hasRenderPass(pass))
continue;
if (pass == RenderPass::Translucent) {
@@ -258,12 +259,12 @@ void Painter::renderPass(RenderPass pass_,
MBGL_DEBUG_GROUP("background");
renderBackground(*layer.as<BackgroundLayer>());
} else if (layer.is<CustomLayer>()) {
- MBGL_DEBUG_GROUP(layer.id + " - custom");
+ MBGL_DEBUG_GROUP(layer.baseImpl->id + " - custom");
VertexArrayObject::Unbind();
- layer.as<CustomLayer>()->render(state);
+ layer.as<CustomLayer>()->impl->render(state);
config.setDirty();
} else {
- MBGL_DEBUG_GROUP(layer.id + " - " + util::toString(item.tile->id));
+ MBGL_DEBUG_GROUP(layer.baseImpl->id + " - " + util::toString(item.tile->id));
if (item.bucket->needsClipping()) {
setClipping(item.tile->clip);
}
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 70d5312b38..ad26457555 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -29,7 +29,6 @@
namespace mbgl {
class Style;
-class StyleLayer;
class Tile;
class SpriteAtlas;
class GlyphAtlas;
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 3f01b74403..bc01d3c32f 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -1,6 +1,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/layer/background_layer.hpp>
+#include <mbgl/layer/background_layer_impl.hpp>
#include <mbgl/shader/pattern_shader.hpp>
#include <mbgl/shader/plain_shader.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
@@ -12,7 +13,7 @@ using namespace mbgl;
void Painter::renderBackground(const BackgroundLayer& layer) {
// Note that for bottommost layers without a pattern, the background color is drawn with
// glClear rather than this method.
- const BackgroundPaintProperties& properties = layer.paint;
+ const BackgroundPaintProperties& properties = layer.impl->paint;
bool isPatterned = !properties.backgroundPattern.value.to.empty();// && false;
optional<SpriteAtlasPosition> imagePosA;
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index fe4348c362..c371f4debe 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -2,6 +2,7 @@
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/layer/circle_layer.hpp>
+#include <mbgl/layer/circle_layer_impl.hpp>
#include <mbgl/shader/circle_shader.hpp>
@@ -20,7 +21,7 @@ void Painter::renderCircle(CircleBucket& bucket,
config.depthMask = GL_FALSE;
setDepthSublayer(0);
- const CirclePaintProperties& properties = layer.paint;
+ const CirclePaintProperties& properties = layer.impl->paint;
mat4 vtxMatrix = translatedMatrix(matrix, properties.circleTranslate, tileID,
properties.circleTranslateAnchor);
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 51cfa1b068..b499d20da3 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -1,6 +1,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/layer/fill_layer.hpp>
+#include <mbgl/layer/fill_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/shader/outline_shader.hpp>
#include <mbgl/shader/outlinepattern_shader.hpp>
@@ -13,7 +14,7 @@ void Painter::renderFill(FillBucket& bucket,
const FillLayer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
- const FillPaintProperties& properties = layer.paint;
+ const FillPaintProperties& properties = layer.impl->paint;
mat4 vtxMatrix =
translatedMatrix(matrix, properties.fillTranslate, tileID, properties.fillTranslateAnchor);
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index d9e3d4037b..3cf1ad4147 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -1,6 +1,7 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/layer/line_layer.hpp>
+#include <mbgl/layer/line_layer_impl.hpp>
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/linesdf_shader.hpp>
#include <mbgl/shader/linepattern_shader.hpp>
@@ -23,7 +24,7 @@ void Painter::renderLine(LineBucket& bucket,
config.depthTest = GL_TRUE;
config.depthMask = GL_FALSE;
- const auto& properties = layer.paint;
+ const auto& properties = layer.impl->paint;
const auto& layout = bucket.layout;
// the distance over which the line edge fades out.
@@ -75,8 +76,8 @@ void Painter::renderLine(LineBucket& bucket,
LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, layout.lineCap == LineCapType::Round, store);
LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, layout.lineCap == LineCapType::Round, store);
- const float widthA = posA.width * properties.lineDasharray.value.fromScale * layer.dashLineWidth;
- const float widthB = posB.width * properties.lineDasharray.value.toScale * layer.dashLineWidth;
+ const float widthA = posA.width * properties.lineDasharray.value.fromScale * layer.impl->dashLineWidth;
+ const float widthB = posB.width * properties.lineDasharray.value.toScale * layer.impl->dashLineWidth;
float scaleXA = 1.0 / tileID.pixelsToTileUnits(widthA, state.getIntegerZoom());
float scaleYA = -posA.height / 2.0;
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 7f55e23ac2..511ac96387 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -2,6 +2,7 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
#include <mbgl/layer/raster_layer.hpp>
+#include <mbgl/layer/raster_layer_impl.hpp>
#include <mbgl/shader/raster_shader.hpp>
using namespace mbgl;
@@ -12,7 +13,7 @@ void Painter::renderRaster(RasterBucket& bucket,
const mat4& matrix) {
if (pass != RenderPass::Translucent) return;
- const RasterPaintProperties& properties = layer.paint;
+ const RasterPaintProperties& properties = layer.impl->paint;
if (bucket.hasData()) {
config.program = rasterShader->getID();
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 55d2e27c11..9774568074 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -110,7 +110,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
return;
}
- const auto& paint = layer.paint;
+ const auto& paint = layer.impl->paint;
const auto& layout = bucket.layout;
config.depthMask = GL_FALSE;
@@ -146,10 +146,10 @@ void Painter::renderSymbol(SymbolBucket& bucket,
? state.getAngle()
: 0;
- const float fontSize = layer.iconSize;
+ const float fontSize = layer.impl->iconSize;
const float fontScale = fontSize / 1.0f;
- SpriteAtlas* activeSpriteAtlas = layer.spriteAtlas;
+ SpriteAtlas* activeSpriteAtlas = layer.impl->spriteAtlas;
const bool iconScaled = fontScale != 1 || frame.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear;
const bool iconTransformed = layout.iconRotationAlignment == RotationAlignmentType::Map || angleOffset != 0 || state.getPitch() != 0;
config.activeTexture = GL_TEXTURE0;
@@ -172,7 +172,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
paint.iconHaloBlur,
paint.iconTranslate,
paint.iconTranslateAnchor,
- layer.iconSize);
+ layer.impl->iconSize);
} else {
mat4 vtxMatrix =
translatedMatrix(matrix, paint.iconTranslate, tileID, paint.iconTranslateAnchor);
@@ -235,7 +235,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
paint.textHaloBlur,
paint.textTranslate,
paint.textTranslateAnchor,
- layer.textSize);
+ layer.impl->textSize);
}
if (bucket.hasCollisionBoxData()) {
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index d6786969c9..b16d7f8161 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -17,7 +17,7 @@ void RasterBucket::upload(gl::ObjectStore& store) {
}
void RasterBucket::render(Painter& painter,
- const StyleLayer& layer,
+ const Layer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
painter.renderRaster(*this, *layer.as<RasterLayer>(), tileID, matrix);
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index 33956fedcd..9125ef2047 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -14,7 +14,7 @@ public:
RasterBucket(gl::TexturePool&);
void upload(gl::ObjectStore&) override;
- void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override;
+ void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override;
bool hasData() const override;
bool needsClipping() const override;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 2f5af330a4..67c8468ecd 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -85,7 +85,7 @@ void SymbolBucket::upload(gl::ObjectStore& store) {
}
void SymbolBucket::render(Painter& painter,
- const StyleLayer& layer,
+ const Layer& layer,
const UnwrappedTileID& tileID,
const mat4& matrix) {
painter.renderSymbol(*this, *layer.as<SymbolLayer>(), tileID, matrix);
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 268bcb7c77..b19a86b275 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -13,7 +13,7 @@
#include <mbgl/text/shaping.hpp>
#include <mbgl/text/quads.hpp>
#include <mbgl/style/filter.hpp>
-#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
#include <memory>
#include <map>
@@ -70,7 +70,7 @@ public:
~SymbolBucket() override;
void upload(gl::ObjectStore&) override;
- void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override;
+ void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override;
bool hasData() const override;
bool hasTextData() const;
bool hasIconData() const;
diff --git a/src/mbgl/source/source.cpp b/src/mbgl/source/source.cpp
index 1c55b9c024..66546909ac 100644
--- a/src/mbgl/source/source.cpp
+++ b/src/mbgl/source/source.cpp
@@ -11,7 +11,7 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/storage/file_source.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/style/layer.hpp>
#include <mbgl/style/style_update_parameters.hpp>
#include <mbgl/style/style_query_parameters.hpp>
#include <mbgl/platform/log.hpp>
diff --git a/src/mbgl/style/function.hpp b/src/mbgl/style/function.hpp
deleted file mode 100644
index a04fc8bb4f..0000000000
--- a/src/mbgl/style/function.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <utility>
-
-namespace mbgl {
-
-template <typename T>
-class Function {
-public:
- using Stop = std::pair<float, T>;
- using Stops = std::vector<Stop>;
-
- explicit Function(const T& constant)
- : stops({{ 0, constant }}) {}
-
- explicit Function(const Stops& stops_, float base_)
- : base(base_), stops(stops_) {}
-
- float getBase() const { return base; }
- const std::vector<std::pair<float, T>>& getStops() const { return stops; }
-
-private:
- float base = 1;
- std::vector<std::pair<float, T>> stops;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/style/function_evaluator.hpp b/src/mbgl/style/function_evaluator.hpp
index 43549179df..de49e79f98 100644
--- a/src/mbgl/style/function_evaluator.hpp
+++ b/src/mbgl/style/function_evaluator.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/style/function.hpp>
+#include <mbgl/style/types.hpp>
#include <mbgl/util/interpolate.hpp>
namespace mbgl {
diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp
index 1df780be52..a856e7589c 100644
--- a/src/mbgl/style/layout_property.hpp
+++ b/src/mbgl/style/layout_property.hpp
@@ -1,7 +1,6 @@
#pragma once
#include <mbgl/style/property_parsing.hpp>
-#include <mbgl/style/function.hpp>
#include <mbgl/style/function_evaluator.hpp>
#include <mbgl/util/rapidjson.hpp>
@@ -27,7 +26,6 @@ public:
}
}
- void operator=(const T& v) { value = v; }
operator T() const { return value; }
optional<Function<T>> parsedValue;
diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp
index 256f045d0d..4bbc564398 100644
--- a/src/mbgl/style/paint_property.hpp
+++ b/src/mbgl/style/paint_property.hpp
@@ -2,7 +2,6 @@
#include <mbgl/style/class_dictionary.hpp>
#include <mbgl/style/property_parsing.hpp>
-#include <mbgl/style/function.hpp>
#include <mbgl/style/function_evaluator.hpp>
#include <mbgl/style/property_transition.hpp>
#include <mbgl/style/style_cascade_parameters.hpp>
@@ -97,7 +96,6 @@ public:
return cascaded->prior.operator bool();
}
- void operator=(const T& v) { values.emplace(ClassID::Default, Fn(v)); }
operator T() const { return value; }
std::map<ClassID, Fn> values;
diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp
index 362b0d7b5a..67baa3ec8d 100644
--- a/src/mbgl/style/property_parsing.cpp
+++ b/src/mbgl/style/property_parsing.cpp
@@ -1,4 +1,7 @@
#include <mbgl/style/property_parsing.hpp>
+#include <mbgl/style/property_transition.hpp>
+
+#include <mbgl/platform/log.hpp>
#include <csscolorparser/csscolorparser.hpp>
diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp
index 8deb58c00b..17c9bf6ba8 100644
--- a/src/mbgl/style/property_parsing.hpp
+++ b/src/mbgl/style/property_parsing.hpp
@@ -1,7 +1,6 @@
#pragma once
#include <mbgl/style/types.hpp>
-#include <mbgl/style/function.hpp>
#include <mbgl/style/property_transition.hpp>
#include <mbgl/util/rapidjson.hpp>
diff --git a/src/mbgl/style/render_item.hpp b/src/mbgl/style/render_item.hpp
index a70c92f620..ebf6799828 100644
--- a/src/mbgl/style/render_item.hpp
+++ b/src/mbgl/style/render_item.hpp
@@ -2,12 +2,12 @@
namespace mbgl {
-class StyleLayer;
+class Layer;
class Tile;
class Bucket;
struct RenderItem {
- inline RenderItem(const StyleLayer& layer_,
+ inline RenderItem(const Layer& layer_,
const Tile* tile_ = nullptr,
Bucket* bucket_ = nullptr)
: tile(tile_), bucket(bucket_), layer(layer_) {
@@ -15,7 +15,7 @@ struct RenderItem {
const Tile* const tile;
Bucket* const bucket;
- const StyleLayer& layer;
+ const Layer& layer;
};
} // namespace mbgl
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index bc2a1d9a40..ee847ccf57 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -4,10 +4,14 @@
#include <mbgl/tile/tile.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
#include <mbgl/layer/custom_layer.hpp>
+#include <mbgl/layer/custom_layer_impl.hpp>
+#include <mbgl/layer/background_layer.hpp>
+#include <mbgl/layer/background_layer_impl.hpp>
#include <mbgl/sprite/sprite_store.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
#include <mbgl/style/style_parser.hpp>
#include <mbgl/style/property_transition.hpp>
#include <mbgl/style/class_dictionary.hpp>
@@ -19,7 +23,6 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/platform/log.hpp>
-#include <mbgl/layer/background_layer.hpp>
#include <mbgl/math/minmax.hpp>
#include <csscolorparser/csscolorparser.hpp>
@@ -109,35 +112,35 @@ void Style::addSource(std::unique_ptr<Source> source) {
sources.emplace_back(std::move(source));
}
-std::vector<std::unique_ptr<StyleLayer>> Style::getLayers() const {
- std::vector<std::unique_ptr<StyleLayer>> result;
+std::vector<std::unique_ptr<Layer>> Style::getLayers() const {
+ std::vector<std::unique_ptr<Layer>> result;
result.reserve(layers.size());
for (const auto& layer : layers) {
- result.push_back(layer->clone());
+ result.push_back(layer->baseImpl->clone());
}
return result;
}
-std::vector<std::unique_ptr<StyleLayer>>::const_iterator Style::findLayer(const std::string& id) const {
+std::vector<std::unique_ptr<Layer>>::const_iterator Style::findLayer(const std::string& id) const {
return std::find_if(layers.begin(), layers.end(), [&](const auto& layer) {
- return layer->id == id;
+ return layer->baseImpl->id == id;
});
}
-StyleLayer* Style::getLayer(const std::string& id) const {
+Layer* Style::getLayer(const std::string& id) const {
auto it = findLayer(id);
return it != layers.end() ? it->get() : nullptr;
}
-void Style::addLayer(std::unique_ptr<StyleLayer> layer, optional<std::string> before) {
+void Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
if (SymbolLayer* symbolLayer = layer->as<SymbolLayer>()) {
- if (!symbolLayer->spriteAtlas) {
- symbolLayer->spriteAtlas = spriteAtlas.get();
+ if (!symbolLayer->impl->spriteAtlas) {
+ symbolLayer->impl->spriteAtlas = spriteAtlas.get();
}
}
if (CustomLayer* customLayer = layer->as<CustomLayer>()) {
- customLayer->initialize();
+ customLayer->impl->initialize();
}
layers.emplace(before ? findLayer(*before) : layers.end(), std::move(layer));
@@ -187,7 +190,7 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) {
transitionProperties = {};
for (const auto& layer : layers) {
- layer->cascade(parameters);
+ layer->baseImpl->cascade(parameters);
}
}
@@ -207,10 +210,10 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
hasPendingTransitions = false;
for (const auto& layer : layers) {
- hasPendingTransitions |= layer->recalculate(parameters);
+ hasPendingTransitions |= layer->baseImpl->recalculate(parameters);
- Source* source = getSource(layer->source);
- if (source && layer->needsRendering()) {
+ Source* source = getSource(layer->baseImpl->source);
+ if (source && layer->baseImpl->needsRendering()) {
source->enabled = true;
if (!source->loaded && !source->isLoading()) {
source->load(fileSource);
@@ -257,17 +260,18 @@ RenderData Style::getRenderData() const {
}
for (const auto& layer : layers) {
- if (layer->visibility == VisibilityType::None)
+ if (layer->baseImpl->visibility == VisibilityType::None)
continue;
if (const BackgroundLayer* background = layer->as<BackgroundLayer>()) {
- if (layer.get() == layers[0].get() && background->paint.backgroundPattern.value.from.empty()) {
+ const BackgroundPaintProperties& paint = background->impl->paint;
+ if (layer.get() == layers[0].get() && paint.backgroundPattern.value.from.empty()) {
// This is a solid background. We can use glClear().
- result.backgroundColor = background->paint.backgroundColor;
- result.backgroundColor[0] *= background->paint.backgroundOpacity;
- result.backgroundColor[1] *= background->paint.backgroundOpacity;
- result.backgroundColor[2] *= background->paint.backgroundOpacity;
- result.backgroundColor[3] *= background->paint.backgroundOpacity;
+ result.backgroundColor = paint.backgroundColor;
+ result.backgroundColor[0] *= paint.backgroundOpacity;
+ result.backgroundColor[1] *= paint.backgroundOpacity;
+ result.backgroundColor[2] *= paint.backgroundOpacity;
+ result.backgroundColor[3] *= paint.backgroundOpacity;
} else {
// This is a textured background, or not the bottommost layer. We need to render it with a quad.
result.order.emplace_back(*layer);
@@ -280,9 +284,9 @@ RenderData Style::getRenderData() const {
continue;
}
- Source* source = getSource(layer->source);
+ Source* source = getSource(layer->baseImpl->source);
if (!source) {
- Log::Warning(Event::Render, "can't find source for layer '%s'", layer->id.c_str());
+ Log::Warning(Event::Render, "can't find source for layer '%s'", layer->baseImpl->id.c_str());
continue;
}
@@ -333,7 +337,7 @@ std::vector<Feature> Style::queryRenderedFeatures(const StyleQueryParameters& pa
// Combine all results based on the style layer order.
for (const auto& layer : layers) {
- auto it = resultsByLayer.find(layer->id);
+ auto it = resultsByLayer.find(layer->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
}
@@ -345,7 +349,7 @@ std::vector<Feature> Style::queryRenderedFeatures(const StyleQueryParameters& pa
float Style::getQueryRadius() const {
float additionalRadius = 0;
for (auto& layer : layers) {
- additionalRadius = util::max(additionalRadius, layer->getQueryRadius());
+ additionalRadius = util::max(additionalRadius, layer->baseImpl->getQueryRadius());
}
return additionalRadius;
}
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 5fdd6cdc8e..6892f4967a 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -69,9 +69,9 @@ public:
Source* getSource(const std::string& id) const;
void addSource(std::unique_ptr<Source>);
- std::vector<std::unique_ptr<StyleLayer>> getLayers() const;
- StyleLayer* getLayer(const std::string& id) const;
- void addLayer(std::unique_ptr<StyleLayer>,
+ std::vector<std::unique_ptr<Layer>> getLayers() const;
+ Layer* getLayer(const std::string& id) const;
+ void addLayer(std::unique_ptr<Layer>,
optional<std::string> beforeLayerID = {});
void removeLayer(const std::string& layerID);
@@ -101,11 +101,11 @@ public:
private:
std::vector<std::unique_ptr<Source>> sources;
- std::vector<std::unique_ptr<StyleLayer>> layers;
+ std::vector<std::unique_ptr<Layer>> layers;
std::vector<std::string> classes;
optional<PropertyTransition> transitionProperties;
- std::vector<std::unique_ptr<StyleLayer>>::const_iterator findLayer(const std::string& layerID) const;
+ std::vector<std::unique_ptr<Layer>>::const_iterator findLayer(const std::string& layerID) const;
// GlyphStoreObserver implementation.
void onGlyphsLoaded(const FontStack&, const GlyphRange&) override;
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 4f081e7d85..6a67ea9daa 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -5,6 +5,8 @@
#include <mbgl/layer/symbol_layer.hpp>
#include <mbgl/layer/raster_layer.hpp>
#include <mbgl/layer/background_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
#include <mbgl/platform/log.hpp>
@@ -331,7 +333,7 @@ void StyleParser::parseLayers(const JSValue& value) {
continue;
}
- layersMap.emplace(layerID, std::pair<const JSValue&, std::unique_ptr<StyleLayer>> { layerValue, nullptr });
+ layersMap.emplace(layerID, std::pair<const JSValue&, std::unique_ptr<Layer>> { layerValue, nullptr });
ids.push_back(layerID);
}
@@ -352,7 +354,7 @@ void StyleParser::parseLayers(const JSValue& value) {
}
}
-void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::unique_ptr<StyleLayer>& layer) {
+void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::unique_ptr<Layer>& layer) {
if (layer) {
// Skip parsing this again. We already have a valid layer definition.
return;
@@ -386,15 +388,13 @@ void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::u
it->second.second);
stack.pop_front();
- StyleLayer* reference = it->second.second.get();
+ Layer* reference = it->second.second.get();
if (!reference) {
return;
}
- layer = reference->clone();
- layer->id = id;
- layer->ref = ref;
-
+ layer = reference->copy(id, ref);
+ layer->baseImpl->parsePaints(value);
} else {
// Otherwise, parse the source/source-layer/filter/render keys to form the bucket.
if (!value.HasMember("type")) {
@@ -411,75 +411,75 @@ void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::u
std::string type { typeVal.GetString(), typeVal.GetStringLength() };
if (type == "fill") {
- layer = std::make_unique<FillLayer>();
+ layer = std::make_unique<FillLayer>(id);
} else if (type == "line") {
- layer = std::make_unique<LineLayer>();
+ layer = std::make_unique<LineLayer>(id);
} else if (type == "circle") {
- layer = std::make_unique<CircleLayer>();
+ layer = std::make_unique<CircleLayer>(id);
} else if (type == "symbol") {
- layer = std::make_unique<SymbolLayer>();
+ layer = std::make_unique<SymbolLayer>(id);
} else if (type == "raster") {
- layer = std::make_unique<RasterLayer>();
+ layer = std::make_unique<RasterLayer>(id);
} else if (type == "background") {
- layer = std::make_unique<BackgroundLayer>();
+ layer = std::make_unique<BackgroundLayer>(id);
} else {
Log::Warning(Event::ParseStyle, "unknown type '%s' for layer '%s'", type.c_str(), id.c_str());
return;
}
- layer->id = id;
+ Layer::Impl* impl = layer->baseImpl.get();
if (value.HasMember("source")) {
const JSValue& value_source = value["source"];
if (value_source.IsString()) {
- layer->source = { value_source.GetString(), value_source.GetStringLength() };
- auto source_it = sourcesMap.find(layer->source);
+ impl->source = { value_source.GetString(), value_source.GetStringLength() };
+ auto source_it = sourcesMap.find(impl->source);
if (source_it == sourcesMap.end()) {
- Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", layer->source.c_str(), layer->id.c_str());
+ Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", impl->source.c_str(), impl->id.c_str());
}
} else {
- Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", layer->id.c_str());
+ Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", impl->id.c_str());
}
}
if (value.HasMember("source-layer")) {
const JSValue& value_source_layer = value["source-layer"];
if (value_source_layer.IsString()) {
- layer->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
+ impl->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
} else {
- Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", layer->id.c_str());
+ Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", impl->id.c_str());
}
}
if (value.HasMember("filter")) {
- layer->filter = parseFilter(value["filter"]);
+ impl->filter = parseFilter(value["filter"]);
}
if (value.HasMember("minzoom")) {
const JSValue& min_zoom = value["minzoom"];
if (min_zoom.IsNumber()) {
- layer->minZoom = min_zoom.GetDouble();
+ impl->minZoom = min_zoom.GetDouble();
} else {
- Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", layer->id.c_str());
+ Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", impl->id.c_str());
}
}
if (value.HasMember("maxzoom")) {
const JSValue& max_zoom = value["maxzoom"];
if (max_zoom.IsNumber()) {
- layer->maxZoom = max_zoom.GetDouble();
+ impl->maxZoom = max_zoom.GetDouble();
} else {
- Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", layer->id.c_str());
+ Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", impl->id.c_str());
}
}
if (value.HasMember("layout")) {
parseVisibility(*layer, value["layout"]);
- layer->parseLayout(value["layout"]);
+ impl->parseLayout(value["layout"]);
}
- }
- layer->parsePaints(value);
+ impl->parsePaints(value);
+ }
}
MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, {
@@ -487,15 +487,16 @@ MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, {
{ VisibilityType::None, "none" },
});
-void StyleParser::parseVisibility(StyleLayer& layer, const JSValue& value) {
+void StyleParser::parseVisibility(Layer& layer, const JSValue& value) {
+ Layer::Impl& impl = *layer.baseImpl;
if (!value.HasMember("visibility")) {
return;
} else if (!value["visibility"].IsString()) {
Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string");
- layer.visibility = VisibilityType::Visible;
+ impl.visibility = VisibilityType::Visible;
return;
}
- layer.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
+ impl.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
}
Value parseFeatureType(const Value& value) {
@@ -669,7 +670,7 @@ std::vector<FontStack> StyleParser::fontStacks() const {
for (const auto& layer : layers) {
if (layer->is<SymbolLayer>()) {
- LayoutProperty<FontStack> property = layer->as<SymbolLayer>()->layout.textFont;
+ LayoutProperty<FontStack> property = layer->as<SymbolLayer>()->impl->layout.textFont;
if (property.parsedValue) {
for (const auto& stop : property.parsedValue->getStops()) {
result.insert(stop.second);
diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp
index 98481aec51..b5445bbfb3 100644
--- a/src/mbgl/style/style_parser.hpp
+++ b/src/mbgl/style/style_parser.hpp
@@ -1,7 +1,7 @@
#pragma once
#include <mbgl/style/types.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/style/layer.hpp>
#include <mbgl/source/source.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/util/rapidjson.hpp>
@@ -14,9 +14,6 @@
namespace mbgl {
-class StyleLayer;
-class Source;
-
Filter parseFilter(const JSValue&);
class StyleParser {
@@ -29,7 +26,7 @@ public:
std::string glyphURL;
std::vector<std::unique_ptr<Source>> sources;
- std::vector<std::unique_ptr<StyleLayer>> layers;
+ std::vector<std::unique_ptr<Layer>> layers;
// Statically evaluate layer properties to determine what font stacks are used.
std::vector<FontStack> fontStacks() const;
@@ -42,11 +39,11 @@ public:
private:
void parseSources(const JSValue&);
void parseLayers(const JSValue&);
- void parseLayer(const std::string& id, const JSValue&, std::unique_ptr<StyleLayer>&);
- void parseVisibility(StyleLayer&, const JSValue& value);
+ void parseLayer(const std::string& id, const JSValue&, std::unique_ptr<Layer>&);
+ void parseVisibility(Layer&, const JSValue& value);
std::unordered_map<std::string, const Source*> sourcesMap;
- std::unordered_map<std::string, std::pair<const JSValue&, std::unique_ptr<StyleLayer>>> layersMap;
+ std::unordered_map<std::string, std::pair<const JSValue&, std::unique_ptr<Layer>>> layersMap;
// Store a stack of layer IDs we're parsing right now. This is to prevent reference cycles.
std::forward_list<std::string> stack;
diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp
index f78d913e74..3cb508a102 100644
--- a/src/mbgl/text/quads.cpp
+++ b/src/mbgl/text/quads.cpp
@@ -2,7 +2,7 @@
#include <mbgl/text/shaping.hpp>
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/geometry/anchor.hpp>
-#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_properties.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/constants.hpp>
#include <cassert>
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 9ad3c3e71d..ce93b4977e 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -1,5 +1,5 @@
#include <mbgl/text/shaping.hpp>
-#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_properties.hpp>
namespace mbgl {
diff --git a/src/mbgl/tile/raster_tile_data.cpp b/src/mbgl/tile/raster_tile_data.cpp
index 29b7ca6af8..a5eab3fb23 100644
--- a/src/mbgl/tile/raster_tile_data.cpp
+++ b/src/mbgl/tile/raster_tile_data.cpp
@@ -61,7 +61,7 @@ RasterTileData::~RasterTileData() {
cancel();
}
-Bucket* RasterTileData::getBucket(StyleLayer const&) {
+Bucket* RasterTileData::getBucket(const Layer&) {
return bucket.get();
}
diff --git a/src/mbgl/tile/raster_tile_data.hpp b/src/mbgl/tile/raster_tile_data.hpp
index 74e0cc400d..ea9b144e25 100644
--- a/src/mbgl/tile/raster_tile_data.hpp
+++ b/src/mbgl/tile/raster_tile_data.hpp
@@ -7,7 +7,7 @@ namespace mbgl {
class FileSource;
class AsyncRequest;
-class StyleLayer;
+class Layer;
namespace gl { class TexturePool; }
class RasterTileData : public TileData {
@@ -22,7 +22,7 @@ public:
~RasterTileData();
void cancel() override;
- Bucket* getBucket(StyleLayer const &layer_desc) override;
+ Bucket* getBucket(const Layer&) override;
private:
gl::TexturePool& texturePool;
diff --git a/src/mbgl/tile/tile_data.hpp b/src/mbgl/tile/tile_data.hpp
index 297bfabcae..035a7ed319 100644
--- a/src/mbgl/tile/tile_data.hpp
+++ b/src/mbgl/tile/tile_data.hpp
@@ -16,7 +16,7 @@
namespace mbgl {
-class StyleLayer;
+class Layer;
class Worker;
class DebugBucket;
class TransformState;
@@ -29,7 +29,7 @@ public:
// Mark this tile as no longer needed and cancel any pending work.
virtual void cancel() = 0;
- virtual Bucket* getBucket(const StyleLayer&) = 0;
+ virtual Bucket* getBucket(const Layer&) = 0;
virtual bool parsePending(std::function<void (std::exception_ptr)>) { return true; }
virtual void redoPlacement(PlacementConfig, const std::function<void()>&) {}
diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp
index fdebe91229..9076684a2d 100644
--- a/src/mbgl/tile/tile_worker.cpp
+++ b/src/mbgl/tile/tile_worker.cpp
@@ -1,11 +1,11 @@
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/tile/tile_worker.hpp>
#include <mbgl/tile/geometry_tile.hpp>
-#include <mbgl/style/style_layer.hpp>
#include <mbgl/style/style_bucket_parameters.hpp>
#include <mbgl/layer/background_layer.hpp>
#include <mbgl/layer/custom_layer.hpp>
#include <mbgl/layer/symbol_layer.hpp>
+#include <mbgl/layer/symbol_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/glyph_atlas.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
@@ -37,7 +37,7 @@ TileWorker::~TileWorker() {
glyphAtlas.removeGlyphs(reinterpret_cast<uintptr_t>(this));
}
-TileParseResult TileWorker::parseAllLayers(std::vector<std::unique_ptr<StyleLayer>> layers_,
+TileParseResult TileWorker::parseAllLayers(std::vector<std::unique_ptr<Layer>> layers_,
std::unique_ptr<const GeometryTile> geometryTile_,
PlacementConfig config) {
// We're doing a fresh parse of the tile, because the underlying data has changed.
@@ -55,12 +55,12 @@ TileParseResult TileWorker::parseAllLayers(std::vector<std::unique_ptr<StyleLaye
std::set<std::string> parsed;
for (auto i = layers.rbegin(); i != layers.rend(); i++) {
- const StyleLayer* layer = i->get();
- if (parsed.find(layer->bucketName()) == parsed.end()) {
- parsed.emplace(layer->bucketName());
+ const Layer* layer = i->get();
+ if (parsed.find(layer->baseImpl->bucketName()) == parsed.end()) {
+ parsed.emplace(layer->baseImpl->bucketName());
parseLayer(layer);
}
- featureIndex->addBucketLayerName(layer->bucketName(), layer->id);
+ featureIndex->addBucketLayerName(layer->baseImpl->bucketName(), layer->baseImpl->id);
}
return prepareResult(config);
@@ -70,16 +70,15 @@ TileParseResult TileWorker::parsePendingLayers(const PlacementConfig config) {
// Try parsing the remaining layers that we couldn't parse in the first step due to missing
// dependencies.
for (auto it = pending.begin(); it != pending.end();) {
- auto& layer = *it->first;
- auto bucket = dynamic_cast<SymbolBucket*>(it->second.get());
- assert(bucket); // Only symbol layers can be pending, so the dynamic cast should never fail.
-
- if (!bucket->needsDependencies(glyphStore, spriteStore)) {
- bucket->addFeatures(reinterpret_cast<uintptr_t>(this),
- *layer.spriteAtlas,
- glyphAtlas,
- glyphStore);
- placementPending.emplace(layer.bucketName(), std::move(it->second));
+ const SymbolLayer& symbolLayer = *it->first;
+ SymbolBucket* symbolBucket = dynamic_cast<SymbolBucket*>(it->second.get());
+
+ if (!symbolBucket->needsDependencies(glyphStore, spriteStore)) {
+ symbolBucket->addFeatures(reinterpret_cast<uintptr_t>(this),
+ *symbolLayer.impl->spriteAtlas,
+ glyphAtlas,
+ glyphStore);
+ placementPending.emplace(symbolLayer.impl->bucketName(), std::move(it->second));
pending.erase(it++);
continue;
}
@@ -120,7 +119,7 @@ std::unique_ptr<CollisionTile> TileWorker::redoPlacement(
auto collisionTile = std::make_unique<CollisionTile>(config);
for (auto i = layers.rbegin(); i != layers.rend(); i++) {
- const auto it = buckets->find((*i)->id);
+ const auto it = buckets->find((*i)->baseImpl->id);
if (it != buckets->end()) {
it->second->placeFeatures(*collisionTile);
}
@@ -129,7 +128,7 @@ std::unique_ptr<CollisionTile> TileWorker::redoPlacement(
return collisionTile;
}
-void TileWorker::parseLayer(const StyleLayer* layer) {
+void TileWorker::parseLayer(const Layer* layer) {
// Cancel early when parsing.
if (obsolete)
return;
@@ -139,19 +138,19 @@ void TileWorker::parseLayer(const StyleLayer* layer) {
return;
// Skip this bucket if we are to not render this
- if ((layer->source != sourceID) ||
- (id.overscaledZ < std::floor(layer->minZoom)) ||
- (id.overscaledZ >= std::ceil(layer->maxZoom)) ||
- (layer->visibility == VisibilityType::None)) {
+ if ((layer->baseImpl->source != sourceID) ||
+ (id.overscaledZ < std::floor(layer->baseImpl->minZoom)) ||
+ (id.overscaledZ >= std::ceil(layer->baseImpl->maxZoom)) ||
+ (layer->baseImpl->visibility == VisibilityType::None)) {
return;
}
- auto geometryLayer = geometryTile->getLayer(layer->sourceLayer);
+ auto geometryLayer = geometryTile->getLayer(layer->baseImpl->sourceLayer);
if (!geometryLayer) {
// The layer specified in the bucket does not exist. Do nothing.
if (debug::tileParseWarnings) {
Log::Warning(Event::ParseTile, "layer '%s' does not exist in tile %s",
- layer->sourceLayer.c_str(), util::toString(id).c_str());
+ layer->baseImpl->sourceLayer.c_str(), util::toString(id).c_str());
}
return;
}
@@ -167,17 +166,17 @@ void TileWorker::parseLayer(const StyleLayer* layer) {
*featureIndex,
mode);
- std::unique_ptr<Bucket> bucket = layer->createBucket(parameters);
+ std::unique_ptr<Bucket> bucket = layer->baseImpl->createBucket(parameters);
if (layer->is<SymbolLayer>()) {
if (partialParse) {
// We cannot parse this bucket yet. Instead, we're saving it for later.
pending.emplace_back(layer->as<SymbolLayer>(), std::move(bucket));
} else {
- placementPending.emplace(layer->bucketName(), std::move(bucket));
+ placementPending.emplace(layer->baseImpl->bucketName(), std::move(bucket));
}
} else {
- insertBucket(layer->bucketName(), std::move(bucket));
+ insertBucket(layer->baseImpl->bucketName(), std::move(bucket));
}
}
diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp
index 83bf6c7f43..a04ef6a78f 100644
--- a/src/mbgl/tile/tile_worker.hpp
+++ b/src/mbgl/tile/tile_worker.hpp
@@ -23,7 +23,7 @@ class SpriteStore;
class GlyphAtlas;
class GlyphStore;
class Bucket;
-class StyleLayer;
+class Layer;
class SymbolLayer;
// We're using this class to shuttle the resulting buckets from the worker thread to the MapContext
@@ -51,7 +51,7 @@ public:
const MapMode);
~TileWorker();
- TileParseResult parseAllLayers(std::vector<std::unique_ptr<StyleLayer>>,
+ TileParseResult parseAllLayers(std::vector<std::unique_ptr<Layer>>,
std::unique_ptr<const GeometryTile> geometryTile,
PlacementConfig);
@@ -62,7 +62,7 @@ public:
private:
TileParseResult prepareResult(const PlacementConfig& config);
- void parseLayer(const StyleLayer*);
+ void parseLayer(const Layer*);
void insertBucket(const std::string& name, std::unique_ptr<Bucket>);
std::unique_ptr<CollisionTile> placeLayers(PlacementConfig);
@@ -77,7 +77,7 @@ private:
bool partialParse = false;
- std::vector<std::unique_ptr<StyleLayer>> layers;
+ std::vector<std::unique_ptr<Layer>> layers;
std::unique_ptr<FeatureIndex> featureIndex;
std::unique_ptr<const GeometryTile> geometryTile;
diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 428c605f26..db0ec8029e 100644
--- a/src/mbgl/tile/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -1,6 +1,6 @@
#include <mbgl/tile/vector_tile_data.hpp>
#include <mbgl/tile/geometry_tile.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/layer_impl.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_request.hpp>
#include <mbgl/style/style.hpp>
@@ -139,8 +139,8 @@ bool VectorTileData::parsePending(std::function<void(std::exception_ptr)> callba
return true;
}
-Bucket* VectorTileData::getBucket(const StyleLayer& layer) {
- const auto it = buckets.find(layer.bucketName());
+Bucket* VectorTileData::getBucket(const Layer& layer) {
+ const auto it = buckets.find(layer.baseImpl->bucketName());
if (it == buckets.end()) {
return nullptr;
}
diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index 2545df801b..4695338e1e 100644
--- a/src/mbgl/tile/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -27,7 +27,7 @@ public:
~VectorTileData();
- Bucket* getBucket(const StyleLayer&) override;
+ Bucket* getBucket(const Layer&) override;
bool parsePending(std::function<void(std::exception_ptr)> callback) override;
diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp
index e116d3f6c6..43abe6792a 100644
--- a/src/mbgl/util/worker.cpp
+++ b/src/mbgl/util/worker.cpp
@@ -4,7 +4,7 @@
#include <mbgl/platform/platform.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
#include <mbgl/tile/geometry_tile.hpp>
-#include <mbgl/style/style_layer.hpp>
+#include <mbgl/style/layer.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <cassert>
@@ -30,7 +30,7 @@ public:
}
void parseGeometryTile(TileWorker* worker,
- std::vector<std::unique_ptr<StyleLayer>> layers,
+ std::vector<std::unique_ptr<Layer>> layers,
std::unique_ptr<GeometryTile> tile,
PlacementConfig config,
std::function<void(TileParseResult)> callback) {
@@ -79,7 +79,7 @@ Worker::parseRasterTile(std::unique_ptr<RasterBucket> bucket,
std::unique_ptr<AsyncRequest>
Worker::parseGeometryTile(TileWorker& worker,
- std::vector<std::unique_ptr<StyleLayer>> layers,
+ std::vector<std::unique_ptr<Layer>> layers,
std::unique_ptr<GeometryTile> tile,
PlacementConfig config,
std::function<void(TileParseResult)> callback) {
diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp
index e07b8b8b44..68625f42bf 100644
--- a/src/mbgl/util/worker.hpp
+++ b/src/mbgl/util/worker.hpp
@@ -40,7 +40,7 @@ public:
std::function<void(RasterTileParseResult)> callback);
Request parseGeometryTile(TileWorker&,
- std::vector<std::unique_ptr<StyleLayer>>,
+ std::vector<std::unique_ptr<Layer>>,
std::unique_ptr<GeometryTile>,
PlacementConfig,
std::function<void(TileParseResult)> callback);
diff --git a/test/style/functions.cpp b/test/style/functions.cpp
index 2389459dbc..586941ecf0 100644
--- a/test/style/functions.cpp
+++ b/test/style/functions.cpp
@@ -1,7 +1,6 @@
#include <iostream>
#include <mbgl/test/util.hpp>
-#include <mbgl/style/function.hpp>
#include <mbgl/style/function_evaluator.hpp>
#include <mbgl/style/style_calculation_parameters.hpp>
diff --git a/test/style/source.cpp b/test/style/source.cpp
index 5023a9efea..b9eb1bc434 100644
--- a/test/style/source.cpp
+++ b/test/style/source.cpp
@@ -274,9 +274,8 @@ TEST(Source, VectorTileCorrupt) {
};
// Need to have at least one layer that uses the source.
- auto layer = std::make_unique<LineLayer>();
- layer->source = "source";
- layer->sourceLayer = "water";
+ auto layer = std::make_unique<LineLayer>("id");
+ layer->setSource("source", "water");
test.style.addLayer(std::move(layer));
auto info = std::make_unique<SourceInfo>();
diff --git a/test/style/style_layer.cpp b/test/style/style_layer.cpp
index 3b1d3be337..3274fe3377 100644
--- a/test/style/style_layer.cpp
+++ b/test/style/style_layer.cpp
@@ -1,24 +1,18 @@
#include <mbgl/test/util.hpp>
-
-#include <mbgl/style/style_layer.hpp>
#include <mbgl/layer/background_layer.hpp>
+#include <mbgl/layer/background_layer_impl.hpp>
using namespace mbgl;
-TEST(StyleLayer, Create) {
- std::unique_ptr<StyleLayer> layer = std::make_unique<BackgroundLayer>();
- EXPECT_TRUE(reinterpret_cast<BackgroundLayer*>(layer.get()));
-}
-
-TEST(StyleLayer, Clone) {
- std::unique_ptr<StyleLayer> layer = std::make_unique<BackgroundLayer>();
- std::unique_ptr<StyleLayer> clone = layer->clone();
+TEST(Layer, Clone) {
+ std::unique_ptr<Layer> layer = std::make_unique<BackgroundLayer>("id");
+ std::unique_ptr<Layer> clone = layer->baseImpl->clone();
EXPECT_NE(layer.get(), clone.get());
- EXPECT_TRUE(reinterpret_cast<BackgroundLayer*>(layer.get()));
+ EXPECT_TRUE(reinterpret_cast<BackgroundLayer::Impl*>(clone->baseImpl.get()));
}
-TEST(StyleLayer, CloneCopiesBaseProperties) {
- std::unique_ptr<BackgroundLayer> layer = std::make_unique<BackgroundLayer>();
- layer->id = "test";
- EXPECT_EQ("test", layer->clone()->id);
+TEST(Layer, CloneCopiesBaseProperties) {
+ std::unique_ptr<BackgroundLayer> layer = std::make_unique<BackgroundLayer>("id");
+ layer->impl->id = "test";
+ EXPECT_EQ("test", layer->baseImpl->clone()->getID());
}