From c902f9098b331302aaa1baac77d1575db624a132 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 26 Apr 2016 16:39:56 -0700 Subject: [core] Rationalize naming for style-related code --- src/mbgl/annotation/annotation_manager.cpp | 10 +- src/mbgl/annotation/annotation_manager.hpp | 5 +- src/mbgl/annotation/fill_annotation_impl.cpp | 4 +- src/mbgl/annotation/fill_annotation_impl.hpp | 2 +- src/mbgl/annotation/line_annotation_impl.cpp | 4 +- src/mbgl/annotation/line_annotation_impl.hpp | 2 +- src/mbgl/annotation/shape_annotation_impl.cpp | 1 + src/mbgl/annotation/shape_annotation_impl.hpp | 7 +- .../annotation/style_sourced_annotation_impl.cpp | 6 +- .../annotation/style_sourced_annotation_impl.hpp | 2 +- src/mbgl/geometry/feature_index.cpp | 14 +- src/mbgl/geometry/feature_index.hpp | 11 +- src/mbgl/layer/background_layer.cpp | 55 -- src/mbgl/layer/background_layer_impl.cpp | 26 - src/mbgl/layer/background_layer_impl.hpp | 24 - src/mbgl/layer/background_layer_properties.cpp | 29 - src/mbgl/layer/background_layer_properties.hpp | 25 - src/mbgl/layer/circle_layer.cpp | 103 --- src/mbgl/layer/circle_layer_impl.cpp | 60 -- src/mbgl/layer/circle_layer_impl.hpp | 31 - src/mbgl/layer/circle_layer_properties.cpp | 38 -- src/mbgl/layer/circle_layer_properties.hpp | 28 - src/mbgl/layer/custom_layer.cpp | 22 - src/mbgl/layer/custom_layer_impl.cpp | 66 -- src/mbgl/layer/custom_layer_impl.hpp | 41 -- src/mbgl/layer/fill_layer.cpp | 111 ---- src/mbgl/layer/fill_layer_impl.cpp | 66 -- src/mbgl/layer/fill_layer_impl.hpp | 31 - src/mbgl/layer/fill_layer_properties.cpp | 41 -- src/mbgl/layer/fill_layer_properties.hpp | 29 - src/mbgl/layer/layer.cpp | 48 -- src/mbgl/layer/layer_impl.cpp | 17 - src/mbgl/layer/layer_impl.hpp | 88 --- src/mbgl/layer/line_layer.cpp | 163 ----- src/mbgl/layer/line_layer_impl.cpp | 114 ---- src/mbgl/layer/line_layer_impl.hpp | 38 -- src/mbgl/layer/line_layer_properties.cpp | 64 -- src/mbgl/layer/line_layer_properties.hpp | 43 -- src/mbgl/layer/raster_layer.cpp | 96 --- src/mbgl/layer/raster_layer_impl.cpp | 26 - src/mbgl/layer/raster_layer_impl.hpp | 24 - src/mbgl/layer/raster_layer_properties.cpp | 41 -- src/mbgl/layer/raster_layer_properties.hpp | 29 - src/mbgl/layer/symbol_layer.cpp | 384 ------------ src/mbgl/layer/symbol_layer_impl.cpp | 80 --- src/mbgl/layer/symbol_layer_impl.hpp | 35 -- src/mbgl/layer/symbol_layer_properties.cpp | 130 ---- src/mbgl/layer/symbol_layer_properties.hpp | 74 --- src/mbgl/map/map.cpp | 42 +- src/mbgl/map/zoom_history.hpp | 36 ++ src/mbgl/renderer/bucket.hpp | 7 +- src/mbgl/renderer/circle_bucket.cpp | 8 +- src/mbgl/renderer/circle_bucket.hpp | 2 +- src/mbgl/renderer/fill_bucket.cpp | 22 +- src/mbgl/renderer/fill_bucket.hpp | 2 +- src/mbgl/renderer/line_bucket.cpp | 8 +- src/mbgl/renderer/line_bucket.hpp | 7 +- src/mbgl/renderer/painter.cpp | 17 +- src/mbgl/renderer/painter.hpp | 45 +- src/mbgl/renderer/painter_background.cpp | 10 +- src/mbgl/renderer/painter_circle.cpp | 10 +- src/mbgl/renderer/painter_clipping.cpp | 2 +- src/mbgl/renderer/painter_fill.cpp | 10 +- src/mbgl/renderer/painter_line.cpp | 10 +- src/mbgl/renderer/painter_raster.cpp | 10 +- src/mbgl/renderer/painter_symbol.cpp | 9 +- src/mbgl/renderer/raster_bucket.cpp | 8 +- src/mbgl/renderer/raster_bucket.hpp | 2 +- src/mbgl/renderer/symbol_bucket.cpp | 4 +- src/mbgl/renderer/symbol_bucket.hpp | 10 +- src/mbgl/source/source.cpp | 426 ------------- src/mbgl/source/source.hpp | 109 ---- src/mbgl/source/source_info.hpp | 27 - src/mbgl/source/source_observer.hpp | 21 - src/mbgl/style/bucket_parameters.cpp | 23 + src/mbgl/style/bucket_parameters.hpp | 65 ++ src/mbgl/style/calculation_parameters.hpp | 30 + src/mbgl/style/cascade_parameters.hpp | 22 + src/mbgl/style/class_dictionary.cpp | 2 + src/mbgl/style/class_dictionary.hpp | 2 + src/mbgl/style/filter_evaluator.hpp | 2 + src/mbgl/style/layer.cpp | 50 ++ src/mbgl/style/layer_impl.cpp | 19 + src/mbgl/style/layer_impl.hpp | 92 +++ src/mbgl/style/layers/background_layer.cpp | 57 ++ src/mbgl/style/layers/background_layer_impl.cpp | 28 + src/mbgl/style/layers/background_layer_impl.hpp | 26 + .../style/layers/background_layer_properties.cpp | 31 + .../style/layers/background_layer_properties.hpp | 27 + src/mbgl/style/layers/circle_layer.cpp | 105 ++++ src/mbgl/style/layers/circle_layer_impl.cpp | 62 ++ src/mbgl/style/layers/circle_layer_impl.hpp | 33 + src/mbgl/style/layers/circle_layer_properties.cpp | 40 ++ src/mbgl/style/layers/circle_layer_properties.hpp | 30 + src/mbgl/style/layers/custom_layer.cpp | 24 + src/mbgl/style/layers/custom_layer_impl.cpp | 68 ++ src/mbgl/style/layers/custom_layer_impl.hpp | 44 ++ src/mbgl/style/layers/fill_layer.cpp | 113 ++++ src/mbgl/style/layers/fill_layer_impl.cpp | 68 ++ src/mbgl/style/layers/fill_layer_impl.hpp | 33 + src/mbgl/style/layers/fill_layer_properties.cpp | 43 ++ src/mbgl/style/layers/fill_layer_properties.hpp | 31 + src/mbgl/style/layers/line_layer.cpp | 165 +++++ src/mbgl/style/layers/line_layer_impl.cpp | 116 ++++ src/mbgl/style/layers/line_layer_impl.hpp | 40 ++ src/mbgl/style/layers/line_layer_properties.cpp | 66 ++ src/mbgl/style/layers/line_layer_properties.hpp | 45 ++ src/mbgl/style/layers/raster_layer.cpp | 98 +++ src/mbgl/style/layers/raster_layer_impl.cpp | 28 + src/mbgl/style/layers/raster_layer_impl.hpp | 26 + src/mbgl/style/layers/raster_layer_properties.cpp | 43 ++ src/mbgl/style/layers/raster_layer_properties.hpp | 31 + src/mbgl/style/layers/symbol_layer.cpp | 386 ++++++++++++ src/mbgl/style/layers/symbol_layer_impl.cpp | 82 +++ src/mbgl/style/layers/symbol_layer_impl.hpp | 35 ++ src/mbgl/style/layers/symbol_layer_properties.cpp | 132 ++++ src/mbgl/style/layers/symbol_layer_properties.hpp | 76 +++ src/mbgl/style/layout_property.hpp | 4 +- src/mbgl/style/observer.hpp | 25 + src/mbgl/style/paint_property.hpp | 18 +- src/mbgl/style/parser.cpp | 689 +++++++++++++++++++++ src/mbgl/style/parser.hpp | 55 ++ src/mbgl/style/property_evaluator.cpp | 5 +- src/mbgl/style/property_evaluator.hpp | 15 +- src/mbgl/style/property_parsing.cpp | 7 +- src/mbgl/style/property_parsing.hpp | 7 +- src/mbgl/style/property_value.hpp | 36 -- src/mbgl/style/query_parameters.hpp | 21 + src/mbgl/style/render_item.hpp | 9 +- src/mbgl/style/source.cpp | 428 +++++++++++++ src/mbgl/style/source.hpp | 113 ++++ src/mbgl/style/source_observer.hpp | 25 + src/mbgl/style/style.cpp | 52 +- src/mbgl/style/style.hpp | 39 +- src/mbgl/style/style_bucket_parameters.cpp | 21 - src/mbgl/style/style_bucket_parameters.hpp | 62 -- src/mbgl/style/style_calculation_parameters.hpp | 28 - src/mbgl/style/style_cascade_parameters.hpp | 20 - src/mbgl/style/style_observer.hpp | 23 - src/mbgl/style/style_parser.cpp | 688 -------------------- src/mbgl/style/style_parser.hpp | 52 -- src/mbgl/style/style_query_parameters.hpp | 18 - src/mbgl/style/style_render_parameters.hpp | 15 - src/mbgl/style/style_update_parameters.hpp | 54 -- src/mbgl/style/types.cpp | 16 - src/mbgl/style/update_parameters.hpp | 58 ++ src/mbgl/style/zoom_history.hpp | 36 -- src/mbgl/text/glyph_pbf.hpp | 2 +- src/mbgl/text/glyph_store.hpp | 2 +- src/mbgl/text/glyph_store_observer.hpp | 1 + src/mbgl/text/quads.cpp | 4 +- src/mbgl/text/quads.hpp | 74 +-- src/mbgl/text/shaping.cpp | 4 +- src/mbgl/text/shaping.hpp | 34 +- src/mbgl/tile/raster_tile_data.cpp | 4 +- src/mbgl/tile/raster_tile_data.hpp | 8 +- src/mbgl/tile/tile_data.hpp | 7 +- src/mbgl/tile/tile_worker.cpp | 18 +- src/mbgl/tile/tile_worker.hpp | 11 +- src/mbgl/tile/vector_tile.cpp | 2 +- src/mbgl/tile/vector_tile_data.cpp | 6 +- src/mbgl/tile/vector_tile_data.hpp | 11 +- src/mbgl/util/font_stack.cpp | 16 + src/mbgl/util/tileset.hpp | 24 + src/mbgl/util/worker.cpp | 4 +- src/mbgl/util/worker.hpp | 2 +- 166 files changed, 4417 insertions(+), 4247 deletions(-) delete mode 100644 src/mbgl/layer/background_layer.cpp delete mode 100644 src/mbgl/layer/background_layer_impl.cpp delete mode 100644 src/mbgl/layer/background_layer_impl.hpp delete mode 100644 src/mbgl/layer/background_layer_properties.cpp delete mode 100644 src/mbgl/layer/background_layer_properties.hpp delete mode 100644 src/mbgl/layer/circle_layer.cpp delete mode 100644 src/mbgl/layer/circle_layer_impl.cpp delete mode 100644 src/mbgl/layer/circle_layer_impl.hpp delete mode 100644 src/mbgl/layer/circle_layer_properties.cpp delete mode 100644 src/mbgl/layer/circle_layer_properties.hpp delete mode 100644 src/mbgl/layer/custom_layer.cpp delete mode 100644 src/mbgl/layer/custom_layer_impl.cpp delete mode 100644 src/mbgl/layer/custom_layer_impl.hpp delete mode 100644 src/mbgl/layer/fill_layer.cpp delete mode 100644 src/mbgl/layer/fill_layer_impl.cpp delete mode 100644 src/mbgl/layer/fill_layer_impl.hpp delete mode 100644 src/mbgl/layer/fill_layer_properties.cpp delete mode 100644 src/mbgl/layer/fill_layer_properties.hpp delete mode 100644 src/mbgl/layer/layer.cpp delete mode 100644 src/mbgl/layer/layer_impl.cpp delete mode 100644 src/mbgl/layer/layer_impl.hpp delete mode 100644 src/mbgl/layer/line_layer.cpp delete mode 100644 src/mbgl/layer/line_layer_impl.cpp delete mode 100644 src/mbgl/layer/line_layer_impl.hpp delete mode 100644 src/mbgl/layer/line_layer_properties.cpp delete mode 100644 src/mbgl/layer/line_layer_properties.hpp delete mode 100644 src/mbgl/layer/raster_layer.cpp delete mode 100644 src/mbgl/layer/raster_layer_impl.cpp delete mode 100644 src/mbgl/layer/raster_layer_impl.hpp delete mode 100644 src/mbgl/layer/raster_layer_properties.cpp delete mode 100644 src/mbgl/layer/raster_layer_properties.hpp delete mode 100644 src/mbgl/layer/symbol_layer.cpp delete mode 100644 src/mbgl/layer/symbol_layer_impl.cpp delete mode 100644 src/mbgl/layer/symbol_layer_impl.hpp delete mode 100644 src/mbgl/layer/symbol_layer_properties.cpp delete mode 100644 src/mbgl/layer/symbol_layer_properties.hpp create mode 100644 src/mbgl/map/zoom_history.hpp delete mode 100644 src/mbgl/source/source.cpp delete mode 100644 src/mbgl/source/source.hpp delete mode 100644 src/mbgl/source/source_info.hpp delete mode 100644 src/mbgl/source/source_observer.hpp create mode 100644 src/mbgl/style/bucket_parameters.cpp create mode 100644 src/mbgl/style/bucket_parameters.hpp create mode 100644 src/mbgl/style/calculation_parameters.hpp create mode 100644 src/mbgl/style/cascade_parameters.hpp create mode 100644 src/mbgl/style/layer.cpp create mode 100644 src/mbgl/style/layer_impl.cpp create mode 100644 src/mbgl/style/layer_impl.hpp create mode 100644 src/mbgl/style/layers/background_layer.cpp create mode 100644 src/mbgl/style/layers/background_layer_impl.cpp create mode 100644 src/mbgl/style/layers/background_layer_impl.hpp create mode 100644 src/mbgl/style/layers/background_layer_properties.cpp create mode 100644 src/mbgl/style/layers/background_layer_properties.hpp create mode 100644 src/mbgl/style/layers/circle_layer.cpp create mode 100644 src/mbgl/style/layers/circle_layer_impl.cpp create mode 100644 src/mbgl/style/layers/circle_layer_impl.hpp create mode 100644 src/mbgl/style/layers/circle_layer_properties.cpp create mode 100644 src/mbgl/style/layers/circle_layer_properties.hpp create mode 100644 src/mbgl/style/layers/custom_layer.cpp create mode 100644 src/mbgl/style/layers/custom_layer_impl.cpp create mode 100644 src/mbgl/style/layers/custom_layer_impl.hpp create mode 100644 src/mbgl/style/layers/fill_layer.cpp create mode 100644 src/mbgl/style/layers/fill_layer_impl.cpp create mode 100644 src/mbgl/style/layers/fill_layer_impl.hpp create mode 100644 src/mbgl/style/layers/fill_layer_properties.cpp create mode 100644 src/mbgl/style/layers/fill_layer_properties.hpp create mode 100644 src/mbgl/style/layers/line_layer.cpp create mode 100644 src/mbgl/style/layers/line_layer_impl.cpp create mode 100644 src/mbgl/style/layers/line_layer_impl.hpp create mode 100644 src/mbgl/style/layers/line_layer_properties.cpp create mode 100644 src/mbgl/style/layers/line_layer_properties.hpp create mode 100644 src/mbgl/style/layers/raster_layer.cpp create mode 100644 src/mbgl/style/layers/raster_layer_impl.cpp create mode 100644 src/mbgl/style/layers/raster_layer_impl.hpp create mode 100644 src/mbgl/style/layers/raster_layer_properties.cpp create mode 100644 src/mbgl/style/layers/raster_layer_properties.hpp create mode 100644 src/mbgl/style/layers/symbol_layer.cpp create mode 100644 src/mbgl/style/layers/symbol_layer_impl.cpp create mode 100644 src/mbgl/style/layers/symbol_layer_impl.hpp create mode 100644 src/mbgl/style/layers/symbol_layer_properties.cpp create mode 100644 src/mbgl/style/layers/symbol_layer_properties.hpp create mode 100644 src/mbgl/style/observer.hpp create mode 100644 src/mbgl/style/parser.cpp create mode 100644 src/mbgl/style/parser.hpp delete mode 100644 src/mbgl/style/property_value.hpp create mode 100644 src/mbgl/style/query_parameters.hpp create mode 100644 src/mbgl/style/source.cpp create mode 100644 src/mbgl/style/source.hpp create mode 100644 src/mbgl/style/source_observer.hpp delete mode 100644 src/mbgl/style/style_bucket_parameters.cpp delete mode 100644 src/mbgl/style/style_bucket_parameters.hpp delete mode 100644 src/mbgl/style/style_calculation_parameters.hpp delete mode 100644 src/mbgl/style/style_cascade_parameters.hpp delete mode 100644 src/mbgl/style/style_observer.hpp delete mode 100644 src/mbgl/style/style_parser.cpp delete mode 100644 src/mbgl/style/style_parser.hpp delete mode 100644 src/mbgl/style/style_query_parameters.hpp delete mode 100644 src/mbgl/style/style_render_parameters.hpp delete mode 100644 src/mbgl/style/style_update_parameters.hpp delete mode 100644 src/mbgl/style/types.cpp create mode 100644 src/mbgl/style/update_parameters.hpp delete mode 100644 src/mbgl/style/zoom_history.hpp create mode 100644 src/mbgl/util/font_stack.cpp create mode 100644 src/mbgl/util/tileset.hpp (limited to 'src') diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 09442b165c..e332850357 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,15 +4,17 @@ #include #include #include -#include +#include #include -#include -#include +#include +#include #include namespace mbgl { +using namespace style; + const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; @@ -105,7 +107,7 @@ std::unique_ptr AnnotationManager::getTile(const CanonicalTileID void AnnotationManager::updateStyle(Style& style) { // Create annotation source, point layer, and point bucket if (!style.getSource(SourceID)) { - std::unique_ptr source = std::make_unique(SourceType::Annotations, SourceID, "", util::tileSize, std::make_unique(), nullptr); + std::unique_ptr source = std::make_unique(SourceType::Annotations, SourceID, "", util::tileSize, std::make_unique(), nullptr); source->enabled = true; style.addSource(std::move(source)); diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index 6862739ebb..73907e10c8 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -18,7 +18,10 @@ class AnnotationTile; class AnnotationTileMonitor; class SymbolAnnotationImpl; class ShapeAnnotationImpl; + +namespace style { class Style; +} class AnnotationManager : private util::noncopyable { public: @@ -36,7 +39,7 @@ public: double getTopOffsetPixelsForIcon(const std::string& name); SpriteAtlas& getSpriteAtlas() { return spriteAtlas; } - void updateStyle(Style&); + void updateStyle(style::Style&); void addTileMonitor(AnnotationTileMonitor&); void removeTileMonitor(AnnotationTileMonitor&); diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp index 17bdd9c38e..31c9f6d720 100644 --- a/src/mbgl/annotation/fill_annotation_impl.cpp +++ b/src/mbgl/annotation/fill_annotation_impl.cpp @@ -1,11 +1,11 @@ #include #include #include -#include +#include namespace mbgl { -namespace geojsonvt = mapbox::geojsonvt; +using namespace style; FillAnnotationImpl::FillAnnotationImpl(const AnnotationID id_, const FillAnnotation& annotation_, const uint8_t maxZoom_) : ShapeAnnotationImpl(id_, maxZoom_), diff --git a/src/mbgl/annotation/fill_annotation_impl.hpp b/src/mbgl/annotation/fill_annotation_impl.hpp index c396499e38..b879860c08 100644 --- a/src/mbgl/annotation/fill_annotation_impl.hpp +++ b/src/mbgl/annotation/fill_annotation_impl.hpp @@ -9,7 +9,7 @@ class FillAnnotationImpl : public ShapeAnnotationImpl { public: FillAnnotationImpl(const AnnotationID, const FillAnnotation&, const uint8_t maxZoom); - void updateStyle(Style&) const final; + void updateStyle(style::Style&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp index 11febc7de7..85177591f4 100644 --- a/src/mbgl/annotation/line_annotation_impl.cpp +++ b/src/mbgl/annotation/line_annotation_impl.cpp @@ -1,11 +1,11 @@ #include #include #include -#include +#include namespace mbgl { -namespace geojsonvt = mapbox::geojsonvt; +using namespace style; LineAnnotationImpl::LineAnnotationImpl(const AnnotationID id_, const LineAnnotation& annotation_, const uint8_t maxZoom_) : ShapeAnnotationImpl(id_, maxZoom_), diff --git a/src/mbgl/annotation/line_annotation_impl.hpp b/src/mbgl/annotation/line_annotation_impl.hpp index 05d650c051..c9a37dd390 100644 --- a/src/mbgl/annotation/line_annotation_impl.hpp +++ b/src/mbgl/annotation/line_annotation_impl.hpp @@ -9,7 +9,7 @@ class LineAnnotationImpl : public ShapeAnnotationImpl { public: LineAnnotationImpl(const AnnotationID, const LineAnnotation&, const uint8_t maxZoom); - void updateStyle(Style&) const final; + void updateStyle(style::Style&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp index 283e736c6d..be6e12558d 100644 --- a/src/mbgl/annotation/shape_annotation_impl.cpp +++ b/src/mbgl/annotation/shape_annotation_impl.cpp @@ -10,6 +10,7 @@ namespace mbgl { +using namespace style; namespace geojsonvt = mapbox::geojsonvt; ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, const uint8_t maxZoom_) diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index 7f36f8b888..e6ba9a4bd7 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -9,16 +9,19 @@ namespace mbgl { -class Style; class AnnotationTile; class CanonicalTileID; +namespace style { +class Style; +} + class ShapeAnnotationImpl { public: ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom); virtual ~ShapeAnnotationImpl() = default; - virtual void updateStyle(Style&) const = 0; + virtual void updateStyle(style::Style&) const = 0; virtual const ShapeAnnotationGeometry& geometry() const = 0; void updateTile(const CanonicalTileID&, AnnotationTile&); diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.cpp b/src/mbgl/annotation/style_sourced_annotation_impl.cpp index e1e11a664a..43a27c8aac 100644 --- a/src/mbgl/annotation/style_sourced_annotation_impl.cpp +++ b/src/mbgl/annotation/style_sourced_annotation_impl.cpp @@ -2,12 +2,12 @@ #include #include #include -#include -#include +#include +#include namespace mbgl { -namespace geojsonvt = mapbox::geojsonvt; +using namespace style; StyleSourcedAnnotationImpl::StyleSourcedAnnotationImpl(const AnnotationID id_, const StyleSourcedAnnotation& annotation_, const uint8_t maxZoom_) : ShapeAnnotationImpl(id_, maxZoom_), diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.hpp b/src/mbgl/annotation/style_sourced_annotation_impl.hpp index 98e9910c66..09ef474fc0 100644 --- a/src/mbgl/annotation/style_sourced_annotation_impl.hpp +++ b/src/mbgl/annotation/style_sourced_annotation_impl.hpp @@ -9,7 +9,7 @@ class StyleSourcedAnnotationImpl : public ShapeAnnotationImpl { public: StyleSourcedAnnotationImpl(const AnnotationID, const StyleSourcedAnnotation&, const uint8_t maxZoom); - void updateStyle(Style&) const final; + void updateStyle(style::Style&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index e72aa344fa..8c10344915 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -59,7 +59,7 @@ void FeatureIndex::query( const optional>& filterLayerIDs, const GeometryTile& geometryTile, const CanonicalTileID& tileID, - const Style& style) const { + const style::Style& style) const { mapbox::geometry::box box = mapbox::geometry::envelope(queryGeometry); @@ -94,7 +94,7 @@ void FeatureIndex::addFeature( const optional>& filterLayerIDs, const GeometryTile& geometryTile, const CanonicalTileID& tileID, - const Style& style, + const style::Style& style, const float bearing, const float pixelsToTileUnits) const { @@ -116,7 +116,7 @@ void FeatureIndex::addFeature( auto styleLayer = style.getLayer(layerID); if (!styleLayer || - (!styleLayer->is() && + (!styleLayer->is() && !styleLayer->baseImpl->queryIntersectsGeometry(queryGeometry, geometryTileFeature->getGeometries(), bearing, pixelsToTileUnits))) { continue; } @@ -128,7 +128,7 @@ void FeatureIndex::addFeature( optional FeatureIndex::translateQueryGeometry( const GeometryCollection& queryGeometry, const std::array& translate, - const TranslateAnchorType anchorType, + const style::TranslateAnchorType anchorType, const float bearing, const float pixelsToTileUnits) { if (translate[0] == 0 && translate[1] == 0) { @@ -136,7 +136,7 @@ optional FeatureIndex::translateQueryGeometry( } GeometryCoordinate translateVec(translate[0] * pixelsToTileUnits, translate[1] * pixelsToTileUnits); - if (anchorType == TranslateAnchorType::Viewport) { + if (anchorType == style::TranslateAnchorType::Viewport) { translateVec = util::rotate(translateVec, -bearing); } diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp index 0dcc154f02..c944a98130 100644 --- a/src/mbgl/geometry/feature_index.hpp +++ b/src/mbgl/geometry/feature_index.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -10,9 +11,11 @@ namespace mbgl { +namespace style { class Style; +} + class CollisionTile; -enum class TranslateAnchorType : bool; class CanonicalTileID; class IndexedSubfeature { @@ -39,12 +42,12 @@ public: const optional>& layerIDs, const GeometryTile&, const CanonicalTileID&, - const Style&) const; + const style::Style&) const; static optional translateQueryGeometry( const GeometryCollection& queryGeometry, const std::array& translate, - const TranslateAnchorType, + const style::TranslateAnchorType, const float bearing, const float pixelsToTileUnits); @@ -60,7 +63,7 @@ private: const optional>& filterLayerIDs, const GeometryTile&, const CanonicalTileID&, - const Style&, + const style::Style&, const float bearing, const float pixelsToTileUnits) const; diff --git a/src/mbgl/layer/background_layer.cpp b/src/mbgl/layer/background_layer.cpp deleted file mode 100644 index 36cf6be07c..0000000000 --- a/src/mbgl/layer/background_layer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -BackgroundLayer::BackgroundLayer(const std::string& layerID) - : Layer(Type::Background, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -BackgroundLayer::BackgroundLayer(const Impl& other) - : Layer(Type::Background, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -BackgroundLayer::~BackgroundLayer() = default; - -std::unique_ptr BackgroundLayer::Impl::clone() const { - return std::make_unique(*this); -} - - -// Layout properties - - -// Paint properties - -PropertyValue BackgroundLayer::getBackgroundColor() const { - return impl->paint.backgroundColor.get(); -} - -void BackgroundLayer::setBackgroundColor(PropertyValue value) { - impl->paint.backgroundColor.set(value); -} - -PropertyValue BackgroundLayer::getBackgroundPattern() const { - return impl->paint.backgroundPattern.get(); -} - -void BackgroundLayer::setBackgroundPattern(PropertyValue value) { - impl->paint.backgroundPattern.set(value); -} - -PropertyValue BackgroundLayer::getBackgroundOpacity() const { - return impl->paint.backgroundOpacity.get(); -} - -void BackgroundLayer::setBackgroundOpacity(PropertyValue value) { - impl->paint.backgroundOpacity.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/background_layer_impl.cpp b/src/mbgl/layer/background_layer_impl.cpp deleted file mode 100644 index 626c8fc805..0000000000 --- a/src/mbgl/layer/background_layer_impl.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -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 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 deleted file mode 100644 index 6af31dd921..0000000000 --- a/src/mbgl/layer/background_layer_impl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class BackgroundLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index d866df7eee..0000000000 --- a/src/mbgl/layer/background_layer_properties.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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 deleted file mode 100644 index 20db9b22fb..0000000000 --- a/src/mbgl/layer/background_layer_properties.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class BackgroundPaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty backgroundColor { {{ 0, 0, 0, 1 }} }; - PaintProperty backgroundPattern { "" }; - PaintProperty backgroundOpacity { 1 }; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/circle_layer.cpp b/src/mbgl/layer/circle_layer.cpp deleted file mode 100644 index efc0e9488d..0000000000 --- a/src/mbgl/layer/circle_layer.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -CircleLayer::CircleLayer(const std::string& layerID) - : Layer(Type::Circle, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -CircleLayer::CircleLayer(const Impl& other) - : Layer(Type::Circle, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -CircleLayer::~CircleLayer() = default; - -std::unique_ptr CircleLayer::Impl::clone() const { - return std::make_unique(*this); -} - -// Source - -void CircleLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { - impl->source = sourceID; - impl->sourceLayer = sourceLayer; -} - -const std::string& CircleLayer::getSourceID() const { - return impl->source; -} - -const std::string& CircleLayer::getSourceLayer() const { - return impl->sourceLayer; -} - -// Filter - -void CircleLayer::setFilter(const Filter& filter) { - impl->filter = filter; -} - -const Filter& CircleLayer::getFilter() const { - return impl->filter; -} - -// Layout properties - - -// Paint properties - -PropertyValue CircleLayer::getCircleRadius() const { - return impl->paint.circleRadius.get(); -} - -void CircleLayer::setCircleRadius(PropertyValue value) { - impl->paint.circleRadius.set(value); -} - -PropertyValue CircleLayer::getCircleColor() const { - return impl->paint.circleColor.get(); -} - -void CircleLayer::setCircleColor(PropertyValue value) { - impl->paint.circleColor.set(value); -} - -PropertyValue CircleLayer::getCircleBlur() const { - return impl->paint.circleBlur.get(); -} - -void CircleLayer::setCircleBlur(PropertyValue value) { - impl->paint.circleBlur.set(value); -} - -PropertyValue CircleLayer::getCircleOpacity() const { - return impl->paint.circleOpacity.get(); -} - -void CircleLayer::setCircleOpacity(PropertyValue value) { - impl->paint.circleOpacity.set(value); -} - -PropertyValue> CircleLayer::getCircleTranslate() const { - return impl->paint.circleTranslate.get(); -} - -void CircleLayer::setCircleTranslate(PropertyValue> value) { - impl->paint.circleTranslate.set(value); -} - -PropertyValue CircleLayer::getCircleTranslateAnchor() const { - return impl->paint.circleTranslateAnchor.get(); -} - -void CircleLayer::setCircleTranslateAnchor(PropertyValue value) { - impl->paint.circleTranslateAnchor.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/circle_layer_impl.cpp b/src/mbgl/layer/circle_layer_impl.cpp deleted file mode 100644 index b1ba778cd6..0000000000 --- a/src/mbgl/layer/circle_layer_impl.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include -#include - -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 CircleLayer::Impl::createBucket(StyleBucketParameters& parameters) const { - auto bucket = std::make_unique(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& 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 deleted file mode 100644 index 1cb19a6205..0000000000 --- a/src/mbgl/layer/circle_layer_impl.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class CircleLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index 48d99b579e..0000000000 --- a/src/mbgl/layer/circle_layer_properties.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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 deleted file mode 100644 index a88db27605..0000000000 --- a/src/mbgl/layer/circle_layer_properties.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class CirclePaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty circleRadius { 5 }; - PaintProperty circleColor { {{ 0, 0, 0, 1 }} }; - PaintProperty circleBlur { 0 }; - PaintProperty circleOpacity { 1 }; - PaintProperty> circleTranslate { {{ 0, 0 }} }; - PaintProperty circleTranslateAnchor { TranslateAnchorType::Map }; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/custom_layer.cpp b/src/mbgl/layer/custom_layer.cpp deleted file mode 100644 index a33176e7f9..0000000000 --- a/src/mbgl/layer/custom_layer.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -namespace mbgl { - -CustomLayer::CustomLayer(const std::string& layerID, - CustomLayerInitializeFunction init, - CustomLayerRenderFunction render, - CustomLayerDeinitializeFunction deinit, - void* context) - : Layer(Type::Custom, std::make_unique(layerID, init, render, deinit, context)) - , impl(static_cast(baseImpl.get())) { -} - -CustomLayer::CustomLayer(const Impl& other) - : Layer(Type::Custom, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -CustomLayer::~CustomLayer() = default; - -} // namespace mbgl diff --git a/src/mbgl/layer/custom_layer_impl.cpp b/src/mbgl/layer/custom_layer_impl.cpp deleted file mode 100644 index 8a08c804ed..0000000000 --- a/src/mbgl/layer/custom_layer_impl.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include - -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 CustomLayer::Impl::clone() const { - return std::make_unique(*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 CustomLayer::Impl::createBucket(StyleBucketParameters&) const { - return nullptr; -} - -} // namespace mbgl diff --git a/src/mbgl/layer/custom_layer_impl.hpp b/src/mbgl/layer/custom_layer_impl.hpp deleted file mode 100644 index 09709a2f9d..0000000000 --- a/src/mbgl/layer/custom_layer_impl.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include - -namespace mbgl { - -class TransformState; - -class CustomLayer::Impl : public Layer::Impl { -public: - Impl(const std::string& id, - CustomLayerInitializeFunction, - CustomLayerRenderFunction, - CustomLayerDeinitializeFunction, - void* context); - - Impl(const Impl&); - ~Impl() final; - - void initialize(); - void render(const TransformState&) const; - -private: - std::unique_ptr clone() const override; - - void parseLayout(const JSValue&) final {} - void parsePaints(const JSValue&) final {} - - void cascade(const StyleCascadeParameters&) final {} - bool recalculate(const StyleCalculationParameters&) final; - - std::unique_ptr createBucket(StyleBucketParameters&) const final; - - CustomLayerInitializeFunction initializeFn = nullptr; - CustomLayerRenderFunction renderFn = nullptr; - CustomLayerDeinitializeFunction deinitializeFn = nullptr; - void* context = nullptr; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/fill_layer.cpp b/src/mbgl/layer/fill_layer.cpp deleted file mode 100644 index 77efaa61aa..0000000000 --- a/src/mbgl/layer/fill_layer.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -FillLayer::FillLayer(const std::string& layerID) - : Layer(Type::Fill, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -FillLayer::FillLayer(const Impl& other) - : Layer(Type::Fill, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -FillLayer::~FillLayer() = default; - -std::unique_ptr FillLayer::Impl::clone() const { - return std::make_unique(*this); -} - -// Source - -void FillLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { - impl->source = sourceID; - impl->sourceLayer = sourceLayer; -} - -const std::string& FillLayer::getSourceID() const { - return impl->source; -} - -const std::string& FillLayer::getSourceLayer() const { - return impl->sourceLayer; -} - -// Filter - -void FillLayer::setFilter(const Filter& filter) { - impl->filter = filter; -} - -const Filter& FillLayer::getFilter() const { - return impl->filter; -} - -// Layout properties - - -// Paint properties - -PropertyValue FillLayer::getFillAntialias() const { - return impl->paint.fillAntialias.get(); -} - -void FillLayer::setFillAntialias(PropertyValue value) { - impl->paint.fillAntialias.set(value); -} - -PropertyValue FillLayer::getFillOpacity() const { - return impl->paint.fillOpacity.get(); -} - -void FillLayer::setFillOpacity(PropertyValue value) { - impl->paint.fillOpacity.set(value); -} - -PropertyValue FillLayer::getFillColor() const { - return impl->paint.fillColor.get(); -} - -void FillLayer::setFillColor(PropertyValue value) { - impl->paint.fillColor.set(value); -} - -PropertyValue FillLayer::getFillOutlineColor() const { - return impl->paint.fillOutlineColor.get(); -} - -void FillLayer::setFillOutlineColor(PropertyValue value) { - impl->paint.fillOutlineColor.set(value); -} - -PropertyValue> FillLayer::getFillTranslate() const { - return impl->paint.fillTranslate.get(); -} - -void FillLayer::setFillTranslate(PropertyValue> value) { - impl->paint.fillTranslate.set(value); -} - -PropertyValue FillLayer::getFillTranslateAnchor() const { - return impl->paint.fillTranslateAnchor.get(); -} - -void FillLayer::setFillTranslateAnchor(PropertyValue value) { - impl->paint.fillTranslateAnchor.set(value); -} - -PropertyValue FillLayer::getFillPattern() const { - return impl->paint.fillPattern.get(); -} - -void FillLayer::setFillPattern(PropertyValue value) { - impl->paint.fillPattern.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/fill_layer_impl.cpp b/src/mbgl/layer/fill_layer_impl.cpp deleted file mode 100644 index 21f482922d..0000000000 --- a/src/mbgl/layer/fill_layer_impl.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include -#include - -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 FillLayer::Impl::createBucket(StyleBucketParameters& parameters) const { - auto bucket = std::make_unique(); - - 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& 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 deleted file mode 100644 index 2af0d6491d..0000000000 --- a/src/mbgl/layer/fill_layer_impl.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class FillLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index e0d4f10bc9..0000000000 --- a/src/mbgl/layer/fill_layer_properties.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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 deleted file mode 100644 index 2ae67ef0a0..0000000000 --- a/src/mbgl/layer/fill_layer_properties.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class FillPaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty fillAntialias { true }; - PaintProperty fillOpacity { 1 }; - PaintProperty fillColor { {{ 0, 0, 0, 1 }} }; - PaintProperty fillOutlineColor { {{ 0, 0, 0, -1 }} }; - PaintProperty> fillTranslate { {{ 0, 0 }} }; - PaintProperty fillTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty fillPattern { "" }; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/layer.cpp b/src/mbgl/layer/layer.cpp deleted file mode 100644 index c26eb9a723..0000000000 --- a/src/mbgl/layer/layer.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -namespace mbgl { - -Layer::Layer(Type type_, std::unique_ptr 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; -} - -float Layer::getMinZoom() const { - return baseImpl->minZoom; -} - -void Layer::setMinZoom(float minZoom) const { - baseImpl->minZoom = minZoom; -} - -float Layer::getMaxZoom() const { - return baseImpl->maxZoom; -} - -void Layer::setMaxZoom(float maxZoom) const { - baseImpl->maxZoom = maxZoom; -} - -std::unique_ptr Layer::copy(const std::string& id, - const std::string& ref) const { - std::unique_ptr 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 deleted file mode 100644 index 315a1cb1b1..0000000000 --- a/src/mbgl/layer/layer_impl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include - -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 deleted file mode 100644 index 3d6b5cccfd..0000000000 --- a/src/mbgl/layer/layer_impl.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -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 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 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::infinity(); - float maxZoom = std::numeric_limits::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 deleted file mode 100644 index e1a7d813af..0000000000 --- a/src/mbgl/layer/line_layer.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -LineLayer::LineLayer(const std::string& layerID) - : Layer(Type::Line, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -LineLayer::LineLayer(const Impl& other) - : Layer(Type::Line, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -LineLayer::~LineLayer() = default; - -std::unique_ptr LineLayer::Impl::clone() const { - return std::make_unique(*this); -} - -// Source - -void LineLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { - impl->source = sourceID; - impl->sourceLayer = sourceLayer; -} - -const std::string& LineLayer::getSourceID() const { - return impl->source; -} - -const std::string& LineLayer::getSourceLayer() const { - return impl->sourceLayer; -} - -// Filter - -void LineLayer::setFilter(const Filter& filter) { - impl->filter = filter; -} - -const Filter& LineLayer::getFilter() const { - return impl->filter; -} - -// Layout properties - -PropertyValue LineLayer::getLineCap() const { - return impl->layout.lineCap.get(); -} - -void LineLayer::setLineCap(PropertyValue value) { - impl->layout.lineCap.set(value); -} -PropertyValue LineLayer::getLineJoin() const { - return impl->layout.lineJoin.get(); -} - -void LineLayer::setLineJoin(PropertyValue value) { - impl->layout.lineJoin.set(value); -} -PropertyValue LineLayer::getLineMiterLimit() const { - return impl->layout.lineMiterLimit.get(); -} - -void LineLayer::setLineMiterLimit(PropertyValue value) { - impl->layout.lineMiterLimit.set(value); -} -PropertyValue LineLayer::getLineRoundLimit() const { - return impl->layout.lineRoundLimit.get(); -} - -void LineLayer::setLineRoundLimit(PropertyValue value) { - impl->layout.lineRoundLimit.set(value); -} - -// Paint properties - -PropertyValue LineLayer::getLineOpacity() const { - return impl->paint.lineOpacity.get(); -} - -void LineLayer::setLineOpacity(PropertyValue value) { - impl->paint.lineOpacity.set(value); -} - -PropertyValue LineLayer::getLineColor() const { - return impl->paint.lineColor.get(); -} - -void LineLayer::setLineColor(PropertyValue value) { - impl->paint.lineColor.set(value); -} - -PropertyValue> LineLayer::getLineTranslate() const { - return impl->paint.lineTranslate.get(); -} - -void LineLayer::setLineTranslate(PropertyValue> value) { - impl->paint.lineTranslate.set(value); -} - -PropertyValue LineLayer::getLineTranslateAnchor() const { - return impl->paint.lineTranslateAnchor.get(); -} - -void LineLayer::setLineTranslateAnchor(PropertyValue value) { - impl->paint.lineTranslateAnchor.set(value); -} - -PropertyValue LineLayer::getLineWidth() const { - return impl->paint.lineWidth.get(); -} - -void LineLayer::setLineWidth(PropertyValue value) { - impl->paint.lineWidth.set(value); -} - -PropertyValue LineLayer::getLineGapWidth() const { - return impl->paint.lineGapWidth.get(); -} - -void LineLayer::setLineGapWidth(PropertyValue value) { - impl->paint.lineGapWidth.set(value); -} - -PropertyValue LineLayer::getLineOffset() const { - return impl->paint.lineOffset.get(); -} - -void LineLayer::setLineOffset(PropertyValue value) { - impl->paint.lineOffset.set(value); -} - -PropertyValue LineLayer::getLineBlur() const { - return impl->paint.lineBlur.get(); -} - -void LineLayer::setLineBlur(PropertyValue value) { - impl->paint.lineBlur.set(value); -} - -PropertyValue> LineLayer::getLineDasharray() const { - return impl->paint.lineDasharray.get(); -} - -void LineLayer::setLineDasharray(PropertyValue> value) { - impl->paint.lineDasharray.set(value); -} - -PropertyValue LineLayer::getLinePattern() const { - return impl->paint.linePattern.get(); -} - -void LineLayer::setLinePattern(PropertyValue value) { - impl->paint.linePattern.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/line_layer_impl.cpp b/src/mbgl/layer/line_layer_impl.cpp deleted file mode 100644 index aee1687046..0000000000 --- a/src/mbgl/layer/line_layer_impl.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include -#include -#include -#include - -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 LineLayer::Impl::createBucket(StyleBucketParameters& parameters) const { - auto bucket = std::make_unique(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 offsetLine(const GeometryCollection& rings, const double offset) { - if (offset == 0) return {}; - - GeometryCollection newRings; - Point 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 aToB = i == ring.begin() ? - zero : - util::perp(util::unit(convertPoint(p - *(i - 1)))); - Point bToC = i + 1 == ring.end() ? - zero : - util::perp(util::unit(convertPoint(*(i + 1) - p))); - Point extrude = util::unit(aToB + bToC); - - const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y; - extrude *= (1.0 / cosHalfAngle); - - newRing.push_back(convertPoint(extrude * offset) + p); - } - } - - return newRings; -} - -float LineLayer::Impl::getQueryRadius() const { - const std::array& 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 deleted file mode 100644 index b602df52fa..0000000000 --- a/src/mbgl/layer/line_layer_impl.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class LineLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index 4941a1ecd2..0000000000 --- a/src/mbgl/layer/line_layer_properties.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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 deleted file mode 100644 index f4dad055bd..0000000000 --- a/src/mbgl/layer/line_layer_properties.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class LineLayoutProperties { -public: - void parse(const JSValue&); - void recalculate(const StyleCalculationParameters&); - - LayoutProperty lineCap { LineCapType::Butt }; - LayoutProperty lineJoin { LineJoinType::Miter }; - LayoutProperty lineMiterLimit { 2 }; - LayoutProperty lineRoundLimit { 1.05 }; -}; - -class LinePaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty lineOpacity { 1 }; - PaintProperty lineColor { {{ 0, 0, 0, 1 }} }; - PaintProperty> lineTranslate { {{ 0, 0 }} }; - PaintProperty lineTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty lineWidth { 1 }; - PaintProperty lineGapWidth { 0 }; - PaintProperty lineOffset { 0 }; - PaintProperty lineBlur { 0 }; - PaintProperty, CrossFadedPropertyEvaluator> lineDasharray { { } }; - PaintProperty linePattern { "" }; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/raster_layer.cpp b/src/mbgl/layer/raster_layer.cpp deleted file mode 100644 index 661c44b7d5..0000000000 --- a/src/mbgl/layer/raster_layer.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -RasterLayer::RasterLayer(const std::string& layerID) - : Layer(Type::Raster, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -RasterLayer::RasterLayer(const Impl& other) - : Layer(Type::Raster, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -RasterLayer::~RasterLayer() = default; - -std::unique_ptr RasterLayer::Impl::clone() const { - return std::make_unique(*this); -} - -// Source - -void RasterLayer::setSource(const std::string& sourceID) { - impl->source = sourceID; -} - -const std::string& RasterLayer::getSourceID() const { - return impl->source; -} - -// Layout properties - - -// Paint properties - -PropertyValue RasterLayer::getRasterOpacity() const { - return impl->paint.rasterOpacity.get(); -} - -void RasterLayer::setRasterOpacity(PropertyValue value) { - impl->paint.rasterOpacity.set(value); -} - -PropertyValue RasterLayer::getRasterHueRotate() const { - return impl->paint.rasterHueRotate.get(); -} - -void RasterLayer::setRasterHueRotate(PropertyValue value) { - impl->paint.rasterHueRotate.set(value); -} - -PropertyValue RasterLayer::getRasterBrightnessMin() const { - return impl->paint.rasterBrightnessMin.get(); -} - -void RasterLayer::setRasterBrightnessMin(PropertyValue value) { - impl->paint.rasterBrightnessMin.set(value); -} - -PropertyValue RasterLayer::getRasterBrightnessMax() const { - return impl->paint.rasterBrightnessMax.get(); -} - -void RasterLayer::setRasterBrightnessMax(PropertyValue value) { - impl->paint.rasterBrightnessMax.set(value); -} - -PropertyValue RasterLayer::getRasterSaturation() const { - return impl->paint.rasterSaturation.get(); -} - -void RasterLayer::setRasterSaturation(PropertyValue value) { - impl->paint.rasterSaturation.set(value); -} - -PropertyValue RasterLayer::getRasterContrast() const { - return impl->paint.rasterContrast.get(); -} - -void RasterLayer::setRasterContrast(PropertyValue value) { - impl->paint.rasterContrast.set(value); -} - -PropertyValue RasterLayer::getRasterFadeDuration() const { - return impl->paint.rasterFadeDuration.get(); -} - -void RasterLayer::setRasterFadeDuration(PropertyValue value) { - impl->paint.rasterFadeDuration.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/raster_layer_impl.cpp b/src/mbgl/layer/raster_layer_impl.cpp deleted file mode 100644 index f44a424f99..0000000000 --- a/src/mbgl/layer/raster_layer_impl.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -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 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 deleted file mode 100644 index a83c7f259e..0000000000 --- a/src/mbgl/layer/raster_layer_impl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class RasterLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index 898188bc83..0000000000 --- a/src/mbgl/layer/raster_layer_properties.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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 deleted file mode 100644 index 46bd00ff2e..0000000000 --- a/src/mbgl/layer/raster_layer_properties.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class RasterPaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty rasterOpacity { 1 }; - PaintProperty rasterHueRotate { 0 }; - PaintProperty rasterBrightnessMin { 0 }; - PaintProperty rasterBrightnessMax { 1 }; - PaintProperty rasterSaturation { 0 }; - PaintProperty rasterContrast { 0 }; - PaintProperty rasterFadeDuration { 300 }; -}; - -} // namespace mbgl diff --git a/src/mbgl/layer/symbol_layer.cpp b/src/mbgl/layer/symbol_layer.cpp deleted file mode 100644 index 66d018b581..0000000000 --- a/src/mbgl/layer/symbol_layer.cpp +++ /dev/null @@ -1,384 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include -#include - -namespace mbgl { - -SymbolLayer::SymbolLayer(const std::string& layerID) - : Layer(Type::Symbol, std::make_unique()) - , impl(static_cast(baseImpl.get())) { - impl->id = layerID; -} - -SymbolLayer::SymbolLayer(const Impl& other) - : Layer(Type::Symbol, std::make_unique(other)) - , impl(static_cast(baseImpl.get())) { -} - -SymbolLayer::~SymbolLayer() = default; - -std::unique_ptr SymbolLayer::Impl::clone() const { - return std::make_unique(*this); -} - -// Source - -void SymbolLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { - impl->source = sourceID; - impl->sourceLayer = sourceLayer; -} - -const std::string& SymbolLayer::getSourceID() const { - return impl->source; -} - -const std::string& SymbolLayer::getSourceLayer() const { - return impl->sourceLayer; -} - -// Filter - -void SymbolLayer::setFilter(const Filter& filter) { - impl->filter = filter; -} - -const Filter& SymbolLayer::getFilter() const { - return impl->filter; -} - -// Layout properties - -PropertyValue SymbolLayer::getSymbolPlacement() const { - return impl->layout.symbolPlacement.get(); -} - -void SymbolLayer::setSymbolPlacement(PropertyValue value) { - impl->layout.symbolPlacement.set(value); -} -PropertyValue SymbolLayer::getSymbolSpacing() const { - return impl->layout.symbolSpacing.get(); -} - -void SymbolLayer::setSymbolSpacing(PropertyValue value) { - impl->layout.symbolSpacing.set(value); -} -PropertyValue SymbolLayer::getSymbolAvoidEdges() const { - return impl->layout.symbolAvoidEdges.get(); -} - -void SymbolLayer::setSymbolAvoidEdges(PropertyValue value) { - impl->layout.symbolAvoidEdges.set(value); -} -PropertyValue SymbolLayer::getIconAllowOverlap() const { - return impl->layout.iconAllowOverlap.get(); -} - -void SymbolLayer::setIconAllowOverlap(PropertyValue value) { - impl->layout.iconAllowOverlap.set(value); -} -PropertyValue SymbolLayer::getIconIgnorePlacement() const { - return impl->layout.iconIgnorePlacement.get(); -} - -void SymbolLayer::setIconIgnorePlacement(PropertyValue value) { - impl->layout.iconIgnorePlacement.set(value); -} -PropertyValue SymbolLayer::getIconOptional() const { - return impl->layout.iconOptional.get(); -} - -void SymbolLayer::setIconOptional(PropertyValue value) { - impl->layout.iconOptional.set(value); -} -PropertyValue SymbolLayer::getIconRotationAlignment() const { - return impl->layout.iconRotationAlignment.get(); -} - -void SymbolLayer::setIconRotationAlignment(PropertyValue value) { - impl->layout.iconRotationAlignment.set(value); -} -PropertyValue SymbolLayer::getIconSize() const { - return impl->layout.iconSize.get(); -} - -void SymbolLayer::setIconSize(PropertyValue value) { - impl->layout.iconSize.set(value); -} -PropertyValue SymbolLayer::getIconImage() const { - return impl->layout.iconImage.get(); -} - -void SymbolLayer::setIconImage(PropertyValue value) { - impl->layout.iconImage.set(value); -} -PropertyValue SymbolLayer::getIconRotate() const { - return impl->layout.iconRotate.get(); -} - -void SymbolLayer::setIconRotate(PropertyValue value) { - impl->layout.iconRotate.set(value); -} -PropertyValue SymbolLayer::getIconPadding() const { - return impl->layout.iconPadding.get(); -} - -void SymbolLayer::setIconPadding(PropertyValue value) { - impl->layout.iconPadding.set(value); -} -PropertyValue SymbolLayer::getIconKeepUpright() const { - return impl->layout.iconKeepUpright.get(); -} - -void SymbolLayer::setIconKeepUpright(PropertyValue value) { - impl->layout.iconKeepUpright.set(value); -} -PropertyValue> SymbolLayer::getIconOffset() const { - return impl->layout.iconOffset.get(); -} - -void SymbolLayer::setIconOffset(PropertyValue> value) { - impl->layout.iconOffset.set(value); -} -PropertyValue SymbolLayer::getTextRotationAlignment() const { - return impl->layout.textRotationAlignment.get(); -} - -void SymbolLayer::setTextRotationAlignment(PropertyValue value) { - impl->layout.textRotationAlignment.set(value); -} -PropertyValue SymbolLayer::getTextField() const { - return impl->layout.textField.get(); -} - -void SymbolLayer::setTextField(PropertyValue value) { - impl->layout.textField.set(value); -} -PropertyValue> SymbolLayer::getTextFont() const { - return impl->layout.textFont.get(); -} - -void SymbolLayer::setTextFont(PropertyValue> value) { - impl->layout.textFont.set(value); -} -PropertyValue SymbolLayer::getTextSize() const { - return impl->layout.textSize.get(); -} - -void SymbolLayer::setTextSize(PropertyValue value) { - impl->layout.textSize.set(value); -} -PropertyValue SymbolLayer::getTextMaxWidth() const { - return impl->layout.textMaxWidth.get(); -} - -void SymbolLayer::setTextMaxWidth(PropertyValue value) { - impl->layout.textMaxWidth.set(value); -} -PropertyValue SymbolLayer::getTextLineHeight() const { - return impl->layout.textLineHeight.get(); -} - -void SymbolLayer::setTextLineHeight(PropertyValue value) { - impl->layout.textLineHeight.set(value); -} -PropertyValue SymbolLayer::getTextLetterSpacing() const { - return impl->layout.textLetterSpacing.get(); -} - -void SymbolLayer::setTextLetterSpacing(PropertyValue value) { - impl->layout.textLetterSpacing.set(value); -} -PropertyValue SymbolLayer::getTextJustify() const { - return impl->layout.textJustify.get(); -} - -void SymbolLayer::setTextJustify(PropertyValue value) { - impl->layout.textJustify.set(value); -} -PropertyValue SymbolLayer::getTextAnchor() const { - return impl->layout.textAnchor.get(); -} - -void SymbolLayer::setTextAnchor(PropertyValue value) { - impl->layout.textAnchor.set(value); -} -PropertyValue SymbolLayer::getTextMaxAngle() const { - return impl->layout.textMaxAngle.get(); -} - -void SymbolLayer::setTextMaxAngle(PropertyValue value) { - impl->layout.textMaxAngle.set(value); -} -PropertyValue SymbolLayer::getTextRotate() const { - return impl->layout.textRotate.get(); -} - -void SymbolLayer::setTextRotate(PropertyValue value) { - impl->layout.textRotate.set(value); -} -PropertyValue SymbolLayer::getTextPadding() const { - return impl->layout.textPadding.get(); -} - -void SymbolLayer::setTextPadding(PropertyValue value) { - impl->layout.textPadding.set(value); -} -PropertyValue SymbolLayer::getTextKeepUpright() const { - return impl->layout.textKeepUpright.get(); -} - -void SymbolLayer::setTextKeepUpright(PropertyValue value) { - impl->layout.textKeepUpright.set(value); -} -PropertyValue SymbolLayer::getTextTransform() const { - return impl->layout.textTransform.get(); -} - -void SymbolLayer::setTextTransform(PropertyValue value) { - impl->layout.textTransform.set(value); -} -PropertyValue> SymbolLayer::getTextOffset() const { - return impl->layout.textOffset.get(); -} - -void SymbolLayer::setTextOffset(PropertyValue> value) { - impl->layout.textOffset.set(value); -} -PropertyValue SymbolLayer::getTextAllowOverlap() const { - return impl->layout.textAllowOverlap.get(); -} - -void SymbolLayer::setTextAllowOverlap(PropertyValue value) { - impl->layout.textAllowOverlap.set(value); -} -PropertyValue SymbolLayer::getTextIgnorePlacement() const { - return impl->layout.textIgnorePlacement.get(); -} - -void SymbolLayer::setTextIgnorePlacement(PropertyValue value) { - impl->layout.textIgnorePlacement.set(value); -} -PropertyValue SymbolLayer::getTextOptional() const { - return impl->layout.textOptional.get(); -} - -void SymbolLayer::setTextOptional(PropertyValue value) { - impl->layout.textOptional.set(value); -} - -// Paint properties - -PropertyValue SymbolLayer::getIconOpacity() const { - return impl->paint.iconOpacity.get(); -} - -void SymbolLayer::setIconOpacity(PropertyValue value) { - impl->paint.iconOpacity.set(value); -} - -PropertyValue SymbolLayer::getIconColor() const { - return impl->paint.iconColor.get(); -} - -void SymbolLayer::setIconColor(PropertyValue value) { - impl->paint.iconColor.set(value); -} - -PropertyValue SymbolLayer::getIconHaloColor() const { - return impl->paint.iconHaloColor.get(); -} - -void SymbolLayer::setIconHaloColor(PropertyValue value) { - impl->paint.iconHaloColor.set(value); -} - -PropertyValue SymbolLayer::getIconHaloWidth() const { - return impl->paint.iconHaloWidth.get(); -} - -void SymbolLayer::setIconHaloWidth(PropertyValue value) { - impl->paint.iconHaloWidth.set(value); -} - -PropertyValue SymbolLayer::getIconHaloBlur() const { - return impl->paint.iconHaloBlur.get(); -} - -void SymbolLayer::setIconHaloBlur(PropertyValue value) { - impl->paint.iconHaloBlur.set(value); -} - -PropertyValue> SymbolLayer::getIconTranslate() const { - return impl->paint.iconTranslate.get(); -} - -void SymbolLayer::setIconTranslate(PropertyValue> value) { - impl->paint.iconTranslate.set(value); -} - -PropertyValue SymbolLayer::getIconTranslateAnchor() const { - return impl->paint.iconTranslateAnchor.get(); -} - -void SymbolLayer::setIconTranslateAnchor(PropertyValue value) { - impl->paint.iconTranslateAnchor.set(value); -} - -PropertyValue SymbolLayer::getTextOpacity() const { - return impl->paint.textOpacity.get(); -} - -void SymbolLayer::setTextOpacity(PropertyValue value) { - impl->paint.textOpacity.set(value); -} - -PropertyValue SymbolLayer::getTextColor() const { - return impl->paint.textColor.get(); -} - -void SymbolLayer::setTextColor(PropertyValue value) { - impl->paint.textColor.set(value); -} - -PropertyValue SymbolLayer::getTextHaloColor() const { - return impl->paint.textHaloColor.get(); -} - -void SymbolLayer::setTextHaloColor(PropertyValue value) { - impl->paint.textHaloColor.set(value); -} - -PropertyValue SymbolLayer::getTextHaloWidth() const { - return impl->paint.textHaloWidth.get(); -} - -void SymbolLayer::setTextHaloWidth(PropertyValue value) { - impl->paint.textHaloWidth.set(value); -} - -PropertyValue SymbolLayer::getTextHaloBlur() const { - return impl->paint.textHaloBlur.get(); -} - -void SymbolLayer::setTextHaloBlur(PropertyValue value) { - impl->paint.textHaloBlur.set(value); -} - -PropertyValue> SymbolLayer::getTextTranslate() const { - return impl->paint.textTranslate.get(); -} - -void SymbolLayer::setTextTranslate(PropertyValue> value) { - impl->paint.textTranslate.set(value); -} - -PropertyValue SymbolLayer::getTextTranslateAnchor() const { - return impl->paint.textTranslateAnchor.get(); -} - -void SymbolLayer::setTextTranslateAnchor(PropertyValue value) { - impl->paint.textTranslateAnchor.set(value); -} - -} // namespace mbgl diff --git a/src/mbgl/layer/symbol_layer_impl.cpp b/src/mbgl/layer/symbol_layer_impl.cpp deleted file mode 100644 index 3a0e0dceca..0000000000 --- a/src/mbgl/layer/symbol_layer_impl.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include - -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 SymbolLayer::Impl::createBucket(StyleBucketParameters& parameters) const { - auto bucket = std::make_unique(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 deleted file mode 100644 index 46503ab916..0000000000 --- a/src/mbgl/layer/symbol_layer_impl.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MBGL_SYMBOL_LAYER -#define MBGL_SYMBOL_LAYER - -#include -#include -#include - -namespace mbgl { - -class SpriteAtlas; - -class SymbolLayer::Impl : public Layer::Impl { -public: - std::unique_ptr 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 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 deleted file mode 100644 index 4b9e9a5fb6..0000000000 --- a/src/mbgl/layer/symbol_layer_properties.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#include - -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_properties.hpp b/src/mbgl/layer/symbol_layer_properties.hpp deleted file mode 100644 index ccbecef00e..0000000000 --- a/src/mbgl/layer/symbol_layer_properties.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. - -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleCascadeParameters; -class StyleCalculationParameters; - -class SymbolLayoutProperties { -public: - void parse(const JSValue&); - void recalculate(const StyleCalculationParameters&); - - LayoutProperty symbolPlacement { SymbolPlacementType::Point }; - LayoutProperty symbolSpacing { 250 }; - LayoutProperty symbolAvoidEdges { false }; - LayoutProperty iconAllowOverlap { false }; - LayoutProperty iconIgnorePlacement { false }; - LayoutProperty iconOptional { false }; - LayoutProperty iconRotationAlignment { RotationAlignmentType::Viewport }; - LayoutProperty iconSize { 1 }; - LayoutProperty iconImage { "" }; - LayoutProperty iconRotate { 0 }; - LayoutProperty iconPadding { 2 }; - LayoutProperty iconKeepUpright { false }; - LayoutProperty> iconOffset { {{ 0, 0 }} }; - LayoutProperty textRotationAlignment { RotationAlignmentType::Viewport }; - LayoutProperty textField { "" }; - LayoutProperty> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } }; - LayoutProperty textSize { 16 }; - LayoutProperty textMaxWidth { 10 }; - LayoutProperty textLineHeight { 1.2 }; - LayoutProperty textLetterSpacing { 0 }; - LayoutProperty textJustify { TextJustifyType::Center }; - LayoutProperty textAnchor { TextAnchorType::Center }; - LayoutProperty textMaxAngle { 45 }; - LayoutProperty textRotate { 0 }; - LayoutProperty textPadding { 2 }; - LayoutProperty textKeepUpright { true }; - LayoutProperty textTransform { TextTransformType::None }; - LayoutProperty> textOffset { {{ 0, 0 }} }; - LayoutProperty textAllowOverlap { false }; - LayoutProperty textIgnorePlacement { false }; - LayoutProperty textOptional { false }; -}; - -class SymbolPaintProperties { -public: - void parse(const JSValue&); - void cascade(const StyleCascadeParameters&); - bool recalculate(const StyleCalculationParameters&); - - PaintProperty iconOpacity { 1 }; - PaintProperty iconColor { {{ 0, 0, 0, 1 }} }; - PaintProperty iconHaloColor { {{ 0, 0, 0, 0 }} }; - PaintProperty iconHaloWidth { 0 }; - PaintProperty iconHaloBlur { 0 }; - PaintProperty> iconTranslate { {{ 0, 0 }} }; - PaintProperty iconTranslateAnchor { TranslateAnchorType::Map }; - PaintProperty textOpacity { 1 }; - PaintProperty textColor { {{ 0, 0, 0, 1 }} }; - PaintProperty textHaloColor { {{ 0, 0, 0, 0 }} }; - PaintProperty textHaloWidth { 0 }; - PaintProperty textHaloBlur { 0 }; - PaintProperty> textTranslate { {{ 0, 0 }} }; - PaintProperty textTranslateAnchor { TranslateAnchorType::Map }; -}; - -} // namespace mbgl diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 4f1c4634ca..ec961a6485 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -5,11 +5,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include @@ -25,13 +25,15 @@ namespace mbgl { +using namespace style; + enum class RenderState { never, partial, fully }; -class Map::Impl : public StyleObserver { +class Map::Impl : public style::Observer { public: Impl(View&, FileSource&, MapMode, GLContextMode, ConstrainMode, ViewportMode); @@ -221,17 +223,17 @@ void Map::Impl::update() { style->recalculate(transform.getZoom(), timePoint, mode); } - StyleUpdateParameters parameters(pixelRatio, - debugOptions, - timePoint, - transform.getState(), - style->workers, - fileSource, - *texturePool, - style->shouldReparsePartialTiles, - mode, - *annotationManager, - *style); + style::UpdateParameters parameters(pixelRatio, + debugOptions, + timePoint, + transform.getState(), + style->workers, + fileSource, + *texturePool, + style->shouldReparsePartialTiles, + mode, + *annotationManager, + *style); style->update(parameters); @@ -799,19 +801,19 @@ bool Map::isFullyLoaded() const { return impl->style->isLoaded(); } -void Map::addClass(const std::string& className, const PropertyTransition& properties) { +void Map::addClass(const std::string& className, const TransitionOptions& properties) { if (impl->style->addClass(className, properties)) { update(Update::Classes); } } -void Map::removeClass(const std::string& className, const PropertyTransition& properties) { +void Map::removeClass(const std::string& className, const TransitionOptions& properties) { if (impl->style->removeClass(className, properties)) { update(Update::Classes); } } -void Map::setClasses(const std::vector& classNames, const PropertyTransition& properties) { +void Map::setClasses(const std::vector& classNames, const TransitionOptions& properties) { impl->style->setClasses(classNames, properties); update(Update::Classes); } diff --git a/src/mbgl/map/zoom_history.hpp b/src/mbgl/map/zoom_history.hpp new file mode 100644 index 0000000000..8c88ea6507 --- /dev/null +++ b/src/mbgl/map/zoom_history.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +#include + +namespace mbgl { + +struct ZoomHistory { + float lastZoom; + float lastIntegerZoom; + TimePoint lastIntegerZoomTime; + bool first = true; + + void update(float z, const TimePoint& now) { + if (first) { + first = false; + + lastIntegerZoom = std::floor(z); + lastIntegerZoomTime = TimePoint(Duration::zero()); + lastZoom = z; + } + + if (std::floor(lastZoom) < std::floor(z)) { + lastIntegerZoom = std::floor(z); + lastIntegerZoomTime = now; + + } else if (std::floor(lastZoom) > std::floor(z)) { + lastIntegerZoom = std::floor(z + 1); + lastIntegerZoomTime = now; + } + + lastZoom = z; + } +}; +} // namespace mbgl diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 89b0ceefb2..c7ebe480ed 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -13,7 +13,6 @@ namespace mbgl { class Painter; -class Layer; class UnwrappedTileID; class CollisionTile; @@ -21,6 +20,10 @@ namespace gl { class ObjectStore; } +namespace style { +class Layer; +} + class Bucket : private util::noncopyable { public: Bucket() : uploaded(false) {} @@ -31,7 +34,7 @@ public: // Every time this bucket is getting rendered, this function is called. This happens either // once or twice (for Opaque and Transparent render passes). - virtual void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) = 0; + virtual void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) = 0; virtual ~Bucket() = default; diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp index 969e05131b..4ae63fed46 100644 --- a/src/mbgl/renderer/circle_bucket.cpp +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -2,10 +2,12 @@ #include #include -#include +#include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; CircleBucket::CircleBucket(MapMode mode_) : mode(mode_) { } @@ -97,3 +99,5 @@ void CircleBucket::drawCircles(CircleShader& shader, gl::ObjectStore& store) { elementsIndex += group->elements_length * elementsBuffer_.itemSize; } } + +} diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index 9c95fce045..fa34aa088a 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -19,7 +19,7 @@ public: ~CircleBucket() override; void upload(gl::ObjectStore&) override; - void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override; + void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 4a9709f4e8..02f346decb 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -12,22 +12,24 @@ #include -struct GeometryTooLongException : std::exception {}; - -using namespace mbgl; - namespace mapbox { namespace util { -template <> struct nth<0, GeometryCoordinate> { - inline static int64_t get(const GeometryCoordinate& t) { return t.x; }; +template <> struct nth<0, mbgl::GeometryCoordinate> { + inline static int64_t get(const mbgl::GeometryCoordinate& t) { return t.x; }; }; -template <> struct nth<1, GeometryCoordinate> { - inline static int64_t get(const GeometryCoordinate& t) { return t.y; }; +template <> struct nth<1, mbgl::GeometryCoordinate> { + inline static int64_t get(const mbgl::GeometryCoordinate& t) { return t.y; }; }; } } +namespace mbgl { + +using namespace style; + +struct GeometryTooLongException : std::exception {}; + FillBucket::FillBucket() { } @@ -165,3 +167,5 @@ void FillBucket::drawVertices(OutlinePatternShader& shader, gl::ObjectStore& sto elements_index += group->elements_length * lineElementsBuffer.itemSize; } } + +} diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index 21e3239f29..35d70d169c 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -21,7 +21,7 @@ public: ~FillBucket() override; void upload(gl::ObjectStore&) override; - void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override; + void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 8124a5daed..d207cdb8c5 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -11,7 +11,9 @@ #include -using namespace mbgl; +namespace mbgl { + +using namespace style; LineBucket::LineBucket(uint32_t overscaling_) : overscaling(overscaling_) { } @@ -505,3 +507,5 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader, gl::ObjectStore& st elements_index += group->elements_length * triangleElementsBuffer.itemSize; } } + +} diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 1093ec2a48..d746f29c7e 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -5,13 +5,12 @@ #include #include #include -#include +#include #include namespace mbgl { -class Style; class LineVertexBuffer; class TriangleElementsBuffer; class LineShader; @@ -26,7 +25,7 @@ public: ~LineBucket() override; void upload(gl::ObjectStore&) override; - void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override; + void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; @@ -50,7 +49,7 @@ private: std::vector& triangleStore); public: - LineLayoutProperties layout; + style::LineLayoutProperties layout; private: LineVertexBuffer vertexBuffer; diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index ccc6e23408..1864bf7ef1 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -1,18 +1,17 @@ #include -#include +#include #include #include #include #include -#include -#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -46,7 +45,9 @@ #include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; Painter::Painter(const TransformState& state_, gl::ObjectStore& store_) : state(state_), @@ -308,3 +309,5 @@ void Painter::setDepthSublayer(int n) { float farDepth = nearDepth + depthRangeSize; config.depthRange = { nearDepth, farDepth }; } + +} diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index ad26457555..f040fee67f 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include @@ -28,27 +28,19 @@ namespace mbgl { -class Style; class Tile; class SpriteAtlas; class GlyphAtlas; class LineAtlas; -class Source; struct FrameData; class TileData; class DebugBucket; class FillBucket; -class FillLayer; class LineBucket; -class LineLayer; class CircleBucket; -class CircleLayer; class SymbolBucket; -class SymbolLayer; class RasterBucket; -class RasterLayer; -class BackgroundLayer; class SDFShader; class PlainShader; @@ -72,6 +64,17 @@ namespace util { class ObjectStore; } +namespace style { +class Style; +class Source; +class FillLayer; +class LineLayer; +class CircleLayer; +class SymbolLayer; +class RasterLayer; +class BackgroundLayer; +} + struct FrameData { std::array framebufferSize; TimePoint timePoint; @@ -86,8 +89,8 @@ public: Painter(const TransformState&, gl::ObjectStore&); ~Painter(); - void render(const Style& style, - const FrameData& frame, + void render(const style::Style&, + const FrameData&, SpriteAtlas& annotationSpriteAtlas); // Renders debug information for a tile. @@ -99,12 +102,12 @@ public: void renderClipMasks(); void renderDebugText(TileData&, const mat4&); - void renderFill(FillBucket&, const FillLayer&, const UnwrappedTileID&, const mat4&); - void renderLine(LineBucket&, const LineLayer&, const UnwrappedTileID&, const mat4&); - void renderCircle(CircleBucket&, const CircleLayer&, const UnwrappedTileID&, const mat4&); - void renderSymbol(SymbolBucket&, const SymbolLayer&, const UnwrappedTileID&, const mat4&); - void renderRaster(RasterBucket&, const RasterLayer&, const UnwrappedTileID&, const mat4&); - void renderBackground(const BackgroundLayer&); + void renderFill(FillBucket&, const style::FillLayer&, const UnwrappedTileID&, const mat4&); + void renderLine(LineBucket&, const style::LineLayer&, const UnwrappedTileID&, const mat4&); + void renderCircle(CircleBucket&, const style::CircleLayer&, const UnwrappedTileID&, const mat4&); + void renderSymbol(SymbolBucket&, const style::SymbolLayer&, const UnwrappedTileID&, const mat4&); + void renderRaster(RasterBucket&, const style::RasterLayer&, const UnwrappedTileID&, const mat4&); + void renderBackground(const style::BackgroundLayer&); float saturationFactor(float saturation); float contrastFactor(float contrast); @@ -118,9 +121,9 @@ private: mat4 translatedMatrix(const mat4& matrix, const std::array& translation, const UnwrappedTileID& id, - TranslateAnchorType anchor); + style::TranslateAnchorType anchor); - std::vector determineRenderOrder(const Style& style); + std::vector determineRenderOrder(const style::Style&); template void renderPass(RenderPass, @@ -138,7 +141,7 @@ private: void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&), // Layout - RotationAlignmentType rotationAlignment, + style::RotationAlignmentType rotationAlignment, float layoutSize, // Paint @@ -148,7 +151,7 @@ private: float haloWidth, float haloBlur, std::array translate, - TranslateAnchorType translateAnchor, + style::TranslateAnchorType translateAnchor, float paintSize); void setDepthSublayer(int n); diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index bc01d3c32f..07e5821ce8 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -1,14 +1,16 @@ #include -#include -#include +#include +#include #include #include #include #include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderBackground(const BackgroundLayer& layer) { // Note that for bottommost layers without a pattern, the background color is drawn with @@ -107,3 +109,5 @@ void Painter::renderBackground(const BackgroundLayer& layer) { MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index())); } } + +} diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index c371f4debe..9f2cd17f7f 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -1,12 +1,14 @@ #include #include -#include -#include +#include +#include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderCircle(CircleBucket& bucket, const CircleLayer& layer, @@ -43,3 +45,5 @@ void Painter::renderCircle(CircleBucket& bucket, bucket.drawCircles(*circleShader, store); } + +} diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index f0fd498267..e6ce1a040e 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index b499d20da3..b89686c815 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -1,14 +1,16 @@ #include #include -#include -#include +#include +#include #include #include #include #include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, @@ -195,3 +197,5 @@ void Painter::renderFill(FillBucket& bucket, bucket.drawVertices(*outlineShader, store); } } + +} diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 3cf1ad4147..26041a8165 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -1,7 +1,7 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -9,7 +9,9 @@ #include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, @@ -161,3 +163,5 @@ void Painter::renderLine(LineBucket& bucket, bucket.drawLines(*lineShader, store); } } + +} diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index 511ac96387..cce71e8ce2 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -1,11 +1,13 @@ #include #include #include -#include -#include +#include +#include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderRaster(RasterBucket& bucket, const RasterLayer& layer, @@ -66,3 +68,5 @@ std::array Painter::spinWeights(float spin) { }}; return spin_weights; } + +} diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 9774568074..3c453242ae 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -1,6 +1,7 @@ #include #include -#include +#include +#include #include #include #include @@ -10,7 +11,9 @@ #include -using namespace mbgl; +namespace mbgl { + +using namespace style; void Painter::renderSDF(SymbolBucket &bucket, const UnwrappedTileID &tileID, @@ -257,3 +260,5 @@ void Painter::renderSymbol(SymbolBucket& bucket, config.activeTexture = GL_TEXTURE0; } + +} diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp index b16d7f8161..39f8dacd92 100644 --- a/src/mbgl/renderer/raster_bucket.cpp +++ b/src/mbgl/renderer/raster_bucket.cpp @@ -1,9 +1,11 @@ #include -#include +#include #include #include -using namespace mbgl; +namespace mbgl { + +using namespace style; RasterBucket::RasterBucket(gl::TexturePool& texturePool) : raster(texturePool) { @@ -40,3 +42,5 @@ bool RasterBucket::hasData() const { bool RasterBucket::needsClipping() const { return false; } + +} diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp index 9125ef2047..93331755fb 100644 --- a/src/mbgl/renderer/raster_bucket.hpp +++ b/src/mbgl/renderer/raster_bucket.hpp @@ -14,7 +14,7 @@ public: RasterBucket(gl::TexturePool&); void upload(gl::ObjectStore&) override; - void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override; + void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 67c8468ecd..f4e55432c1 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -31,6 +31,8 @@ namespace mbgl { +using namespace style; + SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, const Shaping& shapedText, const PositionedIcon& shapedIcon, const SymbolLayoutProperties& layout, const bool addToBuffers, const uint32_t index_, diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index b19a86b275..314d44bdee 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -46,7 +46,7 @@ class SymbolInstance { public: explicit SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, const Shaping& shapedText, const PositionedIcon& shapedIcon, - const SymbolLayoutProperties& layout, const bool inside, const uint32_t index, + const style::SymbolLayoutProperties&, const bool inside, const uint32_t index, const float textBoxScale, const float textPadding, const float textAlongLine, const float iconBoxScale, const float iconPadding, const float iconAlongLine, const GlyphPositions& face, const IndexedSubfeature& indexedfeature); @@ -70,7 +70,7 @@ public: ~SymbolBucket() override; void upload(gl::ObjectStore&) override; - void render(Painter&, const Layer&, const UnwrappedTileID&, const mat4&) override; + void render(Painter&, const style::Layer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool hasTextData() const; bool hasIconData() const; @@ -87,7 +87,7 @@ public: void drawIcons(IconShader&, gl::ObjectStore&); void drawCollisionBoxes(CollisionBoxShader&, gl::ObjectStore&); - void parseFeatures(const GeometryTileLayer&, const Filter&); + void parseFeatures(const GeometryTileLayer&, const style::Filter&); bool needsDependencies(GlyphStore&, SpriteStore&); void placeFeatures(CollisionTile&) override; @@ -109,7 +109,7 @@ private: const bool keepUpright, const bool alongLine, const float placementAngle); public: - SymbolLayoutProperties layout; + style::SymbolLayoutProperties layout; float iconMaxSize = 1.0f; float textMaxSize = 16.0f; diff --git a/src/mbgl/source/source.cpp b/src/mbgl/source/source.cpp deleted file mode 100644 index 66546909ac..0000000000 --- a/src/mbgl/source/source.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -#include -#include - -namespace mbgl { - -static SourceObserver nullObserver; - -Source::Source(SourceType type_, - const std::string& id_, - const std::string& url_, - uint16_t tileSize_, - std::unique_ptr&& info_, - std::unique_ptr&& geojsonvt_) - : type(type_), - id(id_), - url(url_), - tileSize(tileSize_), - info(std::move(info_)), - geojsonvt(std::move(geojsonvt_)), - observer(&nullObserver) { -} - -Source::~Source() = default; - -bool Source::isLoaded() const { - if (!loaded) return false; - - for (const auto& pair : tileDataMap) { - if (!pair.second->isComplete()) { - return false; - } - } - - return true; -} - -bool Source::isLoading() const { - return !loaded && req.operator bool(); -} - -void Source::load(FileSource& fileSource) { - if (url.empty()) { - // In case there is no URL set, we assume that we already have all of the data because the - // TileJSON was specified inline in the stylesheet. - loaded = true; - return; - } - - if (req) { - // We don't have a SourceInfo object yet, but there's already a request underway to load - // the data. - return; - } - - // URL may either be a TileJSON file, or a GeoJSON file. - req = fileSource.request(Resource::source(url), [this](Response res) { - if (res.error) { - observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message))); - } else if (res.notModified) { - return; - } else if (res.noContent) { - observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty source"))); - } else { - bool reloadTiles = false; - - if (type == SourceType::Vector || type == SourceType::Raster) { - std::unique_ptr newInfo; - - // Create a new copy of the SourceInfo object that holds the base values we've parsed - // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved - // via the URL. - try { - newInfo = StyleParser::parseTileJSON(*res.data, url, type, tileSize); - } catch (...) { - observer->onSourceError(*this, std::current_exception()); - return; - } - - // Check whether previous information specifies different tile - if (info && info->tiles != newInfo->tiles) { - reloadTiles = true; - - // Tile size changed: We need to recalculate the tiles we need to load because we - // might have to load tiles for a different zoom level - // This is done automatically when we trigger the onSourceLoaded observer below. - - // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles - // loaded that are outside the new zoom range - // This is done automatically when we trigger the onSourceLoaded observer below. - - // Attribution changed: We need to notify the embedding application that this - // changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723 - // This is not yet implemented. - - // Center/bounds changed: We're not using these values currently - } - - info = std::move(newInfo); - } else if (type == SourceType::GeoJSON) { - std::unique_ptr newInfo = std::make_unique(); - - rapidjson::GenericDocument, rapidjson::CrtAllocator> d; - d.Parse<0>(res.data->c_str()); - - if (d.HasParseError()) { - std::stringstream message; - message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError()); - observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str()))); - return; - } - - geojsonvt = StyleParser::parseGeoJSON(d); - reloadTiles = true; - - newInfo->maxZoom = geojsonvt->options.maxZoom; - info = std::move(newInfo); - } - - if (reloadTiles) { - // Tile information changed because we got new GeoJSON data, or a new tile URL. - tileDataMap.clear(); - tiles.clear(); - cache.clear(); - } - - loaded = true; - observer->onSourceLoaded(*this); - } - }); -} - -void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) { - for (auto& pair : tiles) { - auto& tile = pair.second; - transform.matrixFor(tile.matrix, tile.id); - matrix::multiply(tile.matrix, projMatrix, tile.matrix); - } -} - -void Source::finishRender(Painter &painter) { - for (auto& pair : tiles) { - auto& tile = pair.second; - painter.renderTileDebug(tile); - } -} - -const std::map& Source::getTiles() const { - return tiles; -} - -std::unique_ptr Source::createTile(const OverscaledTileID& overscaledTileID, - const StyleUpdateParameters& parameters) { - std::unique_ptr data = cache.get(overscaledTileID); - if (data) { - return data; - } - - auto callback = std::bind(&Source::tileLoadingCallback, this, overscaledTileID, - std::placeholders::_1, true); - - // If we don't find working tile data, we're just going to load it. - if (type == SourceType::Raster) { - data = std::make_unique(overscaledTileID, parameters.pixelRatio, - info->tiles.at(0), parameters.texturePool, - parameters.worker, parameters.fileSource, callback); - } else { - std::unique_ptr monitor; - - if (type == SourceType::Vector) { - monitor = std::make_unique(overscaledTileID, parameters.pixelRatio, info->tiles.at(0), parameters.fileSource); - } else if (type == SourceType::Annotations) { - monitor = std::make_unique(overscaledTileID, parameters.annotationManager); - } else if (type == SourceType::GeoJSON) { - monitor = std::make_unique(geojsonvt.get(), overscaledTileID); - } else { - Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(type).c_str()); - return nullptr; - } - - data = std::make_unique(overscaledTileID, std::move(monitor), id, - parameters.style, parameters.mode, callback); - } - - return data; -} - -TileData* Source::getTileData(const OverscaledTileID& overscaledTileID) const { - auto it = tileDataMap.find(overscaledTileID); - if (it != tileDataMap.end()) { - return it->second.get(); - } else { - return nullptr; - } -} - -bool Source::update(const StyleUpdateParameters& parameters) { - bool allTilesUpdated = true; - - if (!loaded || parameters.animationTime <= updated) { - return allTilesUpdated; - } - - // Determine the overzooming/underzooming amounts and required tiles. - int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); - int32_t dataTileZoom = overscaledZoom; - - std::vector idealTiles; - if (overscaledZoom >= info->minZoom) { - int32_t idealZoom = std::min(info->maxZoom, overscaledZoom); - - // Make sure we're not reparsing overzoomed raster tiles. - if (type == SourceType::Raster) { - dataTileZoom = idealZoom; - } - - idealTiles = util::tileCover(parameters.transformState, idealZoom); - } - - // Stores a list of all the data tiles that we're definitely going to retain. There are two - // kinds of tiles we need: the ideal tiles determined by the tile cover. They may not yet be in - // use because they're still loading. In addition to that, we also need to retain all tiles that - // we're actively using, e.g. as a replacement for tile that aren't loaded yet. - std::set retain; - - auto retainTileDataFn = [&retain](const TileData& tileData) -> void { - retain.emplace(tileData.id); - }; - auto getTileDataFn = [this](const OverscaledTileID& dataTileID) -> TileData* { - return getTileData(dataTileID); - }; - auto createTileDataFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> TileData* { - if (auto data = createTile(dataTileID, parameters)) { - return tileDataMap.emplace(dataTileID, std::move(data)).first->second.get(); - } else { - return nullptr; - } - }; - auto renderTileFn = [this](const UnwrappedTileID& renderTileID, TileData& tileData) { - tiles.emplace(renderTileID, Tile{ renderTileID, tileData }); - }; - - tiles.clear(); - algorithm::updateRenderables(getTileDataFn, createTileDataFn, retainTileDataFn, renderTileFn, - idealTiles, *info, dataTileZoom); - - if (type != SourceType::Raster && type != SourceType::Annotations && cache.getSize() == 0) { - size_t conservativeCacheSize = - ((float)parameters.transformState.getWidth() / util::tileSize) * - ((float)parameters.transformState.getHeight() / util::tileSize) * - (parameters.transformState.getMaxZoom() - parameters.transformState.getMinZoom() + 1) * - 0.5; - cache.setSize(conservativeCacheSize); - } - - // Remove stale data tiles from the active set of tiles. - // This goes through the (sorted!) tileDataMap and retain set in lockstep and removes items from - // tileDataMap that don't have the corresponding key in the retain set. - auto dataIt = tileDataMap.begin(); - auto retainIt = retain.begin(); - while (dataIt != tileDataMap.end()) { - if (retainIt == retain.end() || dataIt->first < *retainIt) { - cache.add(dataIt->first, std::move(dataIt->second)); - tileDataMap.erase(dataIt++); - } else { - if (!(*retainIt < dataIt->first)) { - ++dataIt; - } - ++retainIt; - } - } - - for (auto& pair : tileDataMap) { - const auto& dataTileID = pair.first; - auto tileData = pair.second.get(); - if (parameters.shouldReparsePartialTiles && tileData->isIncomplete()) { - auto callback = std::bind(&Source::tileLoadingCallback, this, dataTileID, - std::placeholders::_1, false); - - if (!tileData->parsePending(callback)) { - allTilesUpdated = false; - } - } else { - tileData->redoPlacement({ parameters.transformState.getAngle(), - parameters.transformState.getPitch(), - parameters.debugOptions & MapDebugOptions::Collision }, - [this]() { observer->onPlacementRedone(); }); - } - } - - updated = parameters.animationTime; - - return allTilesUpdated; -} - -static Point coordinateToTilePoint(const UnwrappedTileID& tileID, const Point& p) { - auto zoomedCoord = TileCoordinate { p, 0 }.zoomTo(tileID.canonical.z); - return { - int16_t(util::clamp((zoomedCoord.p.x - tileID.canonical.x - tileID.wrap * std::pow(2, tileID.canonical.z)) * util::EXTENT, - std::numeric_limits::min(), - std::numeric_limits::max())), - int16_t(util::clamp((zoomedCoord.p.y - tileID.canonical.y) * util::EXTENT, - std::numeric_limits::min(), - std::numeric_limits::max())) - }; -} - -std::unordered_map> Source::queryRenderedFeatures(const StyleQueryParameters& parameters) const { - LineString queryGeometry; - - for (const auto& p : parameters.geometry) { - queryGeometry.push_back(TileCoordinate::fromScreenCoordinate( - parameters.transformState, 0, { p.x, parameters.transformState.getHeight() - p.y }).p); - } - - mapbox::geometry::box box = mapbox::geometry::envelope(queryGeometry); - - std::unordered_map> result; - - for (const auto& tilePtr : tiles) { - const Tile& tile = tilePtr.second; - - Point tileSpaceBoundsMin = coordinateToTilePoint(tile.id, box.min); - Point tileSpaceBoundsMax = coordinateToTilePoint(tile.id, box.max); - - if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT || - tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) continue; - - GeometryCoordinates tileSpaceQueryGeometry; - - for (const auto& c : queryGeometry) { - tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c)); - } - - tile.data.queryRenderedFeatures(result, - tileSpaceQueryGeometry, - parameters.transformState, - parameters.layerIDs); - } - - return result; -} - -void Source::setCacheSize(size_t size) { - cache.setSize(size); -} - -void Source::onLowMemory() { - cache.clear(); -} - -void Source::setObserver(SourceObserver* observer_) { - observer = observer_; -} - -void Source::tileLoadingCallback(const OverscaledTileID& tileID, - std::exception_ptr error, - bool isNewTile) { - auto it = tileDataMap.find(tileID); - if (it == tileDataMap.end()) { - return; - } - - auto& tileData = it->second; - if (!tileData) { - return; - } - - if (error) { - observer->onTileError(*this, tileID, error); - return; - } - - tileData->redoPlacement([this]() { - observer->onPlacementRedone(); - }); - observer->onTileLoaded(*this, tileID, isNewTile); -} - -void Source::dumpDebugLogs() const { - Log::Info(Event::General, "Source::id: %s", id.c_str()); - Log::Info(Event::General, "Source::loaded: %d", loaded); - - for (const auto& pair : tileDataMap) { - auto& tileData = pair.second; - tileData->dumpDebugLogs(); - } -} - -} // namespace mbgl diff --git a/src/mbgl/source/source.hpp b/src/mbgl/source/source.hpp deleted file mode 100644 index cbdf4afa15..0000000000 --- a/src/mbgl/source/source.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -namespace mapbox { -namespace geojsonvt { -class GeoJSONVT; -} // namespace geojsonvt -} // namespace mapbox - -namespace mbgl { - -class Style; -class StyleUpdateParameters; -class StyleQueryParameters; -class Painter; -class FileSource; -class AsyncRequest; -class TransformState; -class Tile; -struct ClipID; -class SourceObserver; - -class Source : private util::noncopyable { -public: - Source(SourceType, - const std::string& id, - const std::string& url, - uint16_t tileSize, - std::unique_ptr&&, - std::unique_ptr&&); - ~Source(); - - bool loaded = false; - void load(FileSource&); - bool isLoading() const; - bool isLoaded() const; - - const SourceInfo* getInfo() const { return info.get(); } - - // Request or parse all the tiles relevant for the "TransformState". This method - // will return true if all the tiles were scheduled for updating of false if - // they were not. shouldReparsePartialTiles must be set to "true" if there is - // new data available that a tile in the "partial" state might be interested at. - bool update(const StyleUpdateParameters&); - - template - void updateClipIDs(ClipIDGenerator& generator) { - generator.update(tiles); - } - - void updateMatrices(const mat4 &projMatrix, const TransformState &transform); - void finishRender(Painter &painter); - - const std::map& getTiles() const; - - TileData* getTileData(const OverscaledTileID&) const; - - std::unordered_map> - queryRenderedFeatures(const StyleQueryParameters&) const; - - void setCacheSize(size_t); - void onLowMemory(); - - void setObserver(SourceObserver* observer); - void dumpDebugLogs() const; - - const SourceType type; - const std::string id; - const std::string url; - uint16_t tileSize = util::tileSize; - bool enabled = false; - -private: - void tileLoadingCallback(const OverscaledTileID&, std::exception_ptr, bool isNewTile); - - std::unique_ptr createTile(const OverscaledTileID&, - const StyleUpdateParameters& parameters); - -private: - std::unique_ptr info; - - std::unique_ptr geojsonvt; - - // Stores the time when this source was most recently updated. - TimePoint updated = TimePoint::min(); - - std::map tiles; - std::map> tileDataMap; - TileCache cache; - - std::unique_ptr req; - - SourceObserver* observer = nullptr; -}; - -} // namespace mbgl diff --git a/src/mbgl/source/source_info.hpp b/src/mbgl/source/source_info.hpp deleted file mode 100644 index dc79695dc9..0000000000 --- a/src/mbgl/source/source_info.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include - -namespace mbgl { - -class TileID; - -class SourceInfo { -public: - std::vector tiles; - uint8_t minZoom = 0; - uint8_t maxZoom = 22; - std::string attribution; - LatLng center; - double zoom = 0; - LatLngBounds bounds = LatLngBounds::world(); -}; - -} // namespace mbgl diff --git a/src/mbgl/source/source_observer.hpp b/src/mbgl/source/source_observer.hpp deleted file mode 100644 index 828e562a3e..0000000000 --- a/src/mbgl/source/source_observer.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -namespace mbgl { - -class Source; -class OverscaledTileID; - -class SourceObserver { -public: - virtual ~SourceObserver() = default; - - virtual void onSourceLoaded(Source&) {} - virtual void onSourceError(Source&, std::exception_ptr) {} - virtual void onTileLoaded(Source&, const OverscaledTileID&, bool /* isNewTile */) {} - virtual void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) {} - virtual void onPlacementRedone() {} -}; - -} // namespace mbgl diff --git a/src/mbgl/style/bucket_parameters.cpp b/src/mbgl/style/bucket_parameters.cpp new file mode 100644 index 0000000000..f3367d57e1 --- /dev/null +++ b/src/mbgl/style/bucket_parameters.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +namespace mbgl { +namespace style { + +void BucketParameters::eachFilteredFeature(const Filter& filter, + std::function function) { + auto name = layer.getName(); + for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) { + auto feature = layer.getFeature(i); + + FilterEvaluator evaluator(*feature); + if (!Filter::visit(filter, evaluator)) + continue; + + function(*feature, i, name); + } +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/bucket_parameters.hpp b/src/mbgl/style/bucket_parameters.hpp new file mode 100644 index 0000000000..f85e1e17ef --- /dev/null +++ b/src/mbgl/style/bucket_parameters.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace mbgl { + +class TileID; +class GeometryTileLayer; +class GeometryTileFeature; +class SpriteStore; +class GlyphAtlas; +class GlyphStore; +class CollisionTile; +class FeatureIndex; + +namespace style { + +class BucketParameters { +public: + BucketParameters(const OverscaledTileID& tileID_, + const GeometryTileLayer& layer_, + const std::atomic& obsolete_, + uintptr_t tileUID_, + bool& partialParse_, + SpriteStore& spriteStore_, + GlyphAtlas& glyphAtlas_, + GlyphStore& glyphStore_, + FeatureIndex& featureIndex_, + const MapMode mode_) + : tileID(tileID_), + layer(layer_), + obsolete(obsolete_), + tileUID(tileUID_), + partialParse(partialParse_), + spriteStore(spriteStore_), + glyphAtlas(glyphAtlas_), + glyphStore(glyphStore_), + featureIndex(featureIndex_), + mode(mode_) {} + + bool cancelled() const { + return obsolete; + } + + void eachFilteredFeature(const Filter&, std::function); + + const OverscaledTileID& tileID; + const GeometryTileLayer& layer; + const std::atomic& obsolete; + uintptr_t tileUID; + bool& partialParse; + SpriteStore& spriteStore; + GlyphAtlas& glyphAtlas; + GlyphStore& glyphStore; + FeatureIndex& featureIndex; + const MapMode mode; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/calculation_parameters.hpp b/src/mbgl/style/calculation_parameters.hpp new file mode 100644 index 0000000000..2afd7c4b34 --- /dev/null +++ b/src/mbgl/style/calculation_parameters.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +namespace mbgl { +namespace style { + +class CalculationParameters { +public: + explicit CalculationParameters(float z_) + : z(z_) {} + + CalculationParameters(float z_, + const TimePoint& now_, + const ZoomHistory& zoomHistory_, + const Duration& defaultFadeDuration_) + : z(z_), + now(now_), + zoomHistory(zoomHistory_), + defaultFadeDuration(defaultFadeDuration_) {} + + float z; + TimePoint now; + ZoomHistory zoomHistory; + Duration defaultFadeDuration; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/cascade_parameters.hpp b/src/mbgl/style/cascade_parameters.hpp new file mode 100644 index 0000000000..4ad6da2ce3 --- /dev/null +++ b/src/mbgl/style/cascade_parameters.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +#include + +namespace mbgl { +namespace style { + +class TransitionOptions; + +class CascadeParameters { +public: + std::vector classes; + TimePoint now; + TransitionOptions transition; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/class_dictionary.cpp b/src/mbgl/style/class_dictionary.cpp index 53ea5c1484..ec06ee7d9d 100644 --- a/src/mbgl/style/class_dictionary.cpp +++ b/src/mbgl/style/class_dictionary.cpp @@ -3,6 +3,7 @@ #include namespace mbgl { +namespace style { ClassDictionary::ClassDictionary() {} @@ -46,4 +47,5 @@ ClassID ClassDictionary::normalize(ClassID id) { } } +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/class_dictionary.hpp b/src/mbgl/style/class_dictionary.hpp index 703e27b438..c95773d7c3 100644 --- a/src/mbgl/style/class_dictionary.hpp +++ b/src/mbgl/style/class_dictionary.hpp @@ -5,6 +5,7 @@ #include namespace mbgl { +namespace style { enum class ClassID : uint32_t { Fallback = 0, // These values are from the fallback properties @@ -31,4 +32,5 @@ private: uint32_t offset = 0; }; +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/filter_evaluator.hpp b/src/mbgl/style/filter_evaluator.hpp index b607a0c658..e03beaa4d0 100644 --- a/src/mbgl/style/filter_evaluator.hpp +++ b/src/mbgl/style/filter_evaluator.hpp @@ -6,6 +6,7 @@ #include namespace mbgl { +namespace style { class FilterEvaluator { public: @@ -159,3 +160,4 @@ private: }; } // namespace mbgl +} // namespace mbgl diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp new file mode 100644 index 0000000000..342699a2c9 --- /dev/null +++ b/src/mbgl/style/layer.cpp @@ -0,0 +1,50 @@ +#include +#include + +namespace mbgl { +namespace style { + +Layer::Layer(Type type_, std::unique_ptr 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; +} + +float Layer::getMinZoom() const { + return baseImpl->minZoom; +} + +void Layer::setMinZoom(float minZoom) const { + baseImpl->minZoom = minZoom; +} + +float Layer::getMaxZoom() const { + return baseImpl->maxZoom; +} + +void Layer::setMaxZoom(float maxZoom) const { + baseImpl->maxZoom = maxZoom; +} + +std::unique_ptr Layer::copy(const std::string& id, + const std::string& ref) const { + std::unique_ptr result = baseImpl->clone(); + result->baseImpl->id = id; + result->baseImpl->ref = ref; + return result; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layer_impl.cpp b/src/mbgl/style/layer_impl.cpp new file mode 100644 index 0000000000..74cc80d253 --- /dev/null +++ b/src/mbgl/style/layer_impl.cpp @@ -0,0 +1,19 @@ +#include + +namespace mbgl { +namespace style { + +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 style +} // namespace mbgl diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp new file mode 100644 index 0000000000..dcd5d9906b --- /dev/null +++ b/src/mbgl/style/layer_impl.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace mbgl { + +class Bucket; + +namespace style { + +class CascadeParameters; +class CalculationParameters; +class BucketParameters; + +/** + * `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 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 CascadeParameters&) = 0; + + // Fully evaluate cascaded paint properties based on a zoom level. + // Returns true if any paint properties have active transitions. + virtual bool recalculate(const CalculationParameters&) = 0; + + virtual std::unique_ptr createBucket(BucketParameters&) 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::infinity(); + float maxZoom = std::numeric_limits::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 style +} // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp new file mode 100644 index 0000000000..aeb4067503 --- /dev/null +++ b/src/mbgl/style/layers/background_layer.cpp @@ -0,0 +1,57 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +BackgroundLayer::BackgroundLayer(const std::string& layerID) + : Layer(Type::Background, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +BackgroundLayer::BackgroundLayer(const Impl& other) + : Layer(Type::Background, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +BackgroundLayer::~BackgroundLayer() = default; + +std::unique_ptr BackgroundLayer::Impl::clone() const { + return std::make_unique(*this); +} + + +// Layout properties + + +// Paint properties + +PropertyValue BackgroundLayer::getBackgroundColor() const { + return impl->paint.backgroundColor.get(); +} + +void BackgroundLayer::setBackgroundColor(PropertyValue value) { + impl->paint.backgroundColor.set(value); +} + +PropertyValue BackgroundLayer::getBackgroundPattern() const { + return impl->paint.backgroundPattern.get(); +} + +void BackgroundLayer::setBackgroundPattern(PropertyValue value) { + impl->paint.backgroundPattern.set(value); +} + +PropertyValue BackgroundLayer::getBackgroundOpacity() const { + return impl->paint.backgroundOpacity.get(); +} + +void BackgroundLayer::setBackgroundOpacity(PropertyValue value) { + impl->paint.backgroundOpacity.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp new file mode 100644 index 0000000000..0c09c5d158 --- /dev/null +++ b/src/mbgl/style/layers/background_layer_impl.cpp @@ -0,0 +1,28 @@ +#include +#include + +namespace mbgl { +namespace style { + +void BackgroundLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void BackgroundLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool BackgroundLayer::Impl::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = paint.recalculate(parameters); + + passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None; + + return hasTransitions; +} + +std::unique_ptr BackgroundLayer::Impl::createBucket(BucketParameters&) const { + return nullptr; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp new file mode 100644 index 0000000000..19e2a062a4 --- /dev/null +++ b/src/mbgl/style/layers/background_layer_impl.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class BackgroundLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override {}; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + BackgroundPaintProperties paint; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp new file mode 100644 index 0000000000..a20cedf12c --- /dev/null +++ b/src/mbgl/style/layers/background_layer_properties.cpp @@ -0,0 +1,31 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void BackgroundPaintProperties::parse(const JSValue& value) { + backgroundColor.parse("background-color", value); + backgroundPattern.parse("background-pattern", value); + backgroundOpacity.parse("background-opacity", value); +} + +void BackgroundPaintProperties::cascade(const CascadeParameters& parameters) { + backgroundColor.cascade(parameters); + backgroundPattern.cascade(parameters); + backgroundOpacity.cascade(parameters); +} + +bool BackgroundPaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= backgroundColor.calculate(parameters); + hasTransitions |= backgroundPattern.calculate(parameters); + hasTransitions |= backgroundOpacity.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp new file mode 100644 index 0000000000..a1a1a3a5a7 --- /dev/null +++ b/src/mbgl/style/layers/background_layer_properties.hpp @@ -0,0 +1,27 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class BackgroundPaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty backgroundColor { {{ 0, 0, 0, 1 }} }; + PaintProperty backgroundPattern { "" }; + PaintProperty backgroundOpacity { 1 }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp new file mode 100644 index 0000000000..bdfbf629e6 --- /dev/null +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -0,0 +1,105 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +CircleLayer::CircleLayer(const std::string& layerID) + : Layer(Type::Circle, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +CircleLayer::CircleLayer(const Impl& other) + : Layer(Type::Circle, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +CircleLayer::~CircleLayer() = default; + +std::unique_ptr CircleLayer::Impl::clone() const { + return std::make_unique(*this); +} + +// Source + +void CircleLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { + impl->source = sourceID; + impl->sourceLayer = sourceLayer; +} + +const std::string& CircleLayer::getSourceID() const { + return impl->source; +} + +const std::string& CircleLayer::getSourceLayer() const { + return impl->sourceLayer; +} + +// Filter + +void CircleLayer::setFilter(const Filter& filter) { + impl->filter = filter; +} + +const Filter& CircleLayer::getFilter() const { + return impl->filter; +} + +// Layout properties + + +// Paint properties + +PropertyValue CircleLayer::getCircleRadius() const { + return impl->paint.circleRadius.get(); +} + +void CircleLayer::setCircleRadius(PropertyValue value) { + impl->paint.circleRadius.set(value); +} + +PropertyValue CircleLayer::getCircleColor() const { + return impl->paint.circleColor.get(); +} + +void CircleLayer::setCircleColor(PropertyValue value) { + impl->paint.circleColor.set(value); +} + +PropertyValue CircleLayer::getCircleBlur() const { + return impl->paint.circleBlur.get(); +} + +void CircleLayer::setCircleBlur(PropertyValue value) { + impl->paint.circleBlur.set(value); +} + +PropertyValue CircleLayer::getCircleOpacity() const { + return impl->paint.circleOpacity.get(); +} + +void CircleLayer::setCircleOpacity(PropertyValue value) { + impl->paint.circleOpacity.set(value); +} + +PropertyValue> CircleLayer::getCircleTranslate() const { + return impl->paint.circleTranslate.get(); +} + +void CircleLayer::setCircleTranslate(PropertyValue> value) { + impl->paint.circleTranslate.set(value); +} + +PropertyValue CircleLayer::getCircleTranslateAnchor() const { + return impl->paint.circleTranslateAnchor.get(); +} + +void CircleLayer::setCircleTranslateAnchor(PropertyValue value) { + impl->paint.circleTranslateAnchor.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp new file mode 100644 index 0000000000..c2efac5cef --- /dev/null +++ b/src/mbgl/style/layers/circle_layer_impl.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +namespace mbgl { +namespace style { + +void CircleLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void CircleLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool CircleLayer::Impl::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = paint.recalculate(parameters); + + passes = (paint.circleRadius > 0 && paint.circleColor.value[3] > 0 && paint.circleOpacity > 0) + ? RenderPass::Translucent : RenderPass::None; + + return hasTransitions; +} + +std::unique_ptr CircleLayer::Impl::createBucket(BucketParameters& parameters) const { + auto bucket = std::make_unique(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& translate = paint.circleTranslate; + return paint.circleRadius + util::length(translate[0], translate[1]); +} + +bool CircleLayer::Impl::queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const { + + auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( + queryGeometry, paint.circleTranslate, paint.circleTranslateAnchor, bearing, pixelsToTileUnits); + + auto circleRadius = paint.circleRadius * pixelsToTileUnits; + + return util::multiPolygonIntersectsBufferedMultiPoint( + translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp new file mode 100644 index 0000000000..463f3ca18d --- /dev/null +++ b/src/mbgl/style/layers/circle_layer_impl.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CircleLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override {}; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + float getQueryRadius() const override; + bool queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const override; + + CirclePaintProperties paint; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp new file mode 100644 index 0000000000..b21df1e2d0 --- /dev/null +++ b/src/mbgl/style/layers/circle_layer_properties.cpp @@ -0,0 +1,40 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void CirclePaintProperties::parse(const JSValue& value) { + circleRadius.parse("circle-radius", value); + circleColor.parse("circle-color", value); + circleBlur.parse("circle-blur", value); + circleOpacity.parse("circle-opacity", value); + circleTranslate.parse("circle-translate", value); + circleTranslateAnchor.parse("circle-translate-anchor", value); +} + +void CirclePaintProperties::cascade(const CascadeParameters& parameters) { + circleRadius.cascade(parameters); + circleColor.cascade(parameters); + circleBlur.cascade(parameters); + circleOpacity.cascade(parameters); + circleTranslate.cascade(parameters); + circleTranslateAnchor.cascade(parameters); +} + +bool CirclePaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= circleRadius.calculate(parameters); + hasTransitions |= circleColor.calculate(parameters); + hasTransitions |= circleBlur.calculate(parameters); + hasTransitions |= circleOpacity.calculate(parameters); + hasTransitions |= circleTranslate.calculate(parameters); + hasTransitions |= circleTranslateAnchor.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp new file mode 100644 index 0000000000..956e423c45 --- /dev/null +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -0,0 +1,30 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class CirclePaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty circleRadius { 5 }; + PaintProperty circleColor { {{ 0, 0, 0, 1 }} }; + PaintProperty circleBlur { 0 }; + PaintProperty circleOpacity { 1 }; + PaintProperty> circleTranslate { {{ 0, 0 }} }; + PaintProperty circleTranslateAnchor { TranslateAnchorType::Map }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/custom_layer.cpp b/src/mbgl/style/layers/custom_layer.cpp new file mode 100644 index 0000000000..3407a7f5a5 --- /dev/null +++ b/src/mbgl/style/layers/custom_layer.cpp @@ -0,0 +1,24 @@ +#include +#include + +namespace mbgl { +namespace style { + +CustomLayer::CustomLayer(const std::string& layerID, + CustomLayerInitializeFunction init, + CustomLayerRenderFunction render, + CustomLayerDeinitializeFunction deinit, + void* context) + : Layer(Type::Custom, std::make_unique(layerID, init, render, deinit, context)) + , impl(static_cast(baseImpl.get())) { +} + +CustomLayer::CustomLayer(const Impl& other) + : Layer(Type::Custom, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +CustomLayer::~CustomLayer() = default; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp new file mode 100644 index 0000000000..214d4ce663 --- /dev/null +++ b/src/mbgl/style/layers/custom_layer_impl.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +namespace mbgl { +namespace style { + +CustomLayer::Impl::Impl(const std::string& id_, + CustomLayerInitializeFunction initializeFn_, + CustomLayerRenderFunction renderFn_, + CustomLayerDeinitializeFunction deinitializeFn_, + void* context_) { + id = id_; + initializeFn = initializeFn_; + renderFn = renderFn_; + deinitializeFn = deinitializeFn_; + context = context_; +} + +CustomLayer::Impl::Impl(const CustomLayer::Impl& other) + : Layer::Impl(other) { + id = other.id; + // Don't copy anything else. +} + +CustomLayer::Impl::~Impl() { + if (deinitializeFn) { + deinitializeFn(context); + } +} + +std::unique_ptr CustomLayer::Impl::clone() const { + return std::make_unique(*this); +} + +void CustomLayer::Impl::initialize() { + assert(initializeFn); + initializeFn(context); +} + +void CustomLayer::Impl::render(const TransformState& state) const { + assert(renderFn); + + CustomLayerRenderParameters parameters; + + parameters.width = state.getWidth(); + parameters.height = state.getHeight(); + parameters.latitude = state.getLatLng().latitude; + parameters.longitude = state.getLatLng().longitude; + parameters.zoom = state.getZoom(); + parameters.bearing = -state.getAngle() * util::RAD2DEG; + parameters.pitch = state.getPitch(); + parameters.altitude = state.getAltitude(); + + renderFn(context, parameters); +} + +bool CustomLayer::Impl::recalculate(const CalculationParameters&) { + passes = RenderPass::Translucent; + return false; +} + +std::unique_ptr CustomLayer::Impl::createBucket(BucketParameters&) const { + return nullptr; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp new file mode 100644 index 0000000000..00e576b6a3 --- /dev/null +++ b/src/mbgl/style/layers/custom_layer_impl.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class TransformState; + +namespace style { + +class CustomLayer::Impl : public Layer::Impl { +public: + Impl(const std::string& id, + CustomLayerInitializeFunction, + CustomLayerRenderFunction, + CustomLayerDeinitializeFunction, + void* context); + + Impl(const Impl&); + ~Impl() final; + + void initialize(); + void render(const TransformState&) const; + +private: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) final {} + void parsePaints(const JSValue&) final {} + + void cascade(const CascadeParameters&) final {} + bool recalculate(const CalculationParameters&) final; + + std::unique_ptr createBucket(BucketParameters&) const final; + + CustomLayerInitializeFunction initializeFn = nullptr; + CustomLayerRenderFunction renderFn = nullptr; + CustomLayerDeinitializeFunction deinitializeFn = nullptr; + void* context = nullptr; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp new file mode 100644 index 0000000000..1deaabb5ef --- /dev/null +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -0,0 +1,113 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +FillLayer::FillLayer(const std::string& layerID) + : Layer(Type::Fill, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +FillLayer::FillLayer(const Impl& other) + : Layer(Type::Fill, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +FillLayer::~FillLayer() = default; + +std::unique_ptr FillLayer::Impl::clone() const { + return std::make_unique(*this); +} + +// Source + +void FillLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { + impl->source = sourceID; + impl->sourceLayer = sourceLayer; +} + +const std::string& FillLayer::getSourceID() const { + return impl->source; +} + +const std::string& FillLayer::getSourceLayer() const { + return impl->sourceLayer; +} + +// Filter + +void FillLayer::setFilter(const Filter& filter) { + impl->filter = filter; +} + +const Filter& FillLayer::getFilter() const { + return impl->filter; +} + +// Layout properties + + +// Paint properties + +PropertyValue FillLayer::getFillAntialias() const { + return impl->paint.fillAntialias.get(); +} + +void FillLayer::setFillAntialias(PropertyValue value) { + impl->paint.fillAntialias.set(value); +} + +PropertyValue FillLayer::getFillOpacity() const { + return impl->paint.fillOpacity.get(); +} + +void FillLayer::setFillOpacity(PropertyValue value) { + impl->paint.fillOpacity.set(value); +} + +PropertyValue FillLayer::getFillColor() const { + return impl->paint.fillColor.get(); +} + +void FillLayer::setFillColor(PropertyValue value) { + impl->paint.fillColor.set(value); +} + +PropertyValue FillLayer::getFillOutlineColor() const { + return impl->paint.fillOutlineColor.get(); +} + +void FillLayer::setFillOutlineColor(PropertyValue value) { + impl->paint.fillOutlineColor.set(value); +} + +PropertyValue> FillLayer::getFillTranslate() const { + return impl->paint.fillTranslate.get(); +} + +void FillLayer::setFillTranslate(PropertyValue> value) { + impl->paint.fillTranslate.set(value); +} + +PropertyValue FillLayer::getFillTranslateAnchor() const { + return impl->paint.fillTranslateAnchor.get(); +} + +void FillLayer::setFillTranslateAnchor(PropertyValue value) { + impl->paint.fillTranslateAnchor.set(value); +} + +PropertyValue FillLayer::getFillPattern() const { + return impl->paint.fillPattern.get(); +} + +void FillLayer::setFillPattern(PropertyValue value) { + impl->paint.fillPattern.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp new file mode 100644 index 0000000000..c183617482 --- /dev/null +++ b/src/mbgl/style/layers/fill_layer_impl.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include + +namespace mbgl { +namespace style { + +void FillLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void FillLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool FillLayer::Impl::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = paint.recalculate(parameters); + + passes = RenderPass::None; + + if (paint.fillAntialias) { + passes |= RenderPass::Translucent; + } + + if (!paint.fillPattern.value.from.empty() || (paint.fillColor.value[3] * paint.fillOpacity) < 1.0f) { + passes |= RenderPass::Translucent; + } else { + passes |= RenderPass::Opaque; + } + + return hasTransitions; +} + +std::unique_ptr FillLayer::Impl::createBucket(BucketParameters& parameters) const { + auto bucket = std::make_unique(); + + 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& translate = paint.fillTranslate; + return util::length(translate[0], translate[1]); +} + +bool FillLayer::Impl::queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const { + + auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( + queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits); + + return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp new file mode 100644 index 0000000000..a37dd76ace --- /dev/null +++ b/src/mbgl/style/layers/fill_layer_impl.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class FillLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override {}; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + float getQueryRadius() const override; + bool queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const override; + + FillPaintProperties paint; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp new file mode 100644 index 0000000000..a4714689f9 --- /dev/null +++ b/src/mbgl/style/layers/fill_layer_properties.cpp @@ -0,0 +1,43 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void FillPaintProperties::parse(const JSValue& value) { + fillAntialias.parse("fill-antialias", value); + fillOpacity.parse("fill-opacity", value); + fillColor.parse("fill-color", value); + fillOutlineColor.parse("fill-outline-color", value); + fillTranslate.parse("fill-translate", value); + fillTranslateAnchor.parse("fill-translate-anchor", value); + fillPattern.parse("fill-pattern", value); +} + +void FillPaintProperties::cascade(const CascadeParameters& parameters) { + fillAntialias.cascade(parameters); + fillOpacity.cascade(parameters); + fillColor.cascade(parameters); + fillOutlineColor.cascade(parameters); + fillTranslate.cascade(parameters); + fillTranslateAnchor.cascade(parameters); + fillPattern.cascade(parameters); +} + +bool FillPaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= fillAntialias.calculate(parameters); + hasTransitions |= fillOpacity.calculate(parameters); + hasTransitions |= fillColor.calculate(parameters); + hasTransitions |= fillOutlineColor.calculate(parameters); + hasTransitions |= fillTranslate.calculate(parameters); + hasTransitions |= fillTranslateAnchor.calculate(parameters); + hasTransitions |= fillPattern.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp new file mode 100644 index 0000000000..43396f45d2 --- /dev/null +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -0,0 +1,31 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class FillPaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty fillAntialias { true }; + PaintProperty fillOpacity { 1 }; + PaintProperty fillColor { {{ 0, 0, 0, 1 }} }; + PaintProperty fillOutlineColor { {{ 0, 0, 0, -1 }} }; + PaintProperty> fillTranslate { {{ 0, 0 }} }; + PaintProperty fillTranslateAnchor { TranslateAnchorType::Map }; + PaintProperty fillPattern { "" }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp new file mode 100644 index 0000000000..abe326a672 --- /dev/null +++ b/src/mbgl/style/layers/line_layer.cpp @@ -0,0 +1,165 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +LineLayer::LineLayer(const std::string& layerID) + : Layer(Type::Line, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +LineLayer::LineLayer(const Impl& other) + : Layer(Type::Line, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +LineLayer::~LineLayer() = default; + +std::unique_ptr LineLayer::Impl::clone() const { + return std::make_unique(*this); +} + +// Source + +void LineLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { + impl->source = sourceID; + impl->sourceLayer = sourceLayer; +} + +const std::string& LineLayer::getSourceID() const { + return impl->source; +} + +const std::string& LineLayer::getSourceLayer() const { + return impl->sourceLayer; +} + +// Filter + +void LineLayer::setFilter(const Filter& filter) { + impl->filter = filter; +} + +const Filter& LineLayer::getFilter() const { + return impl->filter; +} + +// Layout properties + +PropertyValue LineLayer::getLineCap() const { + return impl->layout.lineCap.get(); +} + +void LineLayer::setLineCap(PropertyValue value) { + impl->layout.lineCap.set(value); +} +PropertyValue LineLayer::getLineJoin() const { + return impl->layout.lineJoin.get(); +} + +void LineLayer::setLineJoin(PropertyValue value) { + impl->layout.lineJoin.set(value); +} +PropertyValue LineLayer::getLineMiterLimit() const { + return impl->layout.lineMiterLimit.get(); +} + +void LineLayer::setLineMiterLimit(PropertyValue value) { + impl->layout.lineMiterLimit.set(value); +} +PropertyValue LineLayer::getLineRoundLimit() const { + return impl->layout.lineRoundLimit.get(); +} + +void LineLayer::setLineRoundLimit(PropertyValue value) { + impl->layout.lineRoundLimit.set(value); +} + +// Paint properties + +PropertyValue LineLayer::getLineOpacity() const { + return impl->paint.lineOpacity.get(); +} + +void LineLayer::setLineOpacity(PropertyValue value) { + impl->paint.lineOpacity.set(value); +} + +PropertyValue LineLayer::getLineColor() const { + return impl->paint.lineColor.get(); +} + +void LineLayer::setLineColor(PropertyValue value) { + impl->paint.lineColor.set(value); +} + +PropertyValue> LineLayer::getLineTranslate() const { + return impl->paint.lineTranslate.get(); +} + +void LineLayer::setLineTranslate(PropertyValue> value) { + impl->paint.lineTranslate.set(value); +} + +PropertyValue LineLayer::getLineTranslateAnchor() const { + return impl->paint.lineTranslateAnchor.get(); +} + +void LineLayer::setLineTranslateAnchor(PropertyValue value) { + impl->paint.lineTranslateAnchor.set(value); +} + +PropertyValue LineLayer::getLineWidth() const { + return impl->paint.lineWidth.get(); +} + +void LineLayer::setLineWidth(PropertyValue value) { + impl->paint.lineWidth.set(value); +} + +PropertyValue LineLayer::getLineGapWidth() const { + return impl->paint.lineGapWidth.get(); +} + +void LineLayer::setLineGapWidth(PropertyValue value) { + impl->paint.lineGapWidth.set(value); +} + +PropertyValue LineLayer::getLineOffset() const { + return impl->paint.lineOffset.get(); +} + +void LineLayer::setLineOffset(PropertyValue value) { + impl->paint.lineOffset.set(value); +} + +PropertyValue LineLayer::getLineBlur() const { + return impl->paint.lineBlur.get(); +} + +void LineLayer::setLineBlur(PropertyValue value) { + impl->paint.lineBlur.set(value); +} + +PropertyValue> LineLayer::getLineDasharray() const { + return impl->paint.lineDasharray.get(); +} + +void LineLayer::setLineDasharray(PropertyValue> value) { + impl->paint.lineDasharray.set(value); +} + +PropertyValue LineLayer::getLinePattern() const { + return impl->paint.linePattern.get(); +} + +void LineLayer::setLinePattern(PropertyValue value) { + impl->paint.linePattern.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp new file mode 100644 index 0000000000..b7ee9dc5bf --- /dev/null +++ b/src/mbgl/style/layers/line_layer_impl.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +namespace mbgl { +namespace style { + +void LineLayer::Impl::parseLayout(const JSValue& value) { + layout.parse(value); +} + +void LineLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void LineLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool LineLayer::Impl::recalculate(const CalculationParameters& parameters) { + // for scaling dasharrays + CalculationParameters dashArrayParams = parameters; + dashArrayParams.z = std::floor(dashArrayParams.z); + paint.lineWidth.calculate(dashArrayParams); + dashLineWidth = paint.lineWidth; + + bool hasTransitions = paint.recalculate(parameters); + + passes = (paint.lineOpacity > 0 && paint.lineColor.value[3] > 0 && paint.lineWidth > 0) + ? RenderPass::Translucent : RenderPass::None; + + return hasTransitions; +} + +std::unique_ptr LineLayer::Impl::createBucket(BucketParameters& parameters) const { + auto bucket = std::make_unique(parameters.tileID.overscaleFactor()); + + bucket->layout = layout; + bucket->layout.recalculate(CalculationParameters(parameters.tileID.overscaledZ)); + + auto& name = bucketName(); + parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) { + auto geometries = feature.getGeometries(); + bucket->addGeometry(geometries); + parameters.featureIndex.insert(geometries, index, layerName, name); + }); + + return std::move(bucket); +} + +float LineLayer::Impl::getLineWidth() const { + if (paint.lineGapWidth > 0) { + return paint.lineGapWidth + 2 * paint.lineWidth; + } else { + return paint.lineWidth; + } +} + +optional offsetLine(const GeometryCollection& rings, const double offset) { + if (offset == 0) return {}; + + GeometryCollection newRings; + Point 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 aToB = i == ring.begin() ? + zero : + util::perp(util::unit(convertPoint(p - *(i - 1)))); + Point bToC = i + 1 == ring.end() ? + zero : + util::perp(util::unit(convertPoint(*(i + 1) - p))); + Point extrude = util::unit(aToB + bToC); + + const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y; + extrude *= (1.0 / cosHalfAngle); + + newRing.push_back(convertPoint(extrude * offset) + p); + } + } + + return newRings; +} + +float LineLayer::Impl::getQueryRadius() const { + const std::array& translate = paint.lineTranslate; + return getLineWidth() / 2.0 + std::abs(paint.lineOffset) + util::length(translate[0], translate[1]); +} + +bool LineLayer::Impl::queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const { + + const float halfWidth = getLineWidth() / 2.0 * pixelsToTileUnits; + + auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( + queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits); + auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits); + + return util::multiPolygonIntersectsBufferedMultiLine( + translatedQueryGeometry.value_or(queryGeometry), + offsetGeometry.value_or(geometry), + halfWidth); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp new file mode 100644 index 0000000000..3356dc2ceb --- /dev/null +++ b/src/mbgl/style/layers/line_layer_impl.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class LineLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + float getQueryRadius() const override; + bool queryIntersectsGeometry( + const GeometryCollection& queryGeometry, + const GeometryCollection& geometry, + const float bearing, + const float pixelsToTileUnits) const override; + + LineLayoutProperties layout; + LinePaintProperties paint; + + // Special case + float dashLineWidth = 1; + +private: + float getLineWidth() const; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp new file mode 100644 index 0000000000..7c74f6de04 --- /dev/null +++ b/src/mbgl/style/layers/line_layer_properties.cpp @@ -0,0 +1,66 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void LineLayoutProperties::parse(const JSValue& value) { + lineCap.parse("line-cap", value); + lineJoin.parse("line-join", value); + lineMiterLimit.parse("line-miter-limit", value); + lineRoundLimit.parse("line-round-limit", value); +} + +void LineLayoutProperties::recalculate(const CalculationParameters& parameters) { + lineCap.calculate(parameters); + lineJoin.calculate(parameters); + lineMiterLimit.calculate(parameters); + lineRoundLimit.calculate(parameters); +} + +void LinePaintProperties::parse(const JSValue& value) { + lineOpacity.parse("line-opacity", value); + lineColor.parse("line-color", value); + lineTranslate.parse("line-translate", value); + lineTranslateAnchor.parse("line-translate-anchor", value); + lineWidth.parse("line-width", value); + lineGapWidth.parse("line-gap-width", value); + lineOffset.parse("line-offset", value); + lineBlur.parse("line-blur", value); + lineDasharray.parse("line-dasharray", value); + linePattern.parse("line-pattern", value); +} + +void LinePaintProperties::cascade(const CascadeParameters& parameters) { + lineOpacity.cascade(parameters); + lineColor.cascade(parameters); + lineTranslate.cascade(parameters); + lineTranslateAnchor.cascade(parameters); + lineWidth.cascade(parameters); + lineGapWidth.cascade(parameters); + lineOffset.cascade(parameters); + lineBlur.cascade(parameters); + lineDasharray.cascade(parameters); + linePattern.cascade(parameters); +} + +bool LinePaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= lineOpacity.calculate(parameters); + hasTransitions |= lineColor.calculate(parameters); + hasTransitions |= lineTranslate.calculate(parameters); + hasTransitions |= lineTranslateAnchor.calculate(parameters); + hasTransitions |= lineWidth.calculate(parameters); + hasTransitions |= lineGapWidth.calculate(parameters); + hasTransitions |= lineOffset.calculate(parameters); + hasTransitions |= lineBlur.calculate(parameters); + hasTransitions |= lineDasharray.calculate(parameters); + hasTransitions |= linePattern.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp new file mode 100644 index 0000000000..e0c63b516b --- /dev/null +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -0,0 +1,45 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class LineLayoutProperties { +public: + void parse(const JSValue&); + void recalculate(const CalculationParameters&); + + LayoutProperty lineCap { LineCapType::Butt }; + LayoutProperty lineJoin { LineJoinType::Miter }; + LayoutProperty lineMiterLimit { 2 }; + LayoutProperty lineRoundLimit { 1.05 }; +}; + +class LinePaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty lineOpacity { 1 }; + PaintProperty lineColor { {{ 0, 0, 0, 1 }} }; + PaintProperty> lineTranslate { {{ 0, 0 }} }; + PaintProperty lineTranslateAnchor { TranslateAnchorType::Map }; + PaintProperty lineWidth { 1 }; + PaintProperty lineGapWidth { 0 }; + PaintProperty lineOffset { 0 }; + PaintProperty lineBlur { 0 }; + PaintProperty, CrossFadedPropertyEvaluator> lineDasharray { { } }; + PaintProperty linePattern { "" }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp new file mode 100644 index 0000000000..fb7f08fbe9 --- /dev/null +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -0,0 +1,98 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +RasterLayer::RasterLayer(const std::string& layerID) + : Layer(Type::Raster, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +RasterLayer::RasterLayer(const Impl& other) + : Layer(Type::Raster, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +RasterLayer::~RasterLayer() = default; + +std::unique_ptr RasterLayer::Impl::clone() const { + return std::make_unique(*this); +} + +// Source + +void RasterLayer::setSource(const std::string& sourceID) { + impl->source = sourceID; +} + +const std::string& RasterLayer::getSourceID() const { + return impl->source; +} + +// Layout properties + + +// Paint properties + +PropertyValue RasterLayer::getRasterOpacity() const { + return impl->paint.rasterOpacity.get(); +} + +void RasterLayer::setRasterOpacity(PropertyValue value) { + impl->paint.rasterOpacity.set(value); +} + +PropertyValue RasterLayer::getRasterHueRotate() const { + return impl->paint.rasterHueRotate.get(); +} + +void RasterLayer::setRasterHueRotate(PropertyValue value) { + impl->paint.rasterHueRotate.set(value); +} + +PropertyValue RasterLayer::getRasterBrightnessMin() const { + return impl->paint.rasterBrightnessMin.get(); +} + +void RasterLayer::setRasterBrightnessMin(PropertyValue value) { + impl->paint.rasterBrightnessMin.set(value); +} + +PropertyValue RasterLayer::getRasterBrightnessMax() const { + return impl->paint.rasterBrightnessMax.get(); +} + +void RasterLayer::setRasterBrightnessMax(PropertyValue value) { + impl->paint.rasterBrightnessMax.set(value); +} + +PropertyValue RasterLayer::getRasterSaturation() const { + return impl->paint.rasterSaturation.get(); +} + +void RasterLayer::setRasterSaturation(PropertyValue value) { + impl->paint.rasterSaturation.set(value); +} + +PropertyValue RasterLayer::getRasterContrast() const { + return impl->paint.rasterContrast.get(); +} + +void RasterLayer::setRasterContrast(PropertyValue value) { + impl->paint.rasterContrast.set(value); +} + +PropertyValue RasterLayer::getRasterFadeDuration() const { + return impl->paint.rasterFadeDuration.get(); +} + +void RasterLayer::setRasterFadeDuration(PropertyValue value) { + impl->paint.rasterFadeDuration.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp new file mode 100644 index 0000000000..4854ec041d --- /dev/null +++ b/src/mbgl/style/layers/raster_layer_impl.cpp @@ -0,0 +1,28 @@ +#include +#include + +namespace mbgl { +namespace style { + +void RasterLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void RasterLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool RasterLayer::Impl::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = paint.recalculate(parameters); + + passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None; + + return hasTransitions; +} + +std::unique_ptr RasterLayer::Impl::createBucket(BucketParameters&) const { + return nullptr; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp new file mode 100644 index 0000000000..6812b469a6 --- /dev/null +++ b/src/mbgl/style/layers/raster_layer_impl.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class RasterLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override {}; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + RasterPaintProperties paint; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp new file mode 100644 index 0000000000..0e6afc5e9c --- /dev/null +++ b/src/mbgl/style/layers/raster_layer_properties.cpp @@ -0,0 +1,43 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void RasterPaintProperties::parse(const JSValue& value) { + rasterOpacity.parse("raster-opacity", value); + rasterHueRotate.parse("raster-hue-rotate", value); + rasterBrightnessMin.parse("raster-brightness-min", value); + rasterBrightnessMax.parse("raster-brightness-max", value); + rasterSaturation.parse("raster-saturation", value); + rasterContrast.parse("raster-contrast", value); + rasterFadeDuration.parse("raster-fade-duration", value); +} + +void RasterPaintProperties::cascade(const CascadeParameters& parameters) { + rasterOpacity.cascade(parameters); + rasterHueRotate.cascade(parameters); + rasterBrightnessMin.cascade(parameters); + rasterBrightnessMax.cascade(parameters); + rasterSaturation.cascade(parameters); + rasterContrast.cascade(parameters); + rasterFadeDuration.cascade(parameters); +} + +bool RasterPaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= rasterOpacity.calculate(parameters); + hasTransitions |= rasterHueRotate.calculate(parameters); + hasTransitions |= rasterBrightnessMin.calculate(parameters); + hasTransitions |= rasterBrightnessMax.calculate(parameters); + hasTransitions |= rasterSaturation.calculate(parameters); + hasTransitions |= rasterContrast.calculate(parameters); + hasTransitions |= rasterFadeDuration.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp new file mode 100644 index 0000000000..049da87312 --- /dev/null +++ b/src/mbgl/style/layers/raster_layer_properties.hpp @@ -0,0 +1,31 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class RasterPaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty rasterOpacity { 1 }; + PaintProperty rasterHueRotate { 0 }; + PaintProperty rasterBrightnessMin { 0 }; + PaintProperty rasterBrightnessMax { 1 }; + PaintProperty rasterSaturation { 0 }; + PaintProperty rasterContrast { 0 }; + PaintProperty rasterFadeDuration { 300 }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp new file mode 100644 index 0000000000..d7d6a02ace --- /dev/null +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -0,0 +1,386 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include +#include + +namespace mbgl { +namespace style { + +SymbolLayer::SymbolLayer(const std::string& layerID) + : Layer(Type::Symbol, std::make_unique()) + , impl(static_cast(baseImpl.get())) { + impl->id = layerID; +} + +SymbolLayer::SymbolLayer(const Impl& other) + : Layer(Type::Symbol, std::make_unique(other)) + , impl(static_cast(baseImpl.get())) { +} + +SymbolLayer::~SymbolLayer() = default; + +std::unique_ptr SymbolLayer::Impl::clone() const { + return std::make_unique(*this); +} + +// Source + +void SymbolLayer::setSource(const std::string& sourceID, const std::string& sourceLayer) { + impl->source = sourceID; + impl->sourceLayer = sourceLayer; +} + +const std::string& SymbolLayer::getSourceID() const { + return impl->source; +} + +const std::string& SymbolLayer::getSourceLayer() const { + return impl->sourceLayer; +} + +// Filter + +void SymbolLayer::setFilter(const Filter& filter) { + impl->filter = filter; +} + +const Filter& SymbolLayer::getFilter() const { + return impl->filter; +} + +// Layout properties + +PropertyValue SymbolLayer::getSymbolPlacement() const { + return impl->layout.symbolPlacement.get(); +} + +void SymbolLayer::setSymbolPlacement(PropertyValue value) { + impl->layout.symbolPlacement.set(value); +} +PropertyValue SymbolLayer::getSymbolSpacing() const { + return impl->layout.symbolSpacing.get(); +} + +void SymbolLayer::setSymbolSpacing(PropertyValue value) { + impl->layout.symbolSpacing.set(value); +} +PropertyValue SymbolLayer::getSymbolAvoidEdges() const { + return impl->layout.symbolAvoidEdges.get(); +} + +void SymbolLayer::setSymbolAvoidEdges(PropertyValue value) { + impl->layout.symbolAvoidEdges.set(value); +} +PropertyValue SymbolLayer::getIconAllowOverlap() const { + return impl->layout.iconAllowOverlap.get(); +} + +void SymbolLayer::setIconAllowOverlap(PropertyValue value) { + impl->layout.iconAllowOverlap.set(value); +} +PropertyValue SymbolLayer::getIconIgnorePlacement() const { + return impl->layout.iconIgnorePlacement.get(); +} + +void SymbolLayer::setIconIgnorePlacement(PropertyValue value) { + impl->layout.iconIgnorePlacement.set(value); +} +PropertyValue SymbolLayer::getIconOptional() const { + return impl->layout.iconOptional.get(); +} + +void SymbolLayer::setIconOptional(PropertyValue value) { + impl->layout.iconOptional.set(value); +} +PropertyValue SymbolLayer::getIconRotationAlignment() const { + return impl->layout.iconRotationAlignment.get(); +} + +void SymbolLayer::setIconRotationAlignment(PropertyValue value) { + impl->layout.iconRotationAlignment.set(value); +} +PropertyValue SymbolLayer::getIconSize() const { + return impl->layout.iconSize.get(); +} + +void SymbolLayer::setIconSize(PropertyValue value) { + impl->layout.iconSize.set(value); +} +PropertyValue SymbolLayer::getIconImage() const { + return impl->layout.iconImage.get(); +} + +void SymbolLayer::setIconImage(PropertyValue value) { + impl->layout.iconImage.set(value); +} +PropertyValue SymbolLayer::getIconRotate() const { + return impl->layout.iconRotate.get(); +} + +void SymbolLayer::setIconRotate(PropertyValue value) { + impl->layout.iconRotate.set(value); +} +PropertyValue SymbolLayer::getIconPadding() const { + return impl->layout.iconPadding.get(); +} + +void SymbolLayer::setIconPadding(PropertyValue value) { + impl->layout.iconPadding.set(value); +} +PropertyValue SymbolLayer::getIconKeepUpright() const { + return impl->layout.iconKeepUpright.get(); +} + +void SymbolLayer::setIconKeepUpright(PropertyValue value) { + impl->layout.iconKeepUpright.set(value); +} +PropertyValue> SymbolLayer::getIconOffset() const { + return impl->layout.iconOffset.get(); +} + +void SymbolLayer::setIconOffset(PropertyValue> value) { + impl->layout.iconOffset.set(value); +} +PropertyValue SymbolLayer::getTextRotationAlignment() const { + return impl->layout.textRotationAlignment.get(); +} + +void SymbolLayer::setTextRotationAlignment(PropertyValue value) { + impl->layout.textRotationAlignment.set(value); +} +PropertyValue SymbolLayer::getTextField() const { + return impl->layout.textField.get(); +} + +void SymbolLayer::setTextField(PropertyValue value) { + impl->layout.textField.set(value); +} +PropertyValue> SymbolLayer::getTextFont() const { + return impl->layout.textFont.get(); +} + +void SymbolLayer::setTextFont(PropertyValue> value) { + impl->layout.textFont.set(value); +} +PropertyValue SymbolLayer::getTextSize() const { + return impl->layout.textSize.get(); +} + +void SymbolLayer::setTextSize(PropertyValue value) { + impl->layout.textSize.set(value); +} +PropertyValue SymbolLayer::getTextMaxWidth() const { + return impl->layout.textMaxWidth.get(); +} + +void SymbolLayer::setTextMaxWidth(PropertyValue value) { + impl->layout.textMaxWidth.set(value); +} +PropertyValue SymbolLayer::getTextLineHeight() const { + return impl->layout.textLineHeight.get(); +} + +void SymbolLayer::setTextLineHeight(PropertyValue value) { + impl->layout.textLineHeight.set(value); +} +PropertyValue SymbolLayer::getTextLetterSpacing() const { + return impl->layout.textLetterSpacing.get(); +} + +void SymbolLayer::setTextLetterSpacing(PropertyValue value) { + impl->layout.textLetterSpacing.set(value); +} +PropertyValue SymbolLayer::getTextJustify() const { + return impl->layout.textJustify.get(); +} + +void SymbolLayer::setTextJustify(PropertyValue value) { + impl->layout.textJustify.set(value); +} +PropertyValue SymbolLayer::getTextAnchor() const { + return impl->layout.textAnchor.get(); +} + +void SymbolLayer::setTextAnchor(PropertyValue value) { + impl->layout.textAnchor.set(value); +} +PropertyValue SymbolLayer::getTextMaxAngle() const { + return impl->layout.textMaxAngle.get(); +} + +void SymbolLayer::setTextMaxAngle(PropertyValue value) { + impl->layout.textMaxAngle.set(value); +} +PropertyValue SymbolLayer::getTextRotate() const { + return impl->layout.textRotate.get(); +} + +void SymbolLayer::setTextRotate(PropertyValue value) { + impl->layout.textRotate.set(value); +} +PropertyValue SymbolLayer::getTextPadding() const { + return impl->layout.textPadding.get(); +} + +void SymbolLayer::setTextPadding(PropertyValue value) { + impl->layout.textPadding.set(value); +} +PropertyValue SymbolLayer::getTextKeepUpright() const { + return impl->layout.textKeepUpright.get(); +} + +void SymbolLayer::setTextKeepUpright(PropertyValue value) { + impl->layout.textKeepUpright.set(value); +} +PropertyValue SymbolLayer::getTextTransform() const { + return impl->layout.textTransform.get(); +} + +void SymbolLayer::setTextTransform(PropertyValue value) { + impl->layout.textTransform.set(value); +} +PropertyValue> SymbolLayer::getTextOffset() const { + return impl->layout.textOffset.get(); +} + +void SymbolLayer::setTextOffset(PropertyValue> value) { + impl->layout.textOffset.set(value); +} +PropertyValue SymbolLayer::getTextAllowOverlap() const { + return impl->layout.textAllowOverlap.get(); +} + +void SymbolLayer::setTextAllowOverlap(PropertyValue value) { + impl->layout.textAllowOverlap.set(value); +} +PropertyValue SymbolLayer::getTextIgnorePlacement() const { + return impl->layout.textIgnorePlacement.get(); +} + +void SymbolLayer::setTextIgnorePlacement(PropertyValue value) { + impl->layout.textIgnorePlacement.set(value); +} +PropertyValue SymbolLayer::getTextOptional() const { + return impl->layout.textOptional.get(); +} + +void SymbolLayer::setTextOptional(PropertyValue value) { + impl->layout.textOptional.set(value); +} + +// Paint properties + +PropertyValue SymbolLayer::getIconOpacity() const { + return impl->paint.iconOpacity.get(); +} + +void SymbolLayer::setIconOpacity(PropertyValue value) { + impl->paint.iconOpacity.set(value); +} + +PropertyValue SymbolLayer::getIconColor() const { + return impl->paint.iconColor.get(); +} + +void SymbolLayer::setIconColor(PropertyValue value) { + impl->paint.iconColor.set(value); +} + +PropertyValue SymbolLayer::getIconHaloColor() const { + return impl->paint.iconHaloColor.get(); +} + +void SymbolLayer::setIconHaloColor(PropertyValue value) { + impl->paint.iconHaloColor.set(value); +} + +PropertyValue SymbolLayer::getIconHaloWidth() const { + return impl->paint.iconHaloWidth.get(); +} + +void SymbolLayer::setIconHaloWidth(PropertyValue value) { + impl->paint.iconHaloWidth.set(value); +} + +PropertyValue SymbolLayer::getIconHaloBlur() const { + return impl->paint.iconHaloBlur.get(); +} + +void SymbolLayer::setIconHaloBlur(PropertyValue value) { + impl->paint.iconHaloBlur.set(value); +} + +PropertyValue> SymbolLayer::getIconTranslate() const { + return impl->paint.iconTranslate.get(); +} + +void SymbolLayer::setIconTranslate(PropertyValue> value) { + impl->paint.iconTranslate.set(value); +} + +PropertyValue SymbolLayer::getIconTranslateAnchor() const { + return impl->paint.iconTranslateAnchor.get(); +} + +void SymbolLayer::setIconTranslateAnchor(PropertyValue value) { + impl->paint.iconTranslateAnchor.set(value); +} + +PropertyValue SymbolLayer::getTextOpacity() const { + return impl->paint.textOpacity.get(); +} + +void SymbolLayer::setTextOpacity(PropertyValue value) { + impl->paint.textOpacity.set(value); +} + +PropertyValue SymbolLayer::getTextColor() const { + return impl->paint.textColor.get(); +} + +void SymbolLayer::setTextColor(PropertyValue value) { + impl->paint.textColor.set(value); +} + +PropertyValue SymbolLayer::getTextHaloColor() const { + return impl->paint.textHaloColor.get(); +} + +void SymbolLayer::setTextHaloColor(PropertyValue value) { + impl->paint.textHaloColor.set(value); +} + +PropertyValue SymbolLayer::getTextHaloWidth() const { + return impl->paint.textHaloWidth.get(); +} + +void SymbolLayer::setTextHaloWidth(PropertyValue value) { + impl->paint.textHaloWidth.set(value); +} + +PropertyValue SymbolLayer::getTextHaloBlur() const { + return impl->paint.textHaloBlur.get(); +} + +void SymbolLayer::setTextHaloBlur(PropertyValue value) { + impl->paint.textHaloBlur.set(value); +} + +PropertyValue> SymbolLayer::getTextTranslate() const { + return impl->paint.textTranslate.get(); +} + +void SymbolLayer::setTextTranslate(PropertyValue> value) { + impl->paint.textTranslate.set(value); +} + +PropertyValue SymbolLayer::getTextTranslateAnchor() const { + return impl->paint.textTranslateAnchor.get(); +} + +void SymbolLayer::setTextTranslateAnchor(PropertyValue value) { + impl->paint.textTranslateAnchor.set(value); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp new file mode 100644 index 0000000000..a4dc264ed2 --- /dev/null +++ b/src/mbgl/style/layers/symbol_layer_impl.cpp @@ -0,0 +1,82 @@ +#include +#include +#include + +namespace mbgl { +namespace style { + +void SymbolLayer::Impl::parseLayout(const JSValue& value) { + layout.parse(value); +} + +void SymbolLayer::Impl::parsePaints(const JSValue& layer) { + paint.parse(layer); +} + +void SymbolLayer::Impl::cascade(const CascadeParameters& parameters) { + paint.cascade(parameters); +} + +bool SymbolLayer::Impl::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = paint.recalculate(parameters); + + // text-size and icon-size are layout properties but they also need to be evaluated as paint properties: + layout.iconSize.calculate(parameters); + layout.textSize.calculate(parameters); + iconSize = layout.iconSize; + textSize = layout.textSize; + + passes = ((paint.iconOpacity > 0 && (paint.iconColor.value[3] > 0 || paint.iconHaloColor.value[3] > 0) && iconSize > 0) + || (paint.textOpacity > 0 && (paint.textColor.value[3] > 0 || paint.textHaloColor.value[3] > 0) && textSize > 0)) + ? RenderPass::Translucent : RenderPass::None; + + return hasTransitions; +} + +std::unique_ptr SymbolLayer::Impl::createBucket(BucketParameters& parameters) const { + auto bucket = std::make_unique(parameters.tileID.overscaleFactor(), + parameters.tileID.overscaledZ, + parameters.mode, + id, + parameters.layer.getName()); + + bucket->layout = layout; + + CalculationParameters p(parameters.tileID.overscaledZ); + bucket->layout.symbolPlacement.calculate(p); + if (bucket->layout.symbolPlacement.value == SymbolPlacementType::Line) { + bucket->layout.iconRotationAlignment.value = RotationAlignmentType::Map; + bucket->layout.textRotationAlignment.value = RotationAlignmentType::Map; + }; + + bucket->layout.recalculate(p); + + bucket->layout.iconSize.calculate(CalculationParameters(18)); + bucket->layout.textSize.calculate(CalculationParameters(18)); + bucket->iconMaxSize = bucket->layout.iconSize; + bucket->textMaxSize = bucket->layout.textSize; + bucket->layout.iconSize.calculate(CalculationParameters(p.z + 1)); + bucket->layout.textSize.calculate(CalculationParameters(p.z + 1)); + + bucket->parseFeatures(parameters.layer, filter); + + if (bucket->needsDependencies(parameters.glyphStore, parameters.spriteStore)) { + parameters.partialParse = true; + } + + // We do not add features if the parser is in a "partial" state because + // the layer ordering needs to be respected when calculating text + // collisions. Although, at this point, we requested all the resources + // needed by this tile. + if (!parameters.partialParse) { + bucket->addFeatures(parameters.tileUID, + *spriteAtlas, + parameters.glyphAtlas, + parameters.glyphStore); + } + + return std::move(bucket); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp new file mode 100644 index 0000000000..9727cc6480 --- /dev/null +++ b/src/mbgl/style/layers/symbol_layer_impl.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { + +class SpriteAtlas; + +namespace style { + +class SymbolLayer::Impl : public Layer::Impl { +public: + std::unique_ptr clone() const override; + + void parseLayout(const JSValue&) override; + void parsePaints(const JSValue&) override; + + void cascade(const CascadeParameters&) override; + bool recalculate(const CalculationParameters&) override; + + std::unique_ptr createBucket(BucketParameters&) const override; + + SymbolLayoutProperties layout; + SymbolPaintProperties paint; + + float iconSize = 1.0f; + float textSize = 16.0f; + + SpriteAtlas* spriteAtlas = nullptr; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp new file mode 100644 index 0000000000..ce16ae2e50 --- /dev/null +++ b/src/mbgl/style/layers/symbol_layer_properties.cpp @@ -0,0 +1,132 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#include + +namespace mbgl { +namespace style { + +void SymbolLayoutProperties::parse(const JSValue& value) { + symbolPlacement.parse("symbol-placement", value); + symbolSpacing.parse("symbol-spacing", value); + symbolAvoidEdges.parse("symbol-avoid-edges", value); + iconAllowOverlap.parse("icon-allow-overlap", value); + iconIgnorePlacement.parse("icon-ignore-placement", value); + iconOptional.parse("icon-optional", value); + iconRotationAlignment.parse("icon-rotation-alignment", value); + iconSize.parse("icon-size", value); + iconImage.parse("icon-image", value); + iconRotate.parse("icon-rotate", value); + iconPadding.parse("icon-padding", value); + iconKeepUpright.parse("icon-keep-upright", value); + iconOffset.parse("icon-offset", value); + textRotationAlignment.parse("text-rotation-alignment", value); + textField.parse("text-field", value); + textFont.parse("text-font", value); + textSize.parse("text-size", value); + textMaxWidth.parse("text-max-width", value); + textLineHeight.parse("text-line-height", value); + textLetterSpacing.parse("text-letter-spacing", value); + textJustify.parse("text-justify", value); + textAnchor.parse("text-anchor", value); + textMaxAngle.parse("text-max-angle", value); + textRotate.parse("text-rotate", value); + textPadding.parse("text-padding", value); + textKeepUpright.parse("text-keep-upright", value); + textTransform.parse("text-transform", value); + textOffset.parse("text-offset", value); + textAllowOverlap.parse("text-allow-overlap", value); + textIgnorePlacement.parse("text-ignore-placement", value); + textOptional.parse("text-optional", value); +} + +void SymbolLayoutProperties::recalculate(const CalculationParameters& parameters) { + symbolPlacement.calculate(parameters); + symbolSpacing.calculate(parameters); + symbolAvoidEdges.calculate(parameters); + iconAllowOverlap.calculate(parameters); + iconIgnorePlacement.calculate(parameters); + iconOptional.calculate(parameters); + iconRotationAlignment.calculate(parameters); + iconSize.calculate(parameters); + iconImage.calculate(parameters); + iconRotate.calculate(parameters); + iconPadding.calculate(parameters); + iconKeepUpright.calculate(parameters); + iconOffset.calculate(parameters); + textRotationAlignment.calculate(parameters); + textField.calculate(parameters); + textFont.calculate(parameters); + textSize.calculate(parameters); + textMaxWidth.calculate(parameters); + textLineHeight.calculate(parameters); + textLetterSpacing.calculate(parameters); + textJustify.calculate(parameters); + textAnchor.calculate(parameters); + textMaxAngle.calculate(parameters); + textRotate.calculate(parameters); + textPadding.calculate(parameters); + textKeepUpright.calculate(parameters); + textTransform.calculate(parameters); + textOffset.calculate(parameters); + textAllowOverlap.calculate(parameters); + textIgnorePlacement.calculate(parameters); + textOptional.calculate(parameters); +} + +void SymbolPaintProperties::parse(const JSValue& value) { + iconOpacity.parse("icon-opacity", value); + iconColor.parse("icon-color", value); + iconHaloColor.parse("icon-halo-color", value); + iconHaloWidth.parse("icon-halo-width", value); + iconHaloBlur.parse("icon-halo-blur", value); + iconTranslate.parse("icon-translate", value); + iconTranslateAnchor.parse("icon-translate-anchor", value); + textOpacity.parse("text-opacity", value); + textColor.parse("text-color", value); + textHaloColor.parse("text-halo-color", value); + textHaloWidth.parse("text-halo-width", value); + textHaloBlur.parse("text-halo-blur", value); + textTranslate.parse("text-translate", value); + textTranslateAnchor.parse("text-translate-anchor", value); +} + +void SymbolPaintProperties::cascade(const CascadeParameters& parameters) { + iconOpacity.cascade(parameters); + iconColor.cascade(parameters); + iconHaloColor.cascade(parameters); + iconHaloWidth.cascade(parameters); + iconHaloBlur.cascade(parameters); + iconTranslate.cascade(parameters); + iconTranslateAnchor.cascade(parameters); + textOpacity.cascade(parameters); + textColor.cascade(parameters); + textHaloColor.cascade(parameters); + textHaloWidth.cascade(parameters); + textHaloBlur.cascade(parameters); + textTranslate.cascade(parameters); + textTranslateAnchor.cascade(parameters); +} + +bool SymbolPaintProperties::recalculate(const CalculationParameters& parameters) { + bool hasTransitions = false; + + hasTransitions |= iconOpacity.calculate(parameters); + hasTransitions |= iconColor.calculate(parameters); + hasTransitions |= iconHaloColor.calculate(parameters); + hasTransitions |= iconHaloWidth.calculate(parameters); + hasTransitions |= iconHaloBlur.calculate(parameters); + hasTransitions |= iconTranslate.calculate(parameters); + hasTransitions |= iconTranslateAnchor.calculate(parameters); + hasTransitions |= textOpacity.calculate(parameters); + hasTransitions |= textColor.calculate(parameters); + hasTransitions |= textHaloColor.calculate(parameters); + hasTransitions |= textHaloWidth.calculate(parameters); + hasTransitions |= textHaloBlur.calculate(parameters); + hasTransitions |= textTranslate.calculate(parameters); + hasTransitions |= textTranslateAnchor.calculate(parameters); + + return hasTransitions; +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp new file mode 100644 index 0000000000..38455b5cac --- /dev/null +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -0,0 +1,76 @@ +// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`. + +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class CascadeParameters; +class CalculationParameters; + +class SymbolLayoutProperties { +public: + void parse(const JSValue&); + void recalculate(const CalculationParameters&); + + LayoutProperty symbolPlacement { SymbolPlacementType::Point }; + LayoutProperty symbolSpacing { 250 }; + LayoutProperty symbolAvoidEdges { false }; + LayoutProperty iconAllowOverlap { false }; + LayoutProperty iconIgnorePlacement { false }; + LayoutProperty iconOptional { false }; + LayoutProperty iconRotationAlignment { RotationAlignmentType::Viewport }; + LayoutProperty iconSize { 1 }; + LayoutProperty iconImage { "" }; + LayoutProperty iconRotate { 0 }; + LayoutProperty iconPadding { 2 }; + LayoutProperty iconKeepUpright { false }; + LayoutProperty> iconOffset { {{ 0, 0 }} }; + LayoutProperty textRotationAlignment { RotationAlignmentType::Viewport }; + LayoutProperty textField { "" }; + LayoutProperty> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } }; + LayoutProperty textSize { 16 }; + LayoutProperty textMaxWidth { 10 }; + LayoutProperty textLineHeight { 1.2 }; + LayoutProperty textLetterSpacing { 0 }; + LayoutProperty textJustify { TextJustifyType::Center }; + LayoutProperty textAnchor { TextAnchorType::Center }; + LayoutProperty textMaxAngle { 45 }; + LayoutProperty textRotate { 0 }; + LayoutProperty textPadding { 2 }; + LayoutProperty textKeepUpright { true }; + LayoutProperty textTransform { TextTransformType::None }; + LayoutProperty> textOffset { {{ 0, 0 }} }; + LayoutProperty textAllowOverlap { false }; + LayoutProperty textIgnorePlacement { false }; + LayoutProperty textOptional { false }; +}; + +class SymbolPaintProperties { +public: + void parse(const JSValue&); + void cascade(const CascadeParameters&); + bool recalculate(const CalculationParameters&); + + PaintProperty iconOpacity { 1 }; + PaintProperty iconColor { {{ 0, 0, 0, 1 }} }; + PaintProperty iconHaloColor { {{ 0, 0, 0, 0 }} }; + PaintProperty iconHaloWidth { 0 }; + PaintProperty iconHaloBlur { 0 }; + PaintProperty> iconTranslate { {{ 0, 0 }} }; + PaintProperty iconTranslateAnchor { TranslateAnchorType::Map }; + PaintProperty textOpacity { 1 }; + PaintProperty textColor { {{ 0, 0, 0, 1 }} }; + PaintProperty textHaloColor { {{ 0, 0, 0, 0 }} }; + PaintProperty textHaloWidth { 0 }; + PaintProperty textHaloBlur { 0 }; + PaintProperty> textTranslate { {{ 0, 0 }} }; + PaintProperty textTranslateAnchor { TranslateAnchorType::Map }; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp index b4857aeae5..f5045b47fc 100644 --- a/src/mbgl/style/layout_property.hpp +++ b/src/mbgl/style/layout_property.hpp @@ -8,6 +8,7 @@ #include namespace mbgl { +namespace style { template class LayoutProperty { @@ -30,7 +31,7 @@ public: } } - void calculate(const StyleCalculationParameters& parameters) { + void calculate(const CalculationParameters& parameters) { if (currentValue) { PropertyEvaluator evaluator(parameters, defaultValue); value = PropertyValue::visit(currentValue, evaluator); @@ -46,4 +47,5 @@ private: PropertyValue currentValue; }; +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/observer.hpp b/src/mbgl/style/observer.hpp new file mode 100644 index 0000000000..c19f58904f --- /dev/null +++ b/src/mbgl/style/observer.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace style { + +class Observer : public GlyphStoreObserver, + public SpriteStoreObserver, + public SourceObserver { +public: + /** + * In addition to the individual glyph, sprite, and source events, the + * following "rollup" events are provided for convenience. They are + * strictly additive; e.g. when a source is loaded, both `onSourceLoaded` + * and `onResourceLoaded` will be called. + */ + virtual void onResourceLoaded() {}; + virtual void onResourceError(std::exception_ptr) {}; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 8428a90533..62fd59684e 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -3,9 +3,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -14,6 +14,7 @@ #include namespace mbgl { +namespace style { template class Evaluator = PropertyEvaluator> class PaintProperty { @@ -62,14 +63,14 @@ public: } if (it->value.HasMember(transitionName.c_str())) { - if (auto v = parsePropertyTransition(name, it->value[transitionName.c_str()])) { + if (auto v = parseTransitionOptions(name, it->value[transitionName.c_str()])) { transitions.emplace(classID, *v); } } } } - void cascade(const StyleCascadeParameters& params) { + void cascade(const CascadeParameters& params) { const bool overrideTransition = !params.transition.delay && !params.transition.duration; Duration delay = params.transition.delay.value_or(Duration::zero()); Duration duration = params.transition.duration.value_or(Duration::zero()); @@ -79,7 +80,7 @@ public: continue; if (overrideTransition && transitions.find(classID) != transitions.end()) { - const PropertyTransition& transition = transitions[classID]; + const TransitionOptions& transition = transitions[classID]; if (transition.delay) delay = *transition.delay; if (transition.duration) duration = *transition.duration; } @@ -95,7 +96,7 @@ public: assert(cascaded); } - bool calculate(const StyleCalculationParameters& parameters) { + bool calculate(const CalculationParameters& parameters) { assert(cascaded); Evaluator evaluator(parameters, defaultValue); value = cascaded->calculate(evaluator, parameters.now); @@ -109,7 +110,7 @@ public: private: T defaultValue; std::map> values; - std::map transitions; + std::map transitions; struct CascadedValue { CascadedValue(std::unique_ptr prior_, @@ -147,4 +148,5 @@ private: std::unique_ptr cascaded; }; +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp new file mode 100644 index 0000000000..28a7d2e81b --- /dev/null +++ b/src/mbgl/style/parser.cpp @@ -0,0 +1,689 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +namespace mbgl { +namespace style { + +namespace { + +void parseTileJSONMember(const JSValue& value, std::vector& target, const char* name) { + if (!value.HasMember(name)) { + return; + } + + const JSValue& property = value[name]; + if (!property.IsArray()) { + return; + } + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) { + if (!property[i].IsString()) { + return; + } + } + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) { + target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength())); + } +} + +void parseTileJSONMember(const JSValue& value, std::string& target, const char* name) { + if (!value.HasMember(name)) { + return; + } + + const JSValue& property = value[name]; + if (!property.IsString()) { + return; + } + + target = { property.GetString(), property.GetStringLength() }; +} + +void parseTileJSONMember(const JSValue& value, uint8_t& target, const char* name) { + if (!value.HasMember(name)) { + return; + } + + const JSValue& property = value[name]; + if (!property.IsUint()) { + return; + } + + unsigned int uint = property.GetUint(); + if (uint > std::numeric_limits::max()) { + return; + } + + target = uint; +} + +void parseTileJSONMember(const JSValue& value, std::array& target, const char* name) { + if (!value.HasMember(name)) { + return; + } + + const JSValue& property = value[name]; + if (!property.IsArray() || property.Size() > 4) { + return; + } + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) { + if (!property[i].IsNumber()) { + return; + } + } + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) { + target[i] = property[i].GetDouble(); + } +} + +} // end namespace + +Parser::~Parser() = default; + +void Parser::parse(const std::string& json) { + rapidjson::GenericDocument, rapidjson::CrtAllocator> document; + document.Parse<0>(json.c_str()); + + if (document.HasParseError()) { + Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError())); + return; + } + + if (document.HasMember("version")) { + int version = document["version"].GetInt(); + if (version != 8) { + Log::Warning(Event::ParseStyle, "current renderer implementation only supports style spec version 8; using an outdated style will cause rendering errors"); + } + } + + if (document.HasMember("sources")) { + parseSources(document["sources"]); + } + + if (document.HasMember("layers")) { + parseLayers(document["layers"]); + } + + if (document.HasMember("sprite")) { + const JSValue& sprite = document["sprite"]; + if (sprite.IsString()) { + spriteURL = { sprite.GetString(), sprite.GetStringLength() }; + } + } + + if (document.HasMember("glyphs")) { + const JSValue& glyphs = document["glyphs"]; + if (glyphs.IsString()) { + glyphURL = { glyphs.GetString(), glyphs.GetStringLength() }; + } + } +} + +void Parser::parseSources(const JSValue& value) { + if (!value.IsObject()) { + Log::Warning(Event::ParseStyle, "sources must be an object"); + return; + } + + JSValue::ConstMemberIterator itr = value.MemberBegin(); + for (; itr != value.MemberEnd(); ++itr) { + const JSValue& nameVal = itr->name; + const JSValue& sourceVal = itr->value; + + if (!sourceVal.HasMember("type")) { + Log::Warning(Event::ParseStyle, "source must have a type"); + continue; + } + + const JSValue& typeVal = sourceVal["type"]; + if (!typeVal.IsString()) { + Log::Warning(Event::ParseStyle, "source type must have one of the enum values"); + continue; + } + + const auto type = SourceTypeClass({ typeVal.GetString(), typeVal.GetStringLength() }); + + // Sources can have URLs, either because they reference an external TileJSON file, or + // because reference a GeoJSON file. They don't have to have one though when all source + // parameters are specified inline. + std::string url; + + uint16_t tileSize = util::tileSize; + + std::unique_ptr tileset; + std::unique_ptr geojsonvt; + + switch (type) { + case SourceType::Raster: + if (sourceVal.HasMember("tileSize")) { + const JSValue& tileSizeVal = sourceVal["tileSize"]; + if (tileSizeVal.IsNumber() && tileSizeVal.GetUint64() <= std::numeric_limits::max()) { + tileSize = tileSizeVal.GetUint64(); + } else { + Log::Error(Event::ParseStyle, "invalid tileSize"); + continue; + } + } + // Fall through. Vector sources are forbidden from having a tileSize. + + case SourceType::Vector: + if (sourceVal.HasMember("url")) { + const JSValue& urlVal = sourceVal["url"]; + if (urlVal.IsString()) { + url = { urlVal.GetString(), urlVal.GetStringLength() }; + } else { + Log::Error(Event::ParseStyle, "source url must be a string"); + continue; + } + } else { + tileset = parseTileJSON(sourceVal); + } + break; + + case SourceType::GeoJSON: + tileset = std::make_unique(); + + // We should probably split this up to have URLs in the url property, and actual data + // in the data property. Until then, we're going to detect the content based on the + // object type. + if (sourceVal.HasMember("data")) { + const JSValue& dataVal = sourceVal["data"]; + if (dataVal.IsString()) { + // We need to load an external GeoJSON file + url = { dataVal.GetString(), dataVal.GetStringLength() }; + } else if (dataVal.IsObject()) { + // We need to parse dataVal as a GeoJSON object + geojsonvt = parseGeoJSON(dataVal); + tileset->maxZoom = geojsonvt->options.maxZoom; + } else { + Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object"); + continue; + } + } else { + Log::Error(Event::ParseStyle, "GeoJSON source must have a data value"); + continue; + } + + break; + + default: + Log::Error(Event::ParseStyle, "source type '%s' is not supported", typeVal.GetString()); + continue; + } + + const std::string id { nameVal.GetString(), nameVal.GetStringLength() }; + std::unique_ptr source = std::make_unique(type, id, url, tileSize, std::move(tileset), std::move(geojsonvt)); + + sourcesMap.emplace(id, source.get()); + sources.emplace_back(std::move(source)); + } +} + +std::unique_ptr parseGeoJSON(const JSValue& value) { + using namespace mapbox::geojsonvt; + + Options options; + options.buffer = util::EXTENT / util::tileSize * 128; + options.extent = util::EXTENT; + + try { + return std::make_unique(Convert::convert(value, 0), options); + } catch (const std::exception& ex) { + Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what()); + // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for + // tiles to load. + return std::make_unique(std::vector{}, options); + } +} + +std::unique_ptr parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type, uint16_t tileSize) { + rapidjson::GenericDocument, rapidjson::CrtAllocator> document; + document.Parse<0>(json.c_str()); + + if (document.HasParseError()) { + std::stringstream message; + message << document.GetErrorOffset() << " - " << rapidjson::GetParseError_En(document.GetParseError()); + throw std::runtime_error(message.str()); + } + + std::unique_ptr result = parseTileJSON(document); + + // TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with. + if (util::mapbox::isMapboxURL(sourceURL)) { + for (auto& url : result->tiles) { + url = util::mapbox::canonicalizeTileURL(url, type, tileSize); + } + } + + return result; +} + +std::unique_ptr parseTileJSON(const JSValue& value) { + auto tileset = std::make_unique(); + parseTileJSONMember(value, tileset->tiles, "tiles"); + parseTileJSONMember(value, tileset->minZoom, "minzoom"); + parseTileJSONMember(value, tileset->maxZoom, "maxzoom"); + parseTileJSONMember(value, tileset->attribution, "attribution"); + + std::array array; + parseTileJSONMember(value, array, "center"); + tileset->center = { array[0], array[1] }; + tileset->zoom = array[2]; + parseTileJSONMember(value, array, "bounds"); + tileset->bounds = LatLngBounds::hull({ array[0], array[1] }, { array[2], array[3] }); + + return tileset; +} + +void Parser::parseLayers(const JSValue& value) { + std::vector ids; + + if (!value.IsArray()) { + Log::Warning(Event::ParseStyle, "layers must be an array"); + return; + } + + for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { + const JSValue& layerValue = value[i]; + + if (!layerValue.IsObject()) { + Log::Warning(Event::ParseStyle, "layer must be an object"); + continue; + } + + if (!layerValue.HasMember("id")) { + Log::Warning(Event::ParseStyle, "layer must have an id"); + continue; + } + + const JSValue& id = layerValue["id"]; + if (!id.IsString()) { + Log::Warning(Event::ParseStyle, "layer id must be a string"); + continue; + } + + const std::string layerID = { id.GetString(), id.GetStringLength() }; + if (layersMap.find(layerID) != layersMap.end()) { + Log::Warning(Event::ParseStyle, "duplicate layer id %s", layerID.c_str()); + continue; + } + + layersMap.emplace(layerID, std::pair> { layerValue, nullptr }); + ids.push_back(layerID); + } + + for (const auto& id : ids) { + auto it = layersMap.find(id); + + parseLayer(it->first, + it->second.first, + it->second.second); + } + + for (const auto& id : ids) { + auto it = layersMap.find(id); + + if (it->second.second) { + layers.emplace_back(std::move(it->second.second)); + } + } +} + +void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique_ptr& layer) { + if (layer) { + // Skip parsing this again. We already have a valid layer definition. + return; + } + + // Make sure we have not previously attempted to parse this layer. + if (std::find(stack.begin(), stack.end(), id) != stack.end()) { + Log::Warning(Event::ParseStyle, "layer reference of '%s' is circular", id.c_str()); + return; + } + + if (value.HasMember("ref")) { + // This layer is referencing another layer. Recursively parse that layer. + const JSValue& refVal = value["ref"]; + if (!refVal.IsString()) { + Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", id.c_str()); + return; + } + + const std::string ref { refVal.GetString(), refVal.GetStringLength() }; + auto it = layersMap.find(ref); + if (it == layersMap.end()) { + Log::Warning(Event::ParseStyle, "layer '%s' references unknown layer %s", id.c_str(), ref.c_str()); + return; + } + + // Recursively parse the referenced layer. + stack.push_front(id); + parseLayer(it->first, + it->second.first, + it->second.second); + stack.pop_front(); + + Layer* reference = it->second.second.get(); + if (!reference) { + return; + } + + layer = reference->copy(id, ref); + layer->baseImpl->parsePaints(value); + } else { + // Otherwise, parse the source/source-layer/filter/render keys to form the bucket. + if (!value.HasMember("type")) { + Log::Warning(Event::ParseStyle, "layer '%s' is missing a type", id.c_str()); + return; + } + + const JSValue& typeVal = value["type"]; + if (!typeVal.IsString()) { + Log::Warning(Event::ParseStyle, "layer '%s' has an invalid type", id.c_str()); + return; + } + + std::string type { typeVal.GetString(), typeVal.GetStringLength() }; + + if (type == "fill") { + layer = std::make_unique(id); + } else if (type == "line") { + layer = std::make_unique(id); + } else if (type == "circle") { + layer = std::make_unique(id); + } else if (type == "symbol") { + layer = std::make_unique(id); + } else if (type == "raster") { + layer = std::make_unique(id); + } else if (type == "background") { + layer = std::make_unique(id); + } else { + Log::Warning(Event::ParseStyle, "unknown type '%s' for layer '%s'", type.c_str(), id.c_str()); + return; + } + + Layer::Impl* impl = layer->baseImpl.get(); + + if (value.HasMember("source")) { + const JSValue& value_source = value["source"]; + if (value_source.IsString()) { + impl->source = { value_source.GetString(), value_source.GetStringLength() }; + auto source_it = sourcesMap.find(impl->source); + if (source_it == sourcesMap.end()) { + Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", impl->source.c_str(), impl->id.c_str()); + } + } else { + Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", impl->id.c_str()); + } + } + + if (value.HasMember("source-layer")) { + const JSValue& value_source_layer = value["source-layer"]; + if (value_source_layer.IsString()) { + impl->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() }; + } else { + Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", impl->id.c_str()); + } + } + + if (value.HasMember("filter")) { + impl->filter = parseFilter(value["filter"]); + } + + if (value.HasMember("minzoom")) { + const JSValue& min_zoom = value["minzoom"]; + if (min_zoom.IsNumber()) { + impl->minZoom = min_zoom.GetDouble(); + } else { + Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", impl->id.c_str()); + } + } + + if (value.HasMember("maxzoom")) { + const JSValue& max_zoom = value["maxzoom"]; + if (max_zoom.IsNumber()) { + impl->maxZoom = max_zoom.GetDouble(); + } else { + Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", impl->id.c_str()); + } + } + + if (value.HasMember("layout")) { + parseVisibility(*layer, value["layout"]); + impl->parseLayout(value["layout"]); + } + + impl->parsePaints(value); + } +} + +MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, { + { VisibilityType::Visible, "visible" }, + { VisibilityType::None, "none" }, +}); + +void Parser::parseVisibility(Layer& layer, const JSValue& value) { + Layer::Impl& impl = *layer.baseImpl; + if (!value.HasMember("visibility")) { + return; + } else if (!value["visibility"].IsString()) { + Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string"); + impl.visibility = VisibilityType::Visible; + return; + } + impl.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() }); +} + +Value parseFeatureType(const Value& value) { + if (value == std::string("Point")) { + return Value(uint64_t(FeatureType::Point)); + } else if (value == std::string("LineString")) { + return Value(uint64_t(FeatureType::LineString)); + } else if (value == std::string("Polygon")) { + return Value(uint64_t(FeatureType::Polygon)); + } else { + Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon"); + return Value(uint64_t(FeatureType::Unknown)); + } +} + +Value parseValue(const JSValue& value) { + switch (value.GetType()) { + case rapidjson::kNullType: + case rapidjson::kFalseType: + return false; + + case rapidjson::kTrueType: + return true; + + case rapidjson::kStringType: + return std::string { value.GetString(), value.GetStringLength() }; + + case rapidjson::kNumberType: + if (value.IsUint64()) return value.GetUint64(); + if (value.IsInt64()) return value.GetInt64(); + return value.GetDouble(); + + default: + return false; + } +} + +template +Filter parseUnaryFilter(const JSValue& value) { + Filter empty; + + if (value.Size() < 2) { + Log::Warning(Event::ParseStyle, "filter expression must have 2 elements"); + return empty; + } + + if (!value[1u].IsString()) { + Log::Warning(Event::ParseStyle, "filter expression key must be a string"); + return empty; + } + + Expression expression; + expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; + return expression; +} + +template +Filter parseBinaryFilter(const JSValue& value) { + Filter empty; + + if (value.Size() < 3) { + Log::Warning(Event::ParseStyle, "filter expression must have 3 elements"); + return empty; + } + + if (!value[1u].IsString()) { + Log::Warning(Event::ParseStyle, "filter expression key must be a string"); + return empty; + } + + Expression expression; + expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; + expression.value = parseValue(value[2u]); + + if (expression.key == "$type") { + expression.value = parseFeatureType(expression.value); + } + + return expression; +} + +template +Filter parseSetFilter(const JSValue& value) { + Filter empty; + + if (value.Size() < 2) { + Log::Warning(Event::ParseStyle, "filter expression must at least 2 elements"); + return empty; + } + + if (!value[1u].IsString()) { + Log::Warning(Event::ParseStyle, "filter expression key must be a string"); + return empty; + } + + Expression expression; + expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; + for (rapidjson::SizeType i = 2; i < value.Size(); ++i) { + Value parsedValue = parseValue(value[i]); + if (expression.key == "$type") { + parsedValue = parseFeatureType(parsedValue); + } + expression.values.push_back(parsedValue); + } + return expression; +} + +template +Filter parseCompoundFilter(const JSValue& value) { + Expression expression; + for (rapidjson::SizeType i = 1; i < value.Size(); ++i) { + expression.filters.push_back(parseFilter(value[i])); + } + return expression; +} + +Filter parseFilter(const JSValue& value) { + Filter empty; + + if (!value.IsArray()) { + Log::Warning(Event::ParseStyle, "filter expression must be an array"); + return empty; + } + + if (value.Size() < 1) { + Log::Warning(Event::ParseStyle, "filter expression must have at least 1 element"); + return empty; + } + + if (!value[0u].IsString()) { + Log::Warning(Event::ParseStyle, "filter operator must be a string"); + return empty; + } + + std::string op = { value[0u].GetString(), value[0u].GetStringLength() }; + + if (op == "==") { + return parseBinaryFilter(value); + } else if (op == "!=") { + return parseBinaryFilter(value); + } else if (op == ">") { + return parseBinaryFilter(value); + } else if (op == ">=") { + return parseBinaryFilter(value); + } else if (op == "<") { + return parseBinaryFilter(value); + } else if (op == "<=") { + return parseBinaryFilter(value); + } else if (op == "in") { + return parseSetFilter(value); + } else if (op == "!in") { + return parseSetFilter(value); + } else if (op == "all") { + return parseCompoundFilter(value); + } else if (op == "any") { + return parseCompoundFilter(value); + } else if (op == "none") { + return parseCompoundFilter(value); + } else if (op == "has") { + return parseUnaryFilter(value); + } else if (op == "!has") { + return parseUnaryFilter(value); + } else { + Log::Warning(Event::ParseStyle, "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\", \"has\", or \"!has\""); + return empty; + } +} + +std::vector Parser::fontStacks() const { + std::set result; + + for (const auto& layer : layers) { + if (layer->is()) { + PropertyValue textFont = layer->as()->getTextFont(); + if (textFont.isUndefined()) { + result.insert({"Open Sans Regular", "Arial Unicode MS Regular"}); + } else if (textFont.isConstant()) { + result.insert(textFont.asConstant()); + } else if (textFont.isFunction()) { + for (const auto& stop : textFont.asFunction().getStops()) { + result.insert(stop.second); + } + } + } + } + + return std::vector(result.begin(), result.end()); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/parser.hpp b/src/mbgl/style/parser.hpp new file mode 100644 index 0000000000..ea821fabde --- /dev/null +++ b/src/mbgl/style/parser.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace mbgl { +namespace style { + +std::unique_ptr parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType, uint16_t tileSize); +std::unique_ptr parseTileJSON(const JSValue&); + +std::unique_ptr parseGeoJSON(const JSValue&); + +Filter parseFilter(const JSValue&); + +class Parser { +public: + ~Parser(); + + void parse(const std::string&); + + std::string spriteURL; + std::string glyphURL; + + std::vector> sources; + std::vector> layers; + + // Statically evaluate layer properties to determine what font stacks are used. + std::vector fontStacks() const; + +private: + void parseSources(const JSValue&); + void parseLayers(const JSValue&); + void parseLayer(const std::string& id, const JSValue&, std::unique_ptr&); + void parseVisibility(Layer&, const JSValue& value); + + std::unordered_map sourcesMap; + std::unordered_map>> layersMap; + + // Store a stack of layer IDs we're parsing right now. This is to prevent reference cycles. + std::forward_list stack; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/property_evaluator.cpp b/src/mbgl/style/property_evaluator.cpp index 08eea899c2..d2e633c782 100644 --- a/src/mbgl/style/property_evaluator.cpp +++ b/src/mbgl/style/property_evaluator.cpp @@ -1,12 +1,14 @@ #include -#include +#include #include #include #include +#include #include namespace mbgl { +namespace style { template inline T defaultStopsValue(); @@ -140,4 +142,5 @@ Faded CrossFadedPropertyEvaluator::calculate(const T& min, const T& mid, c template class CrossFadedPropertyEvaluator; template class CrossFadedPropertyEvaluator>; +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/property_evaluator.hpp b/src/mbgl/style/property_evaluator.hpp index 112c373a44..77100bda46 100644 --- a/src/mbgl/style/property_evaluator.hpp +++ b/src/mbgl/style/property_evaluator.hpp @@ -4,15 +4,16 @@ #include namespace mbgl { +namespace style { -class StyleCalculationParameters; +class CalculationParameters; template class PropertyEvaluator { public: using ResultType = T; - PropertyEvaluator(const StyleCalculationParameters& parameters_, const T& defaultValue_) + PropertyEvaluator(const CalculationParameters& parameters_, const T& defaultValue_) : parameters(parameters_), defaultValue(defaultValue_) {} @@ -21,7 +22,7 @@ public: T operator()(const Function&) const; private: - const StyleCalculationParameters& parameters; + const CalculationParameters& parameters; T defaultValue; }; @@ -39,7 +40,7 @@ class CrossFadedPropertyEvaluator { public: using ResultType = Faded; - CrossFadedPropertyEvaluator(const StyleCalculationParameters& parameters_, const T& defaultValue_) + CrossFadedPropertyEvaluator(const CalculationParameters& parameters_, const T& defaultValue_) : parameters(parameters_), defaultValue(defaultValue_) {} @@ -50,13 +51,15 @@ public: private: Faded calculate(const T& min, const T& mid, const T& max) const; - const StyleCalculationParameters& parameters; + const CalculationParameters& parameters; T defaultValue; }; +} // namespace style + namespace util { template -struct Interpolator> +struct Interpolator> : Uninterpolated {}; } diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp index 67baa3ec8d..9f60ddf3b6 100644 --- a/src/mbgl/style/property_parsing.cpp +++ b/src/mbgl/style/property_parsing.cpp @@ -1,11 +1,11 @@ #include -#include #include #include namespace mbgl { +namespace style { template <> optional parseConstant(const char* name, const JSValue& value) { @@ -264,7 +264,7 @@ optional> parseConstant(const char* name, const JSValue return result; } -optional parsePropertyTransition(const char *, const JSValue& value) { +optional parseTransitionOptions(const char *, const JSValue& value) { if (!value.IsObject()) { return {}; } @@ -283,7 +283,8 @@ optional parsePropertyTransition(const char *, const JSValue return {}; } - return PropertyTransition(duration, delay); + return TransitionOptions(duration, delay); } +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp index c0fe5ce2bc..bb894c2407 100644 --- a/src/mbgl/style/property_parsing.hpp +++ b/src/mbgl/style/property_parsing.hpp @@ -2,10 +2,11 @@ #include #include -#include +#include #include #include +#include #include @@ -14,6 +15,7 @@ #include namespace mbgl { +namespace style { template optional parseConstant(const char* name, const JSValue&); @@ -104,6 +106,7 @@ PropertyValue parseProperty(const char* name, const JSValue& value) { return Function(stops, base); } -optional parsePropertyTransition(const char * name, const JSValue&); +optional parseTransitionOptions(const char * name, const JSValue&); +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/property_value.hpp b/src/mbgl/style/property_value.hpp deleted file mode 100644 index 377e4f17e0..0000000000 --- a/src/mbgl/style/property_value.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -namespace mbgl { - -class Undefined {}; - -template -class PropertyValue { -private: - using Value = variant>; - Value value; - -public: - PropertyValue() : value() {} - PropertyValue( T constant) : value(constant) {} - PropertyValue(Function function) : value(function) {} - - bool isUndefined() const { return value.which() == 0; } - bool isConstant() const { return value.which() == 1; } - bool isFunction() const { return value.which() == 2; } - - const T & asConstant() const { return value.template get< T >(); } - const Function& asFunction() const { return value.template get>(); } - - explicit operator bool() const { return !isUndefined(); }; - - template - static auto visit(const PropertyValue& value, Visitor&& visitor) { - return Value::visit(value.value, visitor); - } -}; - -} diff --git a/src/mbgl/style/query_parameters.hpp b/src/mbgl/style/query_parameters.hpp new file mode 100644 index 0000000000..3c1abf3b70 --- /dev/null +++ b/src/mbgl/style/query_parameters.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include + +namespace mbgl { + +class TransformState; + +namespace style { + +class QueryParameters { +public: + const ScreenLineString& geometry; + const TransformState& transformState; + const optional>& layerIDs; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/render_item.hpp b/src/mbgl/style/render_item.hpp index ebf6799828..da59591c36 100644 --- a/src/mbgl/style/render_item.hpp +++ b/src/mbgl/style/render_item.hpp @@ -2,12 +2,15 @@ namespace mbgl { -class Layer; class Tile; class Bucket; +namespace style { +class Layer; +} + struct RenderItem { - inline RenderItem(const Layer& layer_, + inline RenderItem(const style::Layer& layer_, const Tile* tile_ = nullptr, Bucket* bucket_ = nullptr) : tile(tile_), bucket(bucket_), layer(layer_) { @@ -15,7 +18,7 @@ struct RenderItem { const Tile* const tile; Bucket* const bucket; - const Layer& layer; + const style::Layer& layer; }; } // namespace mbgl diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp new file mode 100644 index 0000000000..8e5973f412 --- /dev/null +++ b/src/mbgl/style/source.cpp @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace mbgl { +namespace style { + +static SourceObserver nullObserver; + +Source::Source(SourceType type_, + const std::string& id_, + const std::string& url_, + uint16_t tileSize_, + std::unique_ptr&& tileset_, + std::unique_ptr&& geojsonvt_) + : type(type_), + id(id_), + url(url_), + tileSize(tileSize_), + tileset(std::move(tileset_)), + geojsonvt(std::move(geojsonvt_)), + observer(&nullObserver) { +} + +Source::~Source() = default; + +bool Source::isLoaded() const { + if (!loaded) return false; + + for (const auto& pair : tileDataMap) { + if (!pair.second->isComplete()) { + return false; + } + } + + return true; +} + +bool Source::isLoading() const { + return !loaded && req.operator bool(); +} + +void Source::load(FileSource& fileSource) { + if (url.empty()) { + // In case there is no URL set, we assume that we already have all of the data because the + // TileJSON was specified inline in the stylesheet. + loaded = true; + return; + } + + if (req) { + // We don't have a Tileset object yet, but there's already a request underway to load + // the data. + return; + } + + // URL may either be a TileJSON file, or a GeoJSON file. + req = fileSource.request(Resource::source(url), [this](Response res) { + if (res.error) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message))); + } else if (res.notModified) { + return; + } else if (res.noContent) { + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty source"))); + } else { + bool reloadTiles = false; + + if (type == SourceType::Vector || type == SourceType::Raster) { + std::unique_ptr newTileset; + + // Create a new copy of the Tileset object that holds the base values we've parsed + // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved + // via the URL. + try { + newTileset = style::parseTileJSON(*res.data, url, type, tileSize); + } catch (...) { + observer->onSourceError(*this, std::current_exception()); + return; + } + + // Check whether previous information specifies different tile + if (tileset && tileset->tiles != newTileset->tiles) { + reloadTiles = true; + + // Tile size changed: We need to recalculate the tiles we need to load because we + // might have to load tiles for a different zoom level + // This is done automatically when we trigger the onSourceLoaded observer below. + + // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles + // loaded that are outside the new zoom range + // This is done automatically when we trigger the onSourceLoaded observer below. + + // Attribution changed: We need to notify the embedding application that this + // changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723 + // This is not yet implemented. + + // Center/bounds changed: We're not using these values currently + } + + tileset = std::move(newTileset); + } else if (type == SourceType::GeoJSON) { + std::unique_ptr newTileset = std::make_unique(); + + rapidjson::GenericDocument, rapidjson::CrtAllocator> d; + d.Parse<0>(res.data->c_str()); + + if (d.HasParseError()) { + std::stringstream message; + message << d.GetErrorOffset() << " - " << rapidjson::GetParseError_En(d.GetParseError()); + observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(message.str()))); + return; + } + + geojsonvt = style::parseGeoJSON(d); + reloadTiles = true; + + newTileset->maxZoom = geojsonvt->options.maxZoom; + tileset = std::move(newTileset); + } + + if (reloadTiles) { + // Tile information changed because we got new GeoJSON data, or a new tile URL. + tileDataMap.clear(); + tiles.clear(); + cache.clear(); + } + + loaded = true; + observer->onSourceLoaded(*this); + } + }); +} + +void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) { + for (auto& pair : tiles) { + auto& tile = pair.second; + transform.matrixFor(tile.matrix, tile.id); + matrix::multiply(tile.matrix, projMatrix, tile.matrix); + } +} + +void Source::finishRender(Painter &painter) { + for (auto& pair : tiles) { + auto& tile = pair.second; + painter.renderTileDebug(tile); + } +} + +const std::map& Source::getTiles() const { + return tiles; +} + +std::unique_ptr Source::createTile(const OverscaledTileID& overscaledTileID, + const UpdateParameters& parameters) { + std::unique_ptr data = cache.get(overscaledTileID); + if (data) { + return data; + } + + auto callback = std::bind(&Source::tileLoadingCallback, this, overscaledTileID, + std::placeholders::_1, true); + + // If we don't find working tile data, we're just going to load it. + if (type == SourceType::Raster) { + data = std::make_unique(overscaledTileID, parameters.pixelRatio, + tileset->tiles.at(0), parameters.texturePool, + parameters.worker, parameters.fileSource, callback); + } else { + std::unique_ptr monitor; + + if (type == SourceType::Vector) { + monitor = std::make_unique(overscaledTileID, parameters.pixelRatio, tileset->tiles.at(0), parameters.fileSource); + } else if (type == SourceType::Annotations) { + monitor = std::make_unique(overscaledTileID, parameters.annotationManager); + } else if (type == SourceType::GeoJSON) { + monitor = std::make_unique(geojsonvt.get(), overscaledTileID); + } else { + Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(type).c_str()); + return nullptr; + } + + data = std::make_unique(overscaledTileID, std::move(monitor), id, + parameters.style, parameters.mode, callback); + } + + return data; +} + +TileData* Source::getTileData(const OverscaledTileID& overscaledTileID) const { + auto it = tileDataMap.find(overscaledTileID); + if (it != tileDataMap.end()) { + return it->second.get(); + } else { + return nullptr; + } +} + +bool Source::update(const UpdateParameters& parameters) { + bool allTilesUpdated = true; + + if (!loaded || parameters.animationTime <= updated) { + return allTilesUpdated; + } + + // Determine the overzooming/underzooming amounts and required tiles. + int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize); + int32_t dataTileZoom = overscaledZoom; + + std::vector idealTiles; + if (overscaledZoom >= tileset->minZoom) { + int32_t idealZoom = std::min(tileset->maxZoom, overscaledZoom); + + // Make sure we're not reparsing overzoomed raster tiles. + if (type == SourceType::Raster) { + dataTileZoom = idealZoom; + } + + idealTiles = util::tileCover(parameters.transformState, idealZoom); + } + + // Stores a list of all the data tiles that we're definitely going to retain. There are two + // kinds of tiles we need: the ideal tiles determined by the tile cover. They may not yet be in + // use because they're still loading. In addition to that, we also need to retain all tiles that + // we're actively using, e.g. as a replacement for tile that aren't loaded yet. + std::set retain; + + auto retainTileDataFn = [&retain](const TileData& tileData) -> void { + retain.emplace(tileData.id); + }; + auto getTileDataFn = [this](const OverscaledTileID& dataTileID) -> TileData* { + return getTileData(dataTileID); + }; + auto createTileDataFn = [this, ¶meters](const OverscaledTileID& dataTileID) -> TileData* { + if (auto data = createTile(dataTileID, parameters)) { + return tileDataMap.emplace(dataTileID, std::move(data)).first->second.get(); + } else { + return nullptr; + } + }; + auto renderTileFn = [this](const UnwrappedTileID& renderTileID, TileData& tileData) { + tiles.emplace(renderTileID, Tile{ renderTileID, tileData }); + }; + + tiles.clear(); + algorithm::updateRenderables(getTileDataFn, createTileDataFn, retainTileDataFn, renderTileFn, + idealTiles, *tileset, dataTileZoom); + + if (type != SourceType::Raster && type != SourceType::Annotations && cache.getSize() == 0) { + size_t conservativeCacheSize = + ((float)parameters.transformState.getWidth() / util::tileSize) * + ((float)parameters.transformState.getHeight() / util::tileSize) * + (parameters.transformState.getMaxZoom() - parameters.transformState.getMinZoom() + 1) * + 0.5; + cache.setSize(conservativeCacheSize); + } + + // Remove stale data tiles from the active set of tiles. + // This goes through the (sorted!) tileDataMap and retain set in lockstep and removes items from + // tileDataMap that don't have the corresponding key in the retain set. + auto dataIt = tileDataMap.begin(); + auto retainIt = retain.begin(); + while (dataIt != tileDataMap.end()) { + if (retainIt == retain.end() || dataIt->first < *retainIt) { + cache.add(dataIt->first, std::move(dataIt->second)); + tileDataMap.erase(dataIt++); + } else { + if (!(*retainIt < dataIt->first)) { + ++dataIt; + } + ++retainIt; + } + } + + for (auto& pair : tileDataMap) { + const auto& dataTileID = pair.first; + auto tileData = pair.second.get(); + if (parameters.shouldReparsePartialTiles && tileData->isIncomplete()) { + auto callback = std::bind(&Source::tileLoadingCallback, this, dataTileID, + std::placeholders::_1, false); + + if (!tileData->parsePending(callback)) { + allTilesUpdated = false; + } + } else { + tileData->redoPlacement({ parameters.transformState.getAngle(), + parameters.transformState.getPitch(), + parameters.debugOptions & MapDebugOptions::Collision }, + [this]() { observer->onPlacementRedone(); }); + } + } + + updated = parameters.animationTime; + + return allTilesUpdated; +} + +static Point coordinateToTilePoint(const UnwrappedTileID& tileID, const Point& p) { + auto zoomedCoord = TileCoordinate { p, 0 }.zoomTo(tileID.canonical.z); + return { + int16_t(util::clamp((zoomedCoord.p.x - tileID.canonical.x - tileID.wrap * std::pow(2, tileID.canonical.z)) * util::EXTENT, + std::numeric_limits::min(), + std::numeric_limits::max())), + int16_t(util::clamp((zoomedCoord.p.y - tileID.canonical.y) * util::EXTENT, + std::numeric_limits::min(), + std::numeric_limits::max())) + }; +} + +std::unordered_map> Source::queryRenderedFeatures(const QueryParameters& parameters) const { + LineString queryGeometry; + + for (const auto& p : parameters.geometry) { + queryGeometry.push_back(TileCoordinate::fromScreenCoordinate( + parameters.transformState, 0, { p.x, parameters.transformState.getHeight() - p.y }).p); + } + + mapbox::geometry::box box = mapbox::geometry::envelope(queryGeometry); + + std::unordered_map> result; + + for (const auto& tilePtr : tiles) { + const Tile& tile = tilePtr.second; + + Point tileSpaceBoundsMin = coordinateToTilePoint(tile.id, box.min); + Point tileSpaceBoundsMax = coordinateToTilePoint(tile.id, box.max); + + if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT || + tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) continue; + + GeometryCoordinates tileSpaceQueryGeometry; + + for (const auto& c : queryGeometry) { + tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c)); + } + + tile.data.queryRenderedFeatures(result, + tileSpaceQueryGeometry, + parameters.transformState, + parameters.layerIDs); + } + + return result; +} + +void Source::setCacheSize(size_t size) { + cache.setSize(size); +} + +void Source::onLowMemory() { + cache.clear(); +} + +void Source::setObserver(SourceObserver* observer_) { + observer = observer_; +} + +void Source::tileLoadingCallback(const OverscaledTileID& tileID, + std::exception_ptr error, + bool isNewTile) { + auto it = tileDataMap.find(tileID); + if (it == tileDataMap.end()) { + return; + } + + auto& tileData = it->second; + if (!tileData) { + return; + } + + if (error) { + observer->onTileError(*this, tileID, error); + return; + } + + tileData->redoPlacement([this]() { + observer->onPlacementRedone(); + }); + observer->onTileLoaded(*this, tileID, isNewTile); +} + +void Source::dumpDebugLogs() const { + Log::Info(Event::General, "Source::id: %s", id.c_str()); + Log::Info(Event::General, "Source::loaded: %d", loaded); + + for (const auto& pair : tileDataMap) { + auto& tileData = pair.second; + tileData->dumpDebugLogs(); + } +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/source.hpp b/src/mbgl/style/source.hpp new file mode 100644 index 0000000000..cadc45c25c --- /dev/null +++ b/src/mbgl/style/source.hpp @@ -0,0 +1,113 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace mapbox { +namespace geojsonvt { +class GeoJSONVT; +} // namespace geojsonvt +} // namespace mapbox + +namespace mbgl { + +class Painter; +class FileSource; +class AsyncRequest; +class TransformState; +class Tile; +struct ClipID; + +namespace style { + +class Style; +class UpdateParameters; +class QueryParameters; +class SourceObserver; + +class Source : private util::noncopyable { +public: + Source(SourceType, + const std::string& id, + const std::string& url, + uint16_t tileSize, + std::unique_ptr&&, + std::unique_ptr&&); + ~Source(); + + bool loaded = false; + void load(FileSource&); + bool isLoading() const; + bool isLoaded() const; + + const Tileset* getTileset() const { return tileset.get(); } + + // Request or parse all the tiles relevant for the "TransformState". This method + // will return true if all the tiles were scheduled for updating of false if + // they were not. shouldReparsePartialTiles must be set to "true" if there is + // new data available that a tile in the "partial" state might be interested at. + bool update(const UpdateParameters&); + + template + void updateClipIDs(ClipIDGenerator& generator) { + generator.update(tiles); + } + + void updateMatrices(const mat4 &projMatrix, const TransformState &transform); + void finishRender(Painter &painter); + + const std::map& getTiles() const; + + TileData* getTileData(const OverscaledTileID&) const; + + std::unordered_map> + queryRenderedFeatures(const QueryParameters&) const; + + void setCacheSize(size_t); + void onLowMemory(); + + void setObserver(SourceObserver* observer); + void dumpDebugLogs() const; + + const SourceType type; + const std::string id; + const std::string url; + uint16_t tileSize = util::tileSize; + bool enabled = false; + +private: + void tileLoadingCallback(const OverscaledTileID&, std::exception_ptr, bool isNewTile); + + std::unique_ptr createTile(const OverscaledTileID&, const UpdateParameters&); + +private: + std::unique_ptr tileset; + + std::unique_ptr geojsonvt; + + // Stores the time when this source was most recently updated. + TimePoint updated = TimePoint::min(); + + std::map tiles; + std::map> tileDataMap; + TileCache cache; + + std::unique_ptr req; + + SourceObserver* observer = nullptr; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/source_observer.hpp b/src/mbgl/style/source_observer.hpp new file mode 100644 index 0000000000..a669e8e756 --- /dev/null +++ b/src/mbgl/style/source_observer.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace mbgl { + +class OverscaledTileID; + +namespace style { + +class Source; + +class SourceObserver { +public: + virtual ~SourceObserver() = default; + + virtual void onSourceLoaded(Source&) {} + virtual void onSourceError(Source&, std::exception_ptr) {} + virtual void onTileLoaded(Source&, const OverscaledTileID&, bool /* isNewTile */) {} + virtual void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) {} + virtual void onPlacementRedone() {} +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index ee847ccf57..136c98df03 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -1,23 +1,23 @@ #include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -30,10 +30,11 @@ #include namespace mbgl { +namespace style { -static StyleObserver nullObserver; +static Observer nullObserver; -bool Style::addClass(const std::string& className, const PropertyTransition& properties) { +bool Style::addClass(const std::string& className, const TransitionOptions& properties) { if (std::find(classes.begin(), classes.end(), className) != classes.end()) return false; classes.push_back(className); transitionProperties = properties; @@ -44,7 +45,7 @@ bool Style::hasClass(const std::string& className) const { return std::find(classes.begin(), classes.end(), className) != classes.end(); } -bool Style::removeClass(const std::string& className, const PropertyTransition& properties) { +bool Style::removeClass(const std::string& className, const TransitionOptions& properties) { const auto it = std::find(classes.begin(), classes.end(), className); if (it != classes.end()) { classes.erase(it); @@ -54,7 +55,7 @@ bool Style::removeClass(const std::string& className, const PropertyTransition& return false; } -void Style::setClasses(const std::vector& classNames, const PropertyTransition& properties) { +void Style::setClasses(const std::vector& classNames, const TransitionOptions& properties) { classes = classNames; transitionProperties = properties; } @@ -81,7 +82,7 @@ void Style::setJSON(const std::string& json, const std::string&) { layers.clear(); classes.clear(); - StyleParser parser; + Parser parser; parser.parse(json); for (auto& source : parser.sources) { @@ -153,7 +154,7 @@ void Style::removeLayer(const std::string& id) { layers.erase(it); } -void Style::update(const StyleUpdateParameters& parameters) { +void Style::update(const UpdateParameters& parameters) { bool allTilesUpdated = true; for (const auto& source : sources) { @@ -172,7 +173,7 @@ void Style::update(const StyleUpdateParameters& parameters) { void Style::cascade(const TimePoint& timePoint, MapMode mode) { // When in continuous mode, we can either have user- or style-defined // transitions. Still mode is always immediate. - static const PropertyTransition immediateTransition; + static const TransitionOptions immediateTransition; std::vector classIDs; for (const auto& className : classes) { @@ -181,7 +182,7 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) { classIDs.push_back(ClassID::Default); classIDs.push_back(ClassID::Fallback); - const StyleCascadeParameters parameters { + const CascadeParameters parameters { classIDs, mode == MapMode::Continuous ? timePoint : Clock::time_point::max(), mode == MapMode::Continuous ? transitionProperties.value_or(immediateTransition) : immediateTransition @@ -201,7 +202,7 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) { zoomHistory.update(z, timePoint); - const StyleCalculationParameters parameters { + const CalculationParameters parameters { z, mode == MapMode::Continuous ? timePoint : Clock::time_point::max(), zoomHistory, @@ -325,7 +326,7 @@ RenderData Style::getRenderData() const { return result; } -std::vector Style::queryRenderedFeatures(const StyleQueryParameters& parameters) const { +std::vector Style::queryRenderedFeatures(const QueryParameters& parameters) const { std::unordered_map> resultsByLayer; for (const auto& source : sources) { @@ -367,7 +368,7 @@ void Style::onLowMemory() { } } -void Style::setObserver(StyleObserver* observer_) { +void Style::setObserver(style::Observer* observer_) { observer = observer_; } @@ -440,4 +441,5 @@ void Style::dumpDebugLogs() const { spriteStore->dumpDebugLogs(); } +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 6892f4967a..49af674336 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -1,20 +1,21 @@ #pragma once #include -#include -#include -#include +#include -#include +#include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -25,20 +26,20 @@ namespace mbgl { class FileSource; class GlyphAtlas; -class GlyphStore; -class SpriteStore; class SpriteAtlas; class LineAtlas; -class StyleUpdateParameters; -class StyleQueryParameters; -class StyleObserver; struct RenderData { Color backgroundColor = {{ 0, 0, 0, 0 }}; - std::set sources; + std::set sources; std::vector order; }; +namespace style { + +class UpdateParameters; +class QueryParameters; + class Style : public GlyphStoreObserver, public SpriteStoreObserver, public SourceObserver, @@ -49,13 +50,13 @@ public: void setJSON(const std::string& data, const std::string& base); - void setObserver(StyleObserver*); + void setObserver(Observer*); bool isLoaded() const; // Fetch the tiles needed by the current viewport and emit a signal when // a tile is ready so observers can render the tile. - void update(const StyleUpdateParameters&); + void update(const UpdateParameters&); void cascade(const TimePoint&, MapMode); void recalculate(float z, const TimePoint&, MapMode); @@ -75,15 +76,15 @@ public: optional beforeLayerID = {}); void removeLayer(const std::string& layerID); - bool addClass(const std::string&, const PropertyTransition& = {}); - bool removeClass(const std::string&, const PropertyTransition& = {}); + bool addClass(const std::string&, const TransitionOptions& = {}); + bool removeClass(const std::string&, const TransitionOptions& = {}); bool hasClass(const std::string&) const; - void setClasses(const std::vector&, const PropertyTransition& = {}); + void setClasses(const std::vector&, const TransitionOptions& = {}); std::vector getClasses() const; RenderData getRenderData() const; - std::vector queryRenderedFeatures(const StyleQueryParameters&) const; + std::vector queryRenderedFeatures(const QueryParameters&) const; float getQueryRadius() const; @@ -103,7 +104,7 @@ private: std::vector> sources; std::vector> layers; std::vector classes; - optional transitionProperties; + optional transitionProperties; std::vector>::const_iterator findLayer(const std::string& layerID) const; @@ -122,7 +123,8 @@ private: void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) override; void onPlacementRedone() override; - StyleObserver* observer = nullptr; + Observer nullObserver; + Observer* observer = &nullObserver; std::exception_ptr lastError; @@ -135,4 +137,5 @@ public: Worker workers; }; +} // namespace style } // namespace mbgl diff --git a/src/mbgl/style/style_bucket_parameters.cpp b/src/mbgl/style/style_bucket_parameters.cpp deleted file mode 100644 index 0b4b2affcd..0000000000 --- a/src/mbgl/style/style_bucket_parameters.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -namespace mbgl { - -void StyleBucketParameters::eachFilteredFeature(const Filter& filter, - std::function function) { - auto name = layer.getName(); - for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) { - auto feature = layer.getFeature(i); - - FilterEvaluator evaluator(*feature); - if (!Filter::visit(filter, evaluator)) - continue; - - function(*feature, i, name); - } -} - -} // namespace mbgl diff --git a/src/mbgl/style/style_bucket_parameters.hpp b/src/mbgl/style/style_bucket_parameters.hpp deleted file mode 100644 index 17639afae7..0000000000 --- a/src/mbgl/style/style_bucket_parameters.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -namespace mbgl { - -class TileID; -class GeometryTileLayer; -class GeometryTileFeature; -class SpriteStore; -class GlyphAtlas; -class GlyphStore; -class CollisionTile; -class FeatureIndex; - -class StyleBucketParameters { -public: - StyleBucketParameters(const OverscaledTileID& tileID_, - const GeometryTileLayer& layer_, - const std::atomic& obsolete_, - uintptr_t tileUID_, - bool& partialParse_, - SpriteStore& spriteStore_, - GlyphAtlas& glyphAtlas_, - GlyphStore& glyphStore_, - FeatureIndex& featureIndex_, - const MapMode mode_) - : tileID(tileID_), - layer(layer_), - obsolete(obsolete_), - tileUID(tileUID_), - partialParse(partialParse_), - spriteStore(spriteStore_), - glyphAtlas(glyphAtlas_), - glyphStore(glyphStore_), - featureIndex(featureIndex_), - mode(mode_) {} - - bool cancelled() const { - return obsolete; - } - - void eachFilteredFeature(const Filter&, std::function); - - const OverscaledTileID& tileID; - const GeometryTileLayer& layer; - const std::atomic& obsolete; - uintptr_t tileUID; - bool& partialParse; - SpriteStore& spriteStore; - GlyphAtlas& glyphAtlas; - GlyphStore& glyphStore; - FeatureIndex& featureIndex; - const MapMode mode; -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_calculation_parameters.hpp b/src/mbgl/style/style_calculation_parameters.hpp deleted file mode 100644 index 1c50bd6128..0000000000 --- a/src/mbgl/style/style_calculation_parameters.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -namespace mbgl { - -class StyleCalculationParameters { -public: - explicit StyleCalculationParameters(float z_) - : z(z_) {} - - StyleCalculationParameters(float z_, - const TimePoint& now_, - const ZoomHistory& zoomHistory_, - const Duration& defaultFadeDuration_) - : z(z_), - now(now_), - zoomHistory(zoomHistory_), - defaultFadeDuration(defaultFadeDuration_) {} - - float z; - TimePoint now; - ZoomHistory zoomHistory; - Duration defaultFadeDuration; -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_cascade_parameters.hpp b/src/mbgl/style/style_cascade_parameters.hpp deleted file mode 100644 index 569145bd04..0000000000 --- a/src/mbgl/style/style_cascade_parameters.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace mbgl { - -class PropertyTransition; - -class StyleCascadeParameters { -public: - std::vector classes; - TimePoint now; - PropertyTransition transition; -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_observer.hpp b/src/mbgl/style/style_observer.hpp deleted file mode 100644 index 9e2c946f7d..0000000000 --- a/src/mbgl/style/style_observer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { - -class StyleObserver : public GlyphStoreObserver, public SpriteStoreObserver, public SourceObserver { -public: - virtual ~StyleObserver() = default; - - /** - * In addition to the individual glyph, sprite, and source events, the - * following "rollup" events are provided for convenience. They are - * strictly additive; e.g. when a source is loaded, both `onSourceLoaded` - * and `onResourceLoaded` will be called. - */ - virtual void onResourceLoaded() {} - virtual void onResourceError(std::exception_ptr) {} -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp deleted file mode 100644 index 95ab36498d..0000000000 --- a/src/mbgl/style/style_parser.cpp +++ /dev/null @@ -1,688 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -namespace mbgl { - - -namespace { - -void parseTileJSONMember(const JSValue& value, std::vector& target, const char* name) { - if (!value.HasMember(name)) { - return; - } - - const JSValue& property = value[name]; - if (!property.IsArray()) { - return; - } - - for (rapidjson::SizeType i = 0; i < property.Size(); i++) { - if (!property[i].IsString()) { - return; - } - } - - for (rapidjson::SizeType i = 0; i < property.Size(); i++) { - target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength())); - } -} - -void parseTileJSONMember(const JSValue& value, std::string& target, const char* name) { - if (!value.HasMember(name)) { - return; - } - - const JSValue& property = value[name]; - if (!property.IsString()) { - return; - } - - target = { property.GetString(), property.GetStringLength() }; -} - -void parseTileJSONMember(const JSValue& value, uint8_t& target, const char* name) { - if (!value.HasMember(name)) { - return; - } - - const JSValue& property = value[name]; - if (!property.IsUint()) { - return; - } - - unsigned int uint = property.GetUint(); - if (uint > std::numeric_limits::max()) { - return; - } - - target = uint; -} - -void parseTileJSONMember(const JSValue& value, std::array& target, const char* name) { - if (!value.HasMember(name)) { - return; - } - - const JSValue& property = value[name]; - if (!property.IsArray() || property.Size() > 4) { - return; - } - - for (rapidjson::SizeType i = 0; i < property.Size(); i++) { - if (!property[i].IsNumber()) { - return; - } - } - - for (rapidjson::SizeType i = 0; i < property.Size(); i++) { - target[i] = property[i].GetDouble(); - } -} - -} // end namespace - -StyleParser::~StyleParser() = default; - -void StyleParser::parse(const std::string& json) { - rapidjson::GenericDocument, rapidjson::CrtAllocator> document; - document.Parse<0>(json.c_str()); - - if (document.HasParseError()) { - Log::Error(Event::ParseStyle, "Error parsing style JSON at %i: %s", document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError())); - return; - } - - if (document.HasMember("version")) { - int version = document["version"].GetInt(); - if (version != 8) { - Log::Warning(Event::ParseStyle, "current renderer implementation only supports style spec version 8; using an outdated style will cause rendering errors"); - } - } - - if (document.HasMember("sources")) { - parseSources(document["sources"]); - } - - if (document.HasMember("layers")) { - parseLayers(document["layers"]); - } - - if (document.HasMember("sprite")) { - const JSValue& sprite = document["sprite"]; - if (sprite.IsString()) { - spriteURL = { sprite.GetString(), sprite.GetStringLength() }; - } - } - - if (document.HasMember("glyphs")) { - const JSValue& glyphs = document["glyphs"]; - if (glyphs.IsString()) { - glyphURL = { glyphs.GetString(), glyphs.GetStringLength() }; - } - } -} - -void StyleParser::parseSources(const JSValue& value) { - if (!value.IsObject()) { - Log::Warning(Event::ParseStyle, "sources must be an object"); - return; - } - - JSValue::ConstMemberIterator itr = value.MemberBegin(); - for (; itr != value.MemberEnd(); ++itr) { - const JSValue& nameVal = itr->name; - const JSValue& sourceVal = itr->value; - - if (!sourceVal.HasMember("type")) { - Log::Warning(Event::ParseStyle, "source must have a type"); - continue; - } - - const JSValue& typeVal = sourceVal["type"]; - if (!typeVal.IsString()) { - Log::Warning(Event::ParseStyle, "source type must have one of the enum values"); - continue; - } - - const auto type = SourceTypeClass({ typeVal.GetString(), typeVal.GetStringLength() }); - - // Sources can have URLs, either because they reference an external TileJSON file, or - // because reference a GeoJSON file. They don't have to have one though when all source - // parameters are specified inline. - std::string url; - - uint16_t tileSize = util::tileSize; - - std::unique_ptr info; - std::unique_ptr geojsonvt; - - switch (type) { - case SourceType::Raster: - if (sourceVal.HasMember("tileSize")) { - const JSValue& tileSizeVal = sourceVal["tileSize"]; - if (tileSizeVal.IsNumber() && tileSizeVal.GetUint64() <= std::numeric_limits::max()) { - tileSize = tileSizeVal.GetUint64(); - } else { - Log::Error(Event::ParseStyle, "invalid tileSize"); - continue; - } - } - // Fall through. Vector sources are forbidden from having a tileSize. - - case SourceType::Vector: - if (sourceVal.HasMember("url")) { - const JSValue& urlVal = sourceVal["url"]; - if (urlVal.IsString()) { - url = { urlVal.GetString(), urlVal.GetStringLength() }; - } else { - Log::Error(Event::ParseStyle, "source url must be a string"); - continue; - } - } else { - info = parseTileJSON(sourceVal); - } - break; - - case SourceType::GeoJSON: - info = std::make_unique(); - - // We should probably split this up to have URLs in the url property, and actual data - // in the data property. Until then, we're going to detect the content based on the - // object type. - if (sourceVal.HasMember("data")) { - const JSValue& dataVal = sourceVal["data"]; - if (dataVal.IsString()) { - // We need to load an external GeoJSON file - url = { dataVal.GetString(), dataVal.GetStringLength() }; - } else if (dataVal.IsObject()) { - // We need to parse dataVal as a GeoJSON object - geojsonvt = parseGeoJSON(dataVal); - info->maxZoom = geojsonvt->options.maxZoom; - } else { - Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object"); - continue; - } - } else { - Log::Error(Event::ParseStyle, "GeoJSON source must have a data value"); - continue; - } - - break; - - default: - Log::Error(Event::ParseStyle, "source type '%s' is not supported", typeVal.GetString()); - continue; - } - - const std::string id { nameVal.GetString(), nameVal.GetStringLength() }; - std::unique_ptr source = std::make_unique(type, id, url, tileSize, std::move(info), std::move(geojsonvt)); - - sourcesMap.emplace(id, source.get()); - sources.emplace_back(std::move(source)); - } -} - -std::unique_ptr StyleParser::parseGeoJSON(const JSValue& value) { - using namespace mapbox::geojsonvt; - - Options options; - options.buffer = util::EXTENT / util::tileSize * 128; - options.extent = util::EXTENT; - - try { - return std::make_unique(Convert::convert(value, 0), options); - } catch (const std::exception& ex) { - Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what()); - // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for - // tiles to load. - return std::make_unique(std::vector{}, options); - } -} - -std::unique_ptr StyleParser::parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type, uint16_t tileSize) { - rapidjson::GenericDocument, rapidjson::CrtAllocator> document; - document.Parse<0>(json.c_str()); - - if (document.HasParseError()) { - std::stringstream message; - message << document.GetErrorOffset() << " - " << rapidjson::GetParseError_En(document.GetParseError()); - throw std::runtime_error(message.str()); - } - - std::unique_ptr result = StyleParser::parseTileJSON(document); - - // TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with. - if (util::mapbox::isMapboxURL(sourceURL)) { - for (auto& url : result->tiles) { - url = util::mapbox::canonicalizeTileURL(url, type, tileSize); - } - } - - return result; -} - -std::unique_ptr StyleParser::parseTileJSON(const JSValue& value) { - auto info = std::make_unique(); - parseTileJSONMember(value, info->tiles, "tiles"); - parseTileJSONMember(value, info->minZoom, "minzoom"); - parseTileJSONMember(value, info->maxZoom, "maxzoom"); - parseTileJSONMember(value, info->attribution, "attribution"); - - std::array array; - parseTileJSONMember(value, array, "center"); - info->center = { array[0], array[1] }; - info->zoom = array[2]; - parseTileJSONMember(value, array, "bounds"); - info->bounds = LatLngBounds::hull({ array[0], array[1] }, { array[2], array[3] }); - - return info; -} - -void StyleParser::parseLayers(const JSValue& value) { - std::vector ids; - - if (!value.IsArray()) { - Log::Warning(Event::ParseStyle, "layers must be an array"); - return; - } - - for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { - const JSValue& layerValue = value[i]; - - if (!layerValue.IsObject()) { - Log::Warning(Event::ParseStyle, "layer must be an object"); - continue; - } - - if (!layerValue.HasMember("id")) { - Log::Warning(Event::ParseStyle, "layer must have an id"); - continue; - } - - const JSValue& id = layerValue["id"]; - if (!id.IsString()) { - Log::Warning(Event::ParseStyle, "layer id must be a string"); - continue; - } - - const std::string layerID = { id.GetString(), id.GetStringLength() }; - if (layersMap.find(layerID) != layersMap.end()) { - Log::Warning(Event::ParseStyle, "duplicate layer id %s", layerID.c_str()); - continue; - } - - layersMap.emplace(layerID, std::pair> { layerValue, nullptr }); - ids.push_back(layerID); - } - - for (const auto& id : ids) { - auto it = layersMap.find(id); - - parseLayer(it->first, - it->second.first, - it->second.second); - } - - for (const auto& id : ids) { - auto it = layersMap.find(id); - - if (it->second.second) { - layers.emplace_back(std::move(it->second.second)); - } - } -} - -void StyleParser::parseLayer(const std::string& id, const JSValue& value, std::unique_ptr& layer) { - if (layer) { - // Skip parsing this again. We already have a valid layer definition. - return; - } - - // Make sure we have not previously attempted to parse this layer. - if (std::find(stack.begin(), stack.end(), id) != stack.end()) { - Log::Warning(Event::ParseStyle, "layer reference of '%s' is circular", id.c_str()); - return; - } - - if (value.HasMember("ref")) { - // This layer is referencing another layer. Recursively parse that layer. - const JSValue& refVal = value["ref"]; - if (!refVal.IsString()) { - Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", id.c_str()); - return; - } - - const std::string ref { refVal.GetString(), refVal.GetStringLength() }; - auto it = layersMap.find(ref); - if (it == layersMap.end()) { - Log::Warning(Event::ParseStyle, "layer '%s' references unknown layer %s", id.c_str(), ref.c_str()); - return; - } - - // Recursively parse the referenced layer. - stack.push_front(id); - parseLayer(it->first, - it->second.first, - it->second.second); - stack.pop_front(); - - Layer* reference = it->second.second.get(); - if (!reference) { - return; - } - - layer = reference->copy(id, ref); - layer->baseImpl->parsePaints(value); - } else { - // Otherwise, parse the source/source-layer/filter/render keys to form the bucket. - if (!value.HasMember("type")) { - Log::Warning(Event::ParseStyle, "layer '%s' is missing a type", id.c_str()); - return; - } - - const JSValue& typeVal = value["type"]; - if (!typeVal.IsString()) { - Log::Warning(Event::ParseStyle, "layer '%s' has an invalid type", id.c_str()); - return; - } - - std::string type { typeVal.GetString(), typeVal.GetStringLength() }; - - if (type == "fill") { - layer = std::make_unique(id); - } else if (type == "line") { - layer = std::make_unique(id); - } else if (type == "circle") { - layer = std::make_unique(id); - } else if (type == "symbol") { - layer = std::make_unique(id); - } else if (type == "raster") { - layer = std::make_unique(id); - } else if (type == "background") { - layer = std::make_unique(id); - } else { - Log::Warning(Event::ParseStyle, "unknown type '%s' for layer '%s'", type.c_str(), id.c_str()); - return; - } - - Layer::Impl* impl = layer->baseImpl.get(); - - if (value.HasMember("source")) { - const JSValue& value_source = value["source"]; - if (value_source.IsString()) { - impl->source = { value_source.GetString(), value_source.GetStringLength() }; - auto source_it = sourcesMap.find(impl->source); - if (source_it == sourcesMap.end()) { - Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", impl->source.c_str(), impl->id.c_str()); - } - } else { - Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", impl->id.c_str()); - } - } - - if (value.HasMember("source-layer")) { - const JSValue& value_source_layer = value["source-layer"]; - if (value_source_layer.IsString()) { - impl->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() }; - } else { - Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", impl->id.c_str()); - } - } - - if (value.HasMember("filter")) { - impl->filter = parseFilter(value["filter"]); - } - - if (value.HasMember("minzoom")) { - const JSValue& min_zoom = value["minzoom"]; - if (min_zoom.IsNumber()) { - impl->minZoom = min_zoom.GetDouble(); - } else { - Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", impl->id.c_str()); - } - } - - if (value.HasMember("maxzoom")) { - const JSValue& max_zoom = value["maxzoom"]; - if (max_zoom.IsNumber()) { - impl->maxZoom = max_zoom.GetDouble(); - } else { - Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", impl->id.c_str()); - } - } - - if (value.HasMember("layout")) { - parseVisibility(*layer, value["layout"]); - impl->parseLayout(value["layout"]); - } - - impl->parsePaints(value); - } -} - -MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, { - { VisibilityType::Visible, "visible" }, - { VisibilityType::None, "none" }, -}); - -void StyleParser::parseVisibility(Layer& layer, const JSValue& value) { - Layer::Impl& impl = *layer.baseImpl; - if (!value.HasMember("visibility")) { - return; - } else if (!value["visibility"].IsString()) { - Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string"); - impl.visibility = VisibilityType::Visible; - return; - } - impl.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() }); -} - -Value parseFeatureType(const Value& value) { - if (value == std::string("Point")) { - return Value(uint64_t(FeatureType::Point)); - } else if (value == std::string("LineString")) { - return Value(uint64_t(FeatureType::LineString)); - } else if (value == std::string("Polygon")) { - return Value(uint64_t(FeatureType::Polygon)); - } else { - Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon"); - return Value(uint64_t(FeatureType::Unknown)); - } -} - -Value parseValue(const JSValue& value) { - switch (value.GetType()) { - case rapidjson::kNullType: - case rapidjson::kFalseType: - return false; - - case rapidjson::kTrueType: - return true; - - case rapidjson::kStringType: - return std::string { value.GetString(), value.GetStringLength() }; - - case rapidjson::kNumberType: - if (value.IsUint64()) return value.GetUint64(); - if (value.IsInt64()) return value.GetInt64(); - return value.GetDouble(); - - default: - return false; - } -} - -template -Filter parseUnaryFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 2) { - Log::Warning(Event::ParseStyle, "filter expression must have 2 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - return expression; -} - -template -Filter parseBinaryFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 3) { - Log::Warning(Event::ParseStyle, "filter expression must have 3 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - expression.value = parseValue(value[2u]); - - if (expression.key == "$type") { - expression.value = parseFeatureType(expression.value); - } - - return expression; -} - -template -Filter parseSetFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 2) { - Log::Warning(Event::ParseStyle, "filter expression must at least 2 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - for (rapidjson::SizeType i = 2; i < value.Size(); ++i) { - Value parsedValue = parseValue(value[i]); - if (expression.key == "$type") { - parsedValue = parseFeatureType(parsedValue); - } - expression.values.push_back(parsedValue); - } - return expression; -} - -template -Filter parseCompoundFilter(const JSValue& value) { - Expression expression; - for (rapidjson::SizeType i = 1; i < value.Size(); ++i) { - expression.filters.push_back(parseFilter(value[i])); - } - return expression; -} - -Filter parseFilter(const JSValue& value) { - Filter empty; - - if (!value.IsArray()) { - Log::Warning(Event::ParseStyle, "filter expression must be an array"); - return empty; - } - - if (value.Size() < 1) { - Log::Warning(Event::ParseStyle, "filter expression must have at least 1 element"); - return empty; - } - - if (!value[0u].IsString()) { - Log::Warning(Event::ParseStyle, "filter operator must be a string"); - return empty; - } - - std::string op = { value[0u].GetString(), value[0u].GetStringLength() }; - - if (op == "==") { - return parseBinaryFilter(value); - } else if (op == "!=") { - return parseBinaryFilter(value); - } else if (op == ">") { - return parseBinaryFilter(value); - } else if (op == ">=") { - return parseBinaryFilter(value); - } else if (op == "<") { - return parseBinaryFilter(value); - } else if (op == "<=") { - return parseBinaryFilter(value); - } else if (op == "in") { - return parseSetFilter(value); - } else if (op == "!in") { - return parseSetFilter(value); - } else if (op == "all") { - return parseCompoundFilter(value); - } else if (op == "any") { - return parseCompoundFilter(value); - } else if (op == "none") { - return parseCompoundFilter(value); - } else if (op == "has") { - return parseUnaryFilter(value); - } else if (op == "!has") { - return parseUnaryFilter(value); - } else { - Log::Warning(Event::ParseStyle, "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\", \"has\", or \"!has\""); - return empty; - } -} - -std::vector StyleParser::fontStacks() const { - std::set result; - - for (const auto& layer : layers) { - if (layer->is()) { - PropertyValue textFont = layer->as()->getTextFont(); - if (textFont.isUndefined()) { - result.insert({"Open Sans Regular", "Arial Unicode MS Regular"}); - } else if (textFont.isConstant()) { - result.insert(textFont.asConstant()); - } else if (textFont.isFunction()) { - for (const auto& stop : textFont.asFunction().getStops()) { - result.insert(stop.second); - } - } - } - } - - return std::vector(result.begin(), result.end()); -} - -} // namespace mbgl diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp deleted file mode 100644 index b5445bbfb3..0000000000 --- a/src/mbgl/style/style_parser.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace mbgl { - -Filter parseFilter(const JSValue&); - -class StyleParser { -public: - ~StyleParser(); - - void parse(const std::string&); - - std::string spriteURL; - std::string glyphURL; - - std::vector> sources; - std::vector> layers; - - // Statically evaluate layer properties to determine what font stacks are used. - std::vector fontStacks() const; - - static std::unique_ptr parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType, uint16_t tileSize); - static std::unique_ptr parseTileJSON(const JSValue&); - - static std::unique_ptr parseGeoJSON(const JSValue&); - -private: - void parseSources(const JSValue&); - void parseLayers(const JSValue&); - void parseLayer(const std::string& id, const JSValue&, std::unique_ptr&); - void parseVisibility(Layer&, const JSValue& value); - - std::unordered_map sourcesMap; - std::unordered_map>> layersMap; - - // Store a stack of layer IDs we're parsing right now. This is to prevent reference cycles. - std::forward_list stack; -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_query_parameters.hpp b/src/mbgl/style/style_query_parameters.hpp deleted file mode 100644 index 33115bdfb2..0000000000 --- a/src/mbgl/style/style_query_parameters.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -namespace mbgl { - -class TransformState; - -class StyleQueryParameters { -public: - const ScreenLineString& geometry; - const TransformState& transformState; - const optional>& layerIDs; -}; - -} // namespace mbgl diff --git a/src/mbgl/style/style_render_parameters.hpp b/src/mbgl/style/style_render_parameters.hpp deleted file mode 100644 index 7347717a1d..0000000000 --- a/src/mbgl/style/style_render_parameters.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -namespace mbgl { - -class TransformState; - -class StyleRenderParameters { -public: - StyleRenderParameters(const TransformState& state_) - : state(state_) {} - - const TransformState& state; -}; - -} diff --git a/src/mbgl/style/style_update_parameters.hpp b/src/mbgl/style/style_update_parameters.hpp deleted file mode 100644 index 73ed500e8e..0000000000 --- a/src/mbgl/style/style_update_parameters.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include - -namespace mbgl { - -class TransformState; -class Worker; -class FileSource; -class Style; -namespace gl { class TexturePool; } -class AnnotationManager; - -class StyleUpdateParameters { -public: - StyleUpdateParameters(float pixelRatio_, - MapDebugOptions debugOptions_, - TimePoint animationTime_, - const TransformState& transformState_, - Worker& worker_, - FileSource& fileSource_, - gl::TexturePool& texturePool_, - bool shouldReparsePartialTiles_, - const MapMode mode_, - AnnotationManager& annotationManager_, - Style& style_) - : pixelRatio(pixelRatio_), - debugOptions(debugOptions_), - animationTime(animationTime_), - transformState(transformState_), - worker(worker_), - fileSource(fileSource_), - texturePool(texturePool_), - shouldReparsePartialTiles(shouldReparsePartialTiles_), - mode(mode_), - annotationManager(annotationManager_), - style(style_) {} - - float pixelRatio; - MapDebugOptions debugOptions; - TimePoint animationTime; - const TransformState& transformState; - Worker& worker; - FileSource& fileSource; - gl::TexturePool& texturePool; - bool shouldReparsePartialTiles; - const MapMode mode; - AnnotationManager& annotationManager; - - // TODO: remove - Style& style; -}; - -} diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp deleted file mode 100644 index 27574afa93..0000000000 --- a/src/mbgl/style/types.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include -#include - -namespace mbgl { - -std::string fontStackToString(const FontStack& fontStack) { - return boost::algorithm::join(fontStack, ","); -} - -std::size_t FontStackHash::operator()(const FontStack& fontStack) const { - return boost::hash_range(fontStack.begin(), fontStack.end()); -} - -} // namespace mbgl diff --git a/src/mbgl/style/update_parameters.hpp b/src/mbgl/style/update_parameters.hpp new file mode 100644 index 0000000000..9faaa32d6f --- /dev/null +++ b/src/mbgl/style/update_parameters.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include + +namespace mbgl { + +class TransformState; +class Worker; +class FileSource; +namespace gl { class TexturePool; } +class AnnotationManager; + +namespace style { + +class Style; + +class UpdateParameters { +public: + UpdateParameters(float pixelRatio_, + MapDebugOptions debugOptions_, + TimePoint animationTime_, + const TransformState& transformState_, + Worker& worker_, + FileSource& fileSource_, + gl::TexturePool& texturePool_, + bool shouldReparsePartialTiles_, + const MapMode mode_, + AnnotationManager& annotationManager_, + Style& style_) + : pixelRatio(pixelRatio_), + debugOptions(debugOptions_), + animationTime(animationTime_), + transformState(transformState_), + worker(worker_), + fileSource(fileSource_), + texturePool(texturePool_), + shouldReparsePartialTiles(shouldReparsePartialTiles_), + mode(mode_), + annotationManager(annotationManager_), + style(style_) {} + + float pixelRatio; + MapDebugOptions debugOptions; + TimePoint animationTime; + const TransformState& transformState; + Worker& worker; + FileSource& fileSource; + gl::TexturePool& texturePool; + bool shouldReparsePartialTiles; + const MapMode mode; + AnnotationManager& annotationManager; + + // TODO: remove + Style& style; +}; + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/zoom_history.hpp b/src/mbgl/style/zoom_history.hpp deleted file mode 100644 index 8c88ea6507..0000000000 --- a/src/mbgl/style/zoom_history.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -#include - -namespace mbgl { - -struct ZoomHistory { - float lastZoom; - float lastIntegerZoom; - TimePoint lastIntegerZoomTime; - bool first = true; - - void update(float z, const TimePoint& now) { - if (first) { - first = false; - - lastIntegerZoom = std::floor(z); - lastIntegerZoomTime = TimePoint(Duration::zero()); - lastZoom = z; - } - - if (std::floor(lastZoom) < std::floor(z)) { - lastIntegerZoom = std::floor(z); - lastIntegerZoomTime = now; - - } else if (std::floor(lastZoom) > std::floor(z)) { - lastIntegerZoom = std::floor(z + 1); - lastIntegerZoomTime = now; - } - - lastZoom = z; - } -}; -} // namespace mbgl diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp index 08616b268b..85f4b62e6f 100644 --- a/src/mbgl/text/glyph_pbf.hpp +++ b/src/mbgl/text/glyph_pbf.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp index d614a4947f..edc89b4894 100644 --- a/src/mbgl/text/glyph_store.hpp +++ b/src/mbgl/text/glyph_store.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/mbgl/text/glyph_store_observer.hpp b/src/mbgl/text/glyph_store_observer.hpp index 89650892ea..39f10cd812 100644 --- a/src/mbgl/text/glyph_store_observer.hpp +++ b/src/mbgl/text/glyph_store_observer.hpp @@ -2,6 +2,7 @@ #include #include +#include #include diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 3cb508a102..ce320791c3 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -2,13 +2,15 @@ #include #include #include -#include +#include #include #include #include namespace mbgl { +using namespace style; + const float globalMinScale = 0.5f; // underscale by 1 zoom level SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index c68ea2fe6a..0627647f4c 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -7,39 +7,43 @@ namespace mbgl { - struct SymbolQuad { - explicit SymbolQuad(const Point &tl_, const Point &tr_, - const Point &bl_, const Point &br_, - const Rect &tex_, float angle_, const Point &anchorPoint_, - float minScale_, float maxScale_) - : tl(tl_), - tr(tr_), - bl(bl_), - br(br_), - tex(tex_), - angle(angle_), - anchorPoint(anchorPoint_), - minScale(minScale_), - maxScale(maxScale_) {} - - Point tl, tr, bl, br; - Rect tex; - float angle; - Point anchorPoint; - float minScale, maxScale; - }; - - typedef std::vector SymbolQuads; - - struct Anchor; - class SymbolLayoutProperties; - class PositionedIcon; - - SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, const SymbolLayoutProperties& layout, - const bool alongLine); - - SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, - const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties& layout, - const bool alongLine, const GlyphPositions& face); +struct Anchor; +class PositionedIcon; + +namespace style { +class SymbolLayoutProperties; +} + +struct SymbolQuad { + explicit SymbolQuad(const Point &tl_, const Point &tr_, + const Point &bl_, const Point &br_, + const Rect &tex_, float angle_, const Point &anchorPoint_, + float minScale_, float maxScale_) + : tl(tl_), + tr(tr_), + bl(bl_), + br(br_), + tex(tex_), + angle(angle_), + anchorPoint(anchorPoint_), + minScale(minScale_), + maxScale(maxScale_) {} + + Point tl, tr, bl, br; + Rect tex; + float angle; + Point anchorPoint; + float minScale, maxScale; +}; + +typedef std::vector SymbolQuads; + +SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon, + const GeometryCoordinates& line, const style::SymbolLayoutProperties&, + const bool alongLine); + +SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, + const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties&, + const bool alongLine, const GlyphPositions& face); + } // namespace mbgl diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index ce93b4977e..1091cd6e94 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -1,9 +1,9 @@ #include -#include +#include namespace mbgl { -PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties& layout) { +PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties& layout) { float dx = layout.iconOffset.value[0]; float dy = layout.iconOffset.value[1]; float x1 = dx - image.spriteImage->getWidth() / 2.0f; diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index ea169b8dc6..f81230acec 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -7,26 +7,28 @@ namespace mbgl { - struct SpriteAtlasElement; +struct SpriteAtlasElement; - class PositionedIcon { - public: - inline explicit PositionedIcon() {} - inline explicit PositionedIcon(const SpriteAtlasElement& _image, - float _top, float _bottom, float _left, float _right) : - image(_image), top(_top), bottom(_bottom), left(_left), right(_right) {} +namespace style { +class SymbolLayoutProperties; +} - optional image; - float top = 0; - float bottom = 0; - float left = 0; - float right = 0; +class PositionedIcon { + public: + inline explicit PositionedIcon() {} + inline explicit PositionedIcon(const SpriteAtlasElement& _image, + float _top, float _bottom, float _left, float _right) : + image(_image), top(_top), bottom(_bottom), left(_left), right(_right) {} - operator bool() const { return image && (*image).pos.hasArea(); } - }; + optional image; + float top = 0; + float bottom = 0; + float left = 0; + float right = 0; - class SymbolLayoutProperties; + operator bool() const { return image && (*image).pos.hasArea(); } +}; - PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties&); +PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties&); } // namespace mbgl diff --git a/src/mbgl/tile/raster_tile_data.cpp b/src/mbgl/tile/raster_tile_data.cpp index a5eab3fb23..420cb7055e 100644 --- a/src/mbgl/tile/raster_tile_data.cpp +++ b/src/mbgl/tile/raster_tile_data.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -61,7 +61,7 @@ RasterTileData::~RasterTileData() { cancel(); } -Bucket* RasterTileData::getBucket(const Layer&) { +Bucket* RasterTileData::getBucket(const style::Layer&) { return bucket.get(); } diff --git a/src/mbgl/tile/raster_tile_data.hpp b/src/mbgl/tile/raster_tile_data.hpp index ea9b144e25..62d21d28c4 100644 --- a/src/mbgl/tile/raster_tile_data.hpp +++ b/src/mbgl/tile/raster_tile_data.hpp @@ -7,9 +7,13 @@ namespace mbgl { class FileSource; class AsyncRequest; -class Layer; + namespace gl { class TexturePool; } +namespace style { +class Layer; +} + class RasterTileData : public TileData { public: RasterTileData(const OverscaledTileID&, @@ -22,7 +26,7 @@ public: ~RasterTileData(); void cancel() override; - Bucket* getBucket(const Layer&) override; + Bucket* getBucket(const style::Layer&) override; private: gl::TexturePool& texturePool; diff --git a/src/mbgl/tile/tile_data.hpp b/src/mbgl/tile/tile_data.hpp index 035a7ed319..5b6583faf8 100644 --- a/src/mbgl/tile/tile_data.hpp +++ b/src/mbgl/tile/tile_data.hpp @@ -16,11 +16,14 @@ namespace mbgl { -class Layer; class Worker; class DebugBucket; class TransformState; +namespace style { +class Layer; +} + class TileData : private util::noncopyable { public: TileData(const OverscaledTileID&); @@ -29,7 +32,7 @@ public: // Mark this tile as no longer needed and cancel any pending work. virtual void cancel() = 0; - virtual Bucket* getBucket(const Layer&) = 0; + virtual Bucket* getBucket(const style::Layer&) = 0; virtual bool parsePending(std::function) { return true; } virtual void redoPlacement(PlacementConfig, const std::function&) {} diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp index 9076684a2d..b2283043da 100644 --- a/src/mbgl/tile/tile_worker.cpp +++ b/src/mbgl/tile/tile_worker.cpp @@ -1,11 +1,11 @@ #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include @@ -15,7 +15,9 @@ #include #include -using namespace mbgl; +namespace mbgl { + +using namespace mbgl::style; TileWorker::TileWorker(const OverscaledTileID& id_, std::string sourceID_, @@ -155,7 +157,7 @@ void TileWorker::parseLayer(const Layer* layer) { return; } - StyleBucketParameters parameters(id, + BucketParameters parameters(id, *geometryLayer, obsolete, reinterpret_cast(this), @@ -185,3 +187,5 @@ void TileWorker::insertBucket(const std::string& name, std::unique_ptr b result.buckets.emplace(name, std::move(bucket)); } } + +} diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp index a04ef6a78f..2757c0f9ba 100644 --- a/src/mbgl/tile/tile_worker.hpp +++ b/src/mbgl/tile/tile_worker.hpp @@ -23,8 +23,11 @@ class SpriteStore; class GlyphAtlas; class GlyphStore; class Bucket; + +namespace style { class Layer; class SymbolLayer; +} // We're using this class to shuttle the resulting buckets from the worker thread to the MapContext // thread. This class is movable-only because the vector contains movable-only value elements. @@ -51,7 +54,7 @@ public: const MapMode); ~TileWorker(); - TileParseResult parseAllLayers(std::vector>, + TileParseResult parseAllLayers(std::vector>, std::unique_ptr geometryTile, PlacementConfig); @@ -62,7 +65,7 @@ public: private: TileParseResult prepareResult(const PlacementConfig& config); - void parseLayer(const Layer*); + void parseLayer(const style::Layer*); void insertBucket(const std::string& name, std::unique_ptr); std::unique_ptr placeLayers(PlacementConfig); @@ -77,14 +80,14 @@ private: bool partialParse = false; - std::vector> layers; + std::vector> layers; std::unique_ptr featureIndex; std::unique_ptr geometryTile; // Contains buckets that we couldn't parse so far due to missing resources. // They will be attempted on subsequent parses. - std::list>> pending; + std::list>> pending; // Contains buckets that have been parsed, but still need placement. // They will be placed when all buckets have been parsed. diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp index 8a69a82314..5126d0ce83 100644 --- a/src/mbgl/tile/vector_tile.cpp +++ b/src/mbgl/tile/vector_tile.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp index db0ec8029e..1ab2566a25 100644 --- a/src/mbgl/tile/vector_tile_data.cpp +++ b/src/mbgl/tile/vector_tile_data.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ namespace mbgl { VectorTileData::VectorTileData(const OverscaledTileID& id_, std::unique_ptr monitor_, std::string sourceID, - Style& style_, + style::Style& style_, const MapMode mode_, const std::function& callback) : TileData(id_), @@ -139,7 +139,7 @@ bool VectorTileData::parsePending(std::function callba return true; } -Bucket* VectorTileData::getBucket(const Layer& layer) { +Bucket* VectorTileData::getBucket(const style::Layer& layer) { const auto it = buckets.find(layer.baseImpl->bucketName()); if (it == buckets.end()) { return nullptr; diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp index 4695338e1e..e7de39e038 100644 --- a/src/mbgl/tile/vector_tile_data.hpp +++ b/src/mbgl/tile/vector_tile_data.hpp @@ -11,23 +11,26 @@ namespace mbgl { -class Style; class AsyncRequest; class GeometryTileMonitor; class FeatureIndex; +namespace style { +class Style; +} + class VectorTileData : public TileData { public: VectorTileData(const OverscaledTileID&, std::unique_ptr monitor, std::string sourceID, - Style&, + style::Style&, const MapMode, const std::function& callback); ~VectorTileData(); - Bucket* getBucket(const Layer&) override; + Bucket* getBucket(const style::Layer&) override; bool parsePending(std::function callback) override; @@ -43,7 +46,7 @@ public: void cancel() override; private: - Style& style; + style::Style& style; Worker& worker; TileWorker tileWorker; diff --git a/src/mbgl/util/font_stack.cpp b/src/mbgl/util/font_stack.cpp new file mode 100644 index 0000000000..fb3b1b60a2 --- /dev/null +++ b/src/mbgl/util/font_stack.cpp @@ -0,0 +1,16 @@ +#include + +#include +#include + +namespace mbgl { + +std::string fontStackToString(const FontStack& fontStack) { + return boost::algorithm::join(fontStack, ","); +} + +std::size_t FontStackHash::operator()(const FontStack& fontStack) const { + return boost::hash_range(fontStack.begin(), fontStack.end()); +} + +} // namespace mbgl diff --git a/src/mbgl/util/tileset.hpp b/src/mbgl/util/tileset.hpp new file mode 100644 index 0000000000..972fc51f8c --- /dev/null +++ b/src/mbgl/util/tileset.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace mbgl { + +class Tileset { +public: + std::vector tiles; + uint8_t minZoom = 0; + uint8_t maxZoom = 22; + std::string attribution; + LatLng center; + double zoom = 0; + LatLngBounds bounds = LatLngBounds::world(); +}; + +} // namespace mbgl diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp index 43abe6792a..2bc545c704 100644 --- a/src/mbgl/util/worker.cpp +++ b/src/mbgl/util/worker.cpp @@ -30,7 +30,7 @@ public: } void parseGeometryTile(TileWorker* worker, - std::vector> layers, + std::vector> layers, std::unique_ptr tile, PlacementConfig config, std::function callback) { @@ -79,7 +79,7 @@ Worker::parseRasterTile(std::unique_ptr bucket, std::unique_ptr Worker::parseGeometryTile(TileWorker& worker, - std::vector> layers, + std::vector> layers, std::unique_ptr tile, PlacementConfig config, std::function callback) { diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp index 68625f42bf..678dfaedb3 100644 --- a/src/mbgl/util/worker.hpp +++ b/src/mbgl/util/worker.hpp @@ -40,7 +40,7 @@ public: std::function callback); Request parseGeometryTile(TileWorker&, - std::vector>, + std::vector>, std::unique_ptr, PlacementConfig, std::function callback); -- cgit v1.2.1