diff options
-rw-r--r-- | include/mbgl/style/property_expression.hpp | 33 | ||||
-rw-r--r-- | metrics/ignores/platform-all.json | 3 | ||||
-rw-r--r-- | src/mbgl/layout/pattern_layout.hpp | 30 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 57 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/fill_bucket.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/line_bucket.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/line_bucket.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/possibly_evaluated_property_value.hpp | 14 | ||||
-rw-r--r-- | src/mbgl/style/properties.hpp | 37 |
10 files changed, 142 insertions, 45 deletions
diff --git a/include/mbgl/style/property_expression.hpp b/include/mbgl/style/property_expression.hpp index 7439ac9ca1..8502bfefbd 100644 --- a/include/mbgl/style/property_expression.hpp +++ b/include/mbgl/style/property_expression.hpp @@ -73,6 +73,20 @@ public: finalDefaultValue); } + T evaluate(const GeometryTileFeature& feature, const CanonicalTileID& canonical, T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(&feature).withCanonicalTileID(&canonical), finalDefaultValue); + } + + T evaluate(const GeometryTileFeature& feature, + const std::set<std::string>& availableImages, + const CanonicalTileID& canonical, + T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(&feature) + .withAvailableImages(&availableImages) + .withCanonicalTileID(&canonical), + finalDefaultValue); + } + T evaluate(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const { return evaluate(expression::EvaluationContext(zoom, &feature), finalDefaultValue); } @@ -85,6 +99,25 @@ public: finalDefaultValue); } + T evaluate(float zoom, + const GeometryTileFeature& feature, + const std::set<std::string>& availableImages, + const CanonicalTileID& canonical, + T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(zoom, &feature) + .withAvailableImages(&availableImages) + .withCanonicalTileID(&canonical), + finalDefaultValue); + } + + T evaluate(float zoom, + const GeometryTileFeature& feature, + const CanonicalTileID& canonical, + T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(zoom, &feature).withCanonicalTileID(&canonical), + finalDefaultValue); + } + T evaluate(float zoom, const GeometryTileFeature& feature, const FeatureState& state, T finalDefaultValue) const { assert(!isFeatureConstant()); return evaluate(expression::EvaluationContext(zoom, &feature, &state), finalDefaultValue); diff --git a/metrics/ignores/platform-all.json b/metrics/ignores/platform-all.json index f27941a3b6..e9ee792f37 100644 --- a/metrics/ignores/platform-all.json +++ b/metrics/ignores/platform-all.json @@ -132,6 +132,5 @@ "render-tests/text-variable-anchor/left-top-right-buttom-offset-tile-map-mode":"https://github.com/mapbox/mapbox-gl-js/pull/9202", "render-tests/line-pattern/with-dasharray":"https://github.com/mapbox/mapbox-gl-js/pull/9189", "render-tests/symbol-sort-key/placement-tile-boundary-right-then-left": "https://github.com/mapbox/mapbox-gl-js/pull/9054", - "render-tests/line-dasharray/zero-length-gap":"https://github.com/mapbox/mapbox-gl-js/pull/9246", - "render-tests/within/layout-text": "TODO: Fix by enabling `within` expreesion with layout property" + "render-tests/line-dasharray/zero-length-gap":"https://github.com/mapbox/mapbox-gl-js/pull/9246" } diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index 81ff3996db..8d612d2589 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -45,7 +45,8 @@ struct PatternFeatureInserter<void> { std::unique_ptr<GeometryTileFeature> feature, PatternLayerMap patternDependencyMap, float /*zoom*/, - const PropertiesType&) { + const PropertiesType&, + const CanonicalTileID&) { features.emplace_back(index, std::move(feature), std::move(patternDependencyMap)); } }; @@ -58,9 +59,10 @@ struct PatternFeatureInserter { std::unique_ptr<GeometryTileFeature> feature, PatternLayerMap patternDependencyMap, float zoom, - const PropertiesType& properties) { + const PropertiesType& properties, + const CanonicalTileID& canonical) { const auto& sortKeyProperty = properties.template get<SortKeyPropertyType>(); - float sortKey = sortKeyProperty.evaluate(*feature, zoom, SortKeyPropertyType::defaultValue()); + float sortKey = sortKeyProperty.evaluate(*feature, zoom, canonical, SortKeyPropertyType::defaultValue()); PatternFeature patternFeature{index, std::move(feature), std::move(patternDependencyMap), sortKey}; const auto lowerBound = std::lower_bound(features.cbegin(), features.cend(), patternFeature); features.insert(lowerBound, std::move(patternFeature)); @@ -127,12 +129,17 @@ public: const auto min = patternProperty.evaluate(*feature, zoom - 1, layoutParameters.availableImages, + parameters.tileID.canonical, + PatternPropertyType::defaultValue()); + const auto mid = patternProperty.evaluate(*feature, + zoom, + layoutParameters.availableImages, + parameters.tileID.canonical, PatternPropertyType::defaultValue()); - const auto mid = patternProperty.evaluate( - *feature, zoom, layoutParameters.availableImages, PatternPropertyType::defaultValue()); const auto max = patternProperty.evaluate(*feature, zoom + 1, layoutParameters.availableImages, + parameters.tileID.canonical, PatternPropertyType::defaultValue()); layoutParameters.imageDependencies.emplace(min.to.id(), ImageType::Pattern); @@ -145,14 +152,17 @@ public: } } - PatternFeatureInserter<SortKeyPropertyType>::insert( - features, i, std::move(feature), std::move(patternDependencyMap), zoom, layout); + PatternFeatureInserter<SortKeyPropertyType>::insert(features, + i, + std::move(feature), + std::move(patternDependencyMap), + zoom, + layout, + parameters.tileID.canonical); } }; - bool hasDependencies() const override { - return hasPattern; - } + bool hasDependencies() const override { return hasPattern; } void createBucket(const ImagePositions& patternPositions, std::unique_ptr<FeatureIndex>& featureIndex, diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index e954a26a50..63ce223574 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -86,6 +86,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, sourceLayer(std::move(sourceLayer_)), overscaling(parameters.tileID.overscaleFactor()), zoom(parameters.tileID.overscaledZ), + canonicalID(parameters.tileID.canonical), mode(parameters.mode), pixelRatio(parameters.pixelRatio), tileSize(util::tileSize * overscaling), @@ -141,9 +142,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, ft.index = i; if (hasText) { - auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages); - auto textTransform = layout->evaluate<TextTransform>(zoom, ft); - FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft); + auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages, canonicalID); + auto textTransform = layout->evaluate<TextTransform>(zoom, ft, canonicalID); + FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft, canonicalID); ft.formattedText = TaggedString(); for (const auto & section : formatted.sections) { @@ -188,13 +189,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } if (hasIcon) { - ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages); + ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages, canonicalID); layoutParameters.imageDependencies.emplace(ft.icon->id(), ImageType::Icon); } if (ft.formattedText || ft.icon) { if (sortFeaturesByKey) { - ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft); + ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft, canonicalID); const auto lowerBound = std::lower_bound(features.begin(), features.end(), ft); features.insert(lowerBound, std::move(ft)); } else { @@ -355,14 +356,16 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, ShapedTextOrientations shapedTextOrientations; optional<PositionedIcon> shapedIcon; std::array<float, 2> textOffset{{0.0f, 0.0f}}; - const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature); - const float layoutTextSizeAtBucketZoomLevel = layout->evaluate<TextSize>(zoom, feature); - const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature); + const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature, canonicalID); + const float layoutTextSizeAtBucketZoomLevel = layout->evaluate<TextSize>(zoom, feature, canonicalID); + const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature, canonicalID); // if feature has text, shape the text if (feature.formattedText && layoutTextSize > 0.0f) { const float lineHeight = layout->get<TextLineHeight>() * util::ONE_EM; - const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout->evaluate<TextLetterSpacing>(zoom, feature) * util::ONE_EM : 0.0f; + const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) + ? layout->evaluate<TextLetterSpacing>(zoom, feature, canonicalID) * util::ONE_EM + : 0.0f; auto applyShaping = [&](const TaggedString& formattedText, WritingModeType writingMode, @@ -371,7 +374,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const Shaping result = getShaping( /* string */ formattedText, /* maxWidth: ems */ - isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f, + isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature, canonicalID) * util::ONE_EM : 0.0f, /* ems */ lineHeight, textAnchor, textJustify, @@ -389,22 +392,24 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, return result; }; - const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout->evaluate<TextVariableAnchor>(zoom, feature); - const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature); + const std::vector<style::TextVariableAnchorType> variableTextAnchor = + layout->evaluate<TextVariableAnchor>(zoom, feature, canonicalID); + const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature, canonicalID); if (variableTextAnchor.empty()) { // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector // is calculated at placement time instead of layout time - const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature); + const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature, canonicalID); if (radialOffset > 0.0f) { // The style spec says don't use `text-offset` and `text-radial-offset` together // but doesn't actually specify what happens if you use both. We go with the radial offset. textOffset = evaluateRadialOffset(textAnchor, radialOffset * util::ONE_EM); } else { - textOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, - layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}}; + textOffset = {{layout->evaluate<TextOffset>(zoom, feature, canonicalID)[0] * util::ONE_EM, + layout->evaluate<TextOffset>(zoom, feature, canonicalID)[1] * util::ONE_EM}}; } } - TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature); + TextJustifyType textJustify = + textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature, canonicalID); const auto addVerticalShapingForPointLabelIfNeeded = [&] { if (allowVerticalPlacement && feature.formattedText->allowsVerticalWritingMode()) { @@ -474,8 +479,8 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, if (image != imageMap.end()) { iconType = SymbolContent::IconRGBA; shapedIcon = PositionedIcon::shapeIcon(imagePositions.at(feature.icon->id()), - layout->evaluate<IconOffset>(zoom, feature), - layout->evaluate<IconAnchor>(zoom, feature)); + layout->evaluate<IconOffset>(zoom, feature, canonicalID), + layout->evaluate<IconAnchor>(zoom, feature, canonicalID)); if (image->second->sdf) { iconType = SymbolContent::IconSDF; } @@ -520,13 +525,13 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float minScale = 0.5f; const float glyphSize = 24.0f; - const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature); + const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature, canonicalID); // To reduce the number of labels that jump around when zooming we need // to use a text-size value that is the same for all zoom levels. // This calculates text-size at a high zoom level so that all tiles can // use the same value when calculating anchor positions. - const float textMaxSize = layout->evaluate<TextSize>(18, feature); + const float textMaxSize = layout->evaluate<TextSize>(18, feature, canonicalID); const float fontScale = layoutTextSize / glyphSize; const float textBoxScale = tilePixelRatio * fontScale; @@ -536,15 +541,15 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float textPadding = layout->get<TextPadding>() * tilePixelRatio; const float iconPadding = layout->get<IconPadding>() * tilePixelRatio; const float textMaxAngle = layout->get<TextMaxAngle>() * util::DEG2RAD; - const float iconRotation = layout->evaluate<IconRotate>(zoom, feature); - const float textRotation = layout->evaluate<TextRotate>(zoom, feature); + const float iconRotation = layout->evaluate<IconRotate>(zoom, feature, canonicalID); + const float textRotation = layout->evaluate<TextRotate>(zoom, feature, canonicalID); std::array<float, 2> variableTextOffset; if (!textRadialOffset.isUndefined()) { - variableTextOffset = {{layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM, - INVALID_OFFSET_VALUE}}; + variableTextOffset = { + {layout->evaluate<TextRadialOffset>(zoom, feature, canonicalID) * util::ONE_EM, INVALID_OFFSET_VALUE}}; } else { - variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, - layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}}; + variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature, canonicalID)[0] * util::ONE_EM, + layout->evaluate<TextOffset>(zoom, feature, canonicalID)[1] * util::ONE_EM}}; } const SymbolPlacementType textPlacement = layout->get<TextRotationAlignment>() != AlignmentType::Map diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 740a69df9e..a1c0b86fd9 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -115,6 +115,7 @@ private: const std::unique_ptr<GeometryTileLayer> sourceLayer; const float overscaling; const float zoom; + const CanonicalTileID canonicalID; const MapMode mode; const float pixelRatio; diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index 73c2530241..f42dc59579 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -115,7 +115,7 @@ void FillBucket::addFeature(const GeometryTileFeature& feature, for (auto& pair : paintPropertyBinders) { const auto it = patternDependencies.find(pair.first); - if (it != patternDependencies.end()){ + if (it != patternDependencies.end()) { pair.second.populateVertexVectors( feature, vertices.elements(), index, patternPositions, it->second, canonical); } else { diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index fdb110bc9d..55593aaa66 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -34,7 +34,7 @@ void LineBucket::addFeature(const GeometryTileFeature& feature, std::size_t index, const CanonicalTileID& canonical) { for (auto& line : geometryCollection) { - addGeometry(line, feature); + addGeometry(line, feature, canonical); } for (auto& pair : paintPropertyBinders) { @@ -97,7 +97,9 @@ private: double total; }; -void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const GeometryTileFeature& feature) { +void LineBucket::addGeometry(const GeometryCoordinates& coordinates, + const GeometryTileFeature& feature, + const CanonicalTileID& canonical) { const FeatureType type = feature.getType(); const std::size_t len = [&coordinates] { std::size_t l = coordinates.size(); @@ -137,7 +139,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome *numericValue<double>(clip_start_it->second), *numericValue<double>(clip_end_it->second), total_length}; } - const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature); + const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature, canonical); const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index a3821d108b..111c16b348 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -52,7 +52,7 @@ public: std::map<std::string, LineProgram::Binders> paintPropertyBinders; private: - void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&); + void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&, const CanonicalTileID&); struct TriangleElement { TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp index 5e412855a4..466e042cbc 100644 --- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp +++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp @@ -51,6 +51,14 @@ public: } template <class Feature> + T evaluate(const Feature& feature, float zoom, const CanonicalTileID& canonical, T defaultValue) const { + return this->match([&](const T& constant_) { return constant_; }, + [&](const style::PropertyExpression<T>& expression) { + return expression.evaluate(zoom, feature, canonical, defaultValue); + }); + } + + template <class Feature> T evaluate(const Feature& feature, float zoom, const FeatureState& featureState, T defaultValue) const { return this->match([&](const T& constant_) { return constant_; }, [&](const style::PropertyExpression<T>& expression) { @@ -96,13 +104,15 @@ public: Faded<T> evaluate(const Feature& feature, float zoom, const std::set<std::string>& availableImages, + const CanonicalTileID& canonical, T defaultValue) const { return this->match( [&] (const Faded<T>& constant_) { return constant_; }, [&] (const style::PropertyExpression<T>& expression) { if (!expression.isZoomConstant()) { - const T min = expression.evaluate(floor(zoom), feature, availableImages, defaultValue); - const T max = expression.evaluate(floor(zoom) + 1, feature, availableImages, defaultValue); + const T min = expression.evaluate(floor(zoom), feature, availableImages, canonical, defaultValue); + const T max = + expression.evaluate(floor(zoom) + 1, feature, availableImages, canonical, defaultValue); return Faded<T> {min, max}; } else { const T evaluated = expression.evaluate(feature, availableImages, defaultValue); diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp index 2fab53ad12..39b6672734 100644 --- a/src/mbgl/style/properties.hpp +++ b/src/mbgl/style/properties.hpp @@ -169,6 +169,11 @@ public: } template <class T> + static T evaluate(float, const GeometryTileFeature&, const CanonicalTileID&, const T& t, const T&) { + return t; + } + + template <class T> static T evaluate(float z, const GeometryTileFeature& feature, const PossiblyEvaluatedPropertyValue<T>& v, @@ -194,6 +199,30 @@ public: } template <class T> + static T evaluate(float z, + const GeometryTileFeature& feature, + const PossiblyEvaluatedPropertyValue<T>& v, + const T& defaultValue, + const std::set<std::string>& availableImages, + const CanonicalTileID& canonical) { + return v.match([&](const T& t) { return t; }, + [&](const PropertyExpression<T>& t) { + return t.evaluate(z, feature, availableImages, canonical, defaultValue); + }); + } + + template <class T> + static T evaluate(float z, + const GeometryTileFeature& feature, + const CanonicalTileID& canonical, + const PossiblyEvaluatedPropertyValue<T>& v, + const T& defaultValue) { + return v.match( + [&](const T& t) { return t; }, + [&](const PropertyExpression<T>& t) { return t.evaluate(z, feature, canonical, defaultValue); }); + } + + template <class T> static T evaluate(float z, const GeometryTileFeature& feature, const FeatureState& state, const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) { return v.match([&](const T& t) { return t; }, @@ -220,6 +249,14 @@ public: return evaluate(z, feature, this->template get<P>(), P::defaultValue(), availableImages); } + template <class P> + auto evaluate(float z, + const GeometryTileFeature& feature, + const std::set<std::string>& availableImages, + const CanonicalTileID& canonical) const { + return evaluate(z, feature, this->template get<P>(), P::defaultValue(), availableImages, canonical); + } + Evaluated evaluate(float z, const GeometryTileFeature& feature) const { return Evaluated { evaluate<Ps>(z, feature)... |