summaryrefslogtreecommitdiff
path: root/src/mbgl/layout
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2019-10-30 10:21:17 +0200
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2019-11-11 18:20:01 +0200
commitc6f3cc8b60e0cff032020a780d4fd3de1cb2a112 (patch)
tree155fe444f21ae88dda664e81cfc8378e28297b0e /src/mbgl/layout
parente1556fc539607db626b978040895716c1564c9b9 (diff)
downloadqtlocation-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.hpp1
-rw-r--r--src/mbgl/layout/pattern_layout.hpp46
-rw-r--r--src/mbgl/layout/symbol_feature.hpp5
-rw-r--r--src/mbgl/layout/symbol_layout.cpp23
-rw-r--r--src/mbgl/layout/symbol_layout.hpp5
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&,