diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-10-30 10:21:17 +0200 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2019-11-11 18:20:01 +0200 |
commit | c6f3cc8b60e0cff032020a780d4fd3de1cb2a112 (patch) | |
tree | 155fe444f21ae88dda664e81cfc8378e28297b0e /src/mbgl/layout | |
parent | e1556fc539607db626b978040895716c1564c9b9 (diff) | |
download | qtlocation-mapboxgl-c6f3cc8b60e0cff032020a780d4fd3de1cb2a112.tar.gz |
[core] Implement image expression (#15877)
* [core] Bump gl-js version
* [core] Implement image expression
* [core] Use new image expression
* [core] Coerce image expression to / from string
* [core] Serialize evaluated image
* [core] Pass available images to layout
* [core] Pass images to evaluation context
* [core] Set available flag value based on image availability
* [core] Allow image coercion to boolean to indicate image availability
* [core] Coalesce image expression
* [core] Add image expression to next build system
* [core] Align serialization format and evaluated type with gl-js
* [core] Add images to expression evaluation method
* [core] Add support for Image expression to expression test runner
* [core] Unskip image expression tests
* [core] Update unit tests
* [core] Use image expression in annotation manager
* [core] Add string to ImageExpression conversion
* [core] Add image expression to expression dsl
* [core] Convert tokens for implicitly created Image literal
* [core] Fix clang format
* [core] Split generated style code lines that are over 120 characters
* [core] Add unit test for image expression equality
* [core] Add image property expression evaluation unit test
* [core] Unskip image expression render test
* [core] Skip 'in' expression tests
* [core] Ignore fill-pattern/update-feature-state render test
* [core] Rename Image::serialize to Image::toValue
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r-- | src/mbgl/layout/layout.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/layout/pattern_layout.hpp | 46 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_feature.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 5 |
5 files changed, 44 insertions, 36 deletions
diff --git a/src/mbgl/layout/layout.hpp b/src/mbgl/layout/layout.hpp index d1f03792c1..91d3e3f596 100644 --- a/src/mbgl/layout/layout.hpp +++ b/src/mbgl/layout/layout.hpp @@ -38,6 +38,7 @@ public: const BucketParameters& bucketParameters; GlyphDependencies& glyphDependencies; ImageDependencies& imageDependencies; + std::set<std::string>& availableImages; }; } // namespace mbgl diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index d6d878955f..48531e836b 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -1,8 +1,9 @@ #pragma once +#include <mbgl/geometry/feature_index.hpp> #include <mbgl/layout/layout.hpp> #include <mbgl/renderer/bucket_parameters.hpp> -#include <mbgl/geometry/feature_index.hpp> #include <mbgl/renderer/render_layer.hpp> +#include <mbgl/style/expression/image.hpp> #include <mbgl/style/layer_properties.hpp> namespace mbgl { @@ -32,11 +33,11 @@ public: PatternLayout(const BucketParameters& parameters, const std::vector<Immutable<style::LayerProperties>>& group, std::unique_ptr<GeometryTileLayer> sourceLayer_, - ImageDependencies& patternDependencies) - : sourceLayer(std::move(sourceLayer_)), - zoom(parameters.tileID.overscaledZ), - overscaling(parameters.tileID.overscaleFactor()), - hasPattern(false) { + const LayoutParameters& layoutParameters) + : sourceLayer(std::move(sourceLayer_)), + zoom(parameters.tileID.overscaledZ), + overscaling(parameters.tileID.overscaleFactor()), + hasPattern(false) { assert(!group.empty()); auto leaderLayerProperties = staticImmutableCast<LayerPropertiesType>(group.front()); layout = leaderLayerProperties->layerImpl().layout.evaluate(PropertyEvaluationParameters(zoom)); @@ -47,15 +48,15 @@ public: const std::string& layerId = layerProperties->baseImpl->id; const auto& evaluated = style::getEvaluated<LayerPropertiesType>(layerProperties); const auto patternProperty = evaluated.template get<PatternPropertyType>(); - const auto constantPattern = patternProperty.constantOr(Faded<std::basic_string<char> >{ "", ""}); + const auto constantPattern = patternProperty.constantOr(Faded<style::expression::Image>{"", ""}); // determine if layer group has any layers that use *-pattern property and add // constant pattern dependencies. if (!patternProperty.isConstant()) { hasPattern = true; - } else if (!constantPattern.to.empty()){ + } else if (!constantPattern.to.id().empty()) { hasPattern = true; - patternDependencies.emplace(constantPattern.to, ImageType::Pattern); - patternDependencies.emplace(constantPattern.from, ImageType::Pattern); + layoutParameters.imageDependencies.emplace(constantPattern.to.id(), ImageType::Pattern); + layoutParameters.imageDependencies.emplace(constantPattern.from.id(), ImageType::Pattern); } layerPropertiesMap.emplace(layerId, layerProperties); } @@ -77,15 +78,22 @@ public: if (!patternProperty.isConstant()) { // For layers with non-data-constant pattern properties, evaluate their expression and add // the patterns to the dependency vector - const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternPropertyType::defaultValue()); - const auto mid = patternProperty.evaluate(*feature, zoom, PatternPropertyType::defaultValue()); - const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternPropertyType::defaultValue()); - - patternDependencies.emplace(min.to, ImageType::Pattern); - patternDependencies.emplace(mid.to, ImageType::Pattern); - patternDependencies.emplace(max.to, ImageType::Pattern); - patternDependencyMap.emplace(layerId, PatternDependency {min.to, mid.to, max.to}); - + const auto min = patternProperty.evaluate(*feature, + zoom - 1, + layoutParameters.availableImages, + PatternPropertyType::defaultValue()); + const auto mid = patternProperty.evaluate( + *feature, zoom, layoutParameters.availableImages, PatternPropertyType::defaultValue()); + const auto max = patternProperty.evaluate(*feature, + zoom + 1, + layoutParameters.availableImages, + PatternPropertyType::defaultValue()); + + layoutParameters.imageDependencies.emplace(min.to.id(), ImageType::Pattern); + layoutParameters.imageDependencies.emplace(mid.to.id(), ImageType::Pattern); + layoutParameters.imageDependencies.emplace(max.to.id(), ImageType::Pattern); + patternDependencyMap.emplace(layerId, + PatternDependency{min.to.id(), mid.to.id(), max.to.id()}); } } } diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index 03d8e5018d..d0aced1b19 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -1,8 +1,9 @@ #pragma once +#include <mbgl/style/expression/image.hpp> +#include <mbgl/text/tagged_string.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/util/optional.hpp> -#include <mbgl/text/tagged_string.hpp> #include <array> #include <string> @@ -29,7 +30,7 @@ public: std::unique_ptr<GeometryTileFeature> feature; GeometryCollection geometry; optional<TaggedString> formattedText; - optional<std::string> icon; + optional<style::expression::Image> icon; float sortKey = 0.0f; std::size_t index; bool allowsVerticalWritingMode = false; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index d0227c36c5..af0b1bd21b 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -81,8 +81,7 @@ inline Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> createLayout( SymbolLayout::SymbolLayout(const BucketParameters& parameters, const std::vector<Immutable<style::LayerProperties>>& layers, std::unique_ptr<GeometryTileLayer> sourceLayer_, - ImageDependencies& imageDependencies, - GlyphDependencies& glyphDependencies) + const LayoutParameters& layoutParameters) : bucketLeaderID(layers.front()->baseImpl->id), sourceLayer(std::move(sourceLayer_)), overscaling(parameters.tileID.overscaleFactor()), @@ -141,7 +140,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, ft.index = i; if (hasText) { - auto formatted = layout->evaluate<TextField>(zoom, ft); + auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages); auto textTransform = layout->evaluate<TextTransform>(zoom, ft); FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft); @@ -168,7 +167,8 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, // Loop through all characters of this text and collect unique codepoints. for (std::size_t j = 0; j < ft.formattedText->length(); j++) { const auto& sectionFontStack = formatted.sections[ft.formattedText->getSectionIndex(j)].fontStack; - GlyphIDs& dependencies = glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack]; + GlyphIDs& dependencies = + layoutParameters.glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack]; char16_t codePoint = ft.formattedText->getCharCodeAt(j); dependencies.insert(codePoint); if (canVerticalizeText || (allowVerticalPlacement && ft.formattedText->allowsVerticalWritingMode())) { @@ -180,8 +180,8 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } if (hasIcon) { - ft.icon = layout->evaluate<IconImage>(zoom, ft); - imageDependencies.emplace(*ft.icon, ImageType::Icon); + ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages); + layoutParameters.imageDependencies.emplace(ft.icon->id(), ImageType::Icon); } if (ft.formattedText || ft.icon) { @@ -448,14 +448,13 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions // if feature has icon, get sprite atlas position SymbolContent iconType{SymbolContent::None}; if (feature.icon) { - auto image = imageMap.find(*feature.icon); + auto image = imageMap.find(feature.icon->id()); if (image != imageMap.end()) { iconType = SymbolContent::IconRGBA; - shapedIcon = PositionedIcon::shapeIcon( - imagePositions.at(*feature.icon), - layout->evaluate<IconOffset>(zoom, feature), - layout->evaluate<IconAnchor>(zoom, feature), - layout->evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); + shapedIcon = PositionedIcon::shapeIcon(imagePositions.at(feature.icon->id()), + layout->evaluate<IconOffset>(zoom, feature), + layout->evaluate<IconAnchor>(zoom, feature), + layout->evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); if (image->second->sdf) { iconType = SymbolContent::IconSDF; } diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 1abcaaa5d6..2b99c2fa24 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -27,9 +27,8 @@ public: SymbolLayout(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&, std::unique_ptr<GeometryTileLayer>, - ImageDependencies&, - GlyphDependencies&); - + const LayoutParameters& parameters); + ~SymbolLayout() final = default; void prepareSymbols(const GlyphMap&, const GlyphPositions&, |