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