diff options
author | Anand Thakker <anandthakker@users.noreply.github.com> | 2017-02-28 19:54:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-28 19:54:24 -0800 |
commit | f901e776b3e63aaaa6bc0cc4476624bf84127fe6 (patch) | |
tree | 3e311971d57109c64e5ace45c111fb5909e7fb7b /src/mbgl/layout | |
parent | c3ed1f51ca677c8c2045320fe13ec881cbd94772 (diff) | |
download | qtlocation-mapboxgl-f901e776b3e63aaaa6bc0cc4476624bf84127fe6.tar.gz |
[core] Implement data-driven styling for {text,icon}-{color,opacity,halo-color,halo-blur,halo-width} (#7939)
* Add symbol dds attributes and adapt style code generation
* Update to mapbox-gl-js/master
* Refactor SymbolFeature as a subclass of GeometryTileFeature
Prepares for enabling DDS on symbol paint properties by allowing the
SymbolFeatures, which we keep around after constructing SymbolLayout,
to be used in evaluating data-driven paint properties later in the
layout process.
* Draft approach for splitting icon/text paint properties
The `Program` types are set up to bind GL attributes to each of the
data-driven paint properties specified in the `PaintProperties` type
provided. Since `SymbolPaintProperties` specifies both `Text*` and
`Icon*` properties, the symbolIcon, symbolIconSDF, and symbolGlyph
programs each attempt to bind roughly double the number of attributes
that they actually need.
This change addresses this by:
- Adding the more specific `IconPaintProperties` and `TextPaintProperties` types, which are subsets of the full `SymbolPaintProperties`.
- The symbol layer continues to use its `SymbolPaintProperties paint` member to track layer property state, but it provides helpers that construct objects of each the specific `{Icon,Text}PaintProperties::Evaluated` type, for use by the painter.
- The three symbol programs instantiate `Program<>` using the appropriate `{Icon,Text}PaintProperties` type.
* check in generated style code
* Populate paint buffers for symbol DDS properties
* Address first round of review comments
* Refactor VectorTile{Layer,Feature} to explicitly share data
* Update submodule
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r-- | src/mbgl/layout/symbol_feature.hpp | 17 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_instance.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 51 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.hpp | 7 |
5 files changed, 55 insertions, 28 deletions
diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index e55995f952..f4dc1680bc 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -8,14 +8,23 @@ namespace mbgl { -class SymbolFeature { +class SymbolFeature : public GeometryTileFeature { public: - FeatureType type; + SymbolFeature(std::unique_ptr<GeometryTileFeature> feature_) : + feature(std::move(feature_)), + geometry(feature->getGeometries()) // we need a mutable copy of the geometry for mergeLines() + {} + + FeatureType getType() const override { return feature->getType(); } + optional<Value> getValue(const std::string& key) const override { return feature->getValue(key); }; + std::unordered_map<std::string,Value> getProperties() const override { return feature->getProperties(); }; + optional<FeatureIdentifier> getID() const override { return feature->getID(); }; + GeometryCollection getGeometries() const override { return geometry; }; + + std::unique_ptr<GeometryTileFeature> feature; GeometryCollection geometry; optional<std::u16string> text; optional<std::string> icon; - std::array<float, 2> iconOffset; - float iconRotation; std::size_t index; }; diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 4f425641e7..d81783b2f6 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -10,7 +10,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, const bool addToBuffers, const uint32_t index_, const float textBoxScale, const float textPadding, const SymbolPlacementType textPlacement, const float iconBoxScale, const float iconPadding, const SymbolPlacementType iconPlacement, - const GlyphPositions& face, const IndexedSubfeature& indexedFeature) : + const GlyphPositions& face, const IndexedSubfeature& indexedFeature, const std::size_t featureIndex_) : point(anchor.point), index(index_), hasText(shapedTextOrientations.first || shapedTextOrientations.second), @@ -18,7 +18,8 @@ SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, // Create the collision features that will be used to check whether this symbol instance can be placed textCollisionFeature(line, anchor, shapedTextOrientations.second ?: shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature), - iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconPlacement, indexedFeature) { + iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconPlacement, indexedFeature), + featureIndex(featureIndex_) { // Create the quads used for rendering the icon and glyphs. if (addToBuffers) { diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 2dbb3bac23..532a4d30d8 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -17,7 +17,7 @@ public: const style::SymbolLayoutProperties::Evaluated&, const bool inside, const uint32_t index, const float textBoxScale, const float textPadding, style::SymbolPlacementType textPlacement, const float iconBoxScale, const float iconPadding, style::SymbolPlacementType iconPlacement, - const GlyphPositions& face, const IndexedSubfeature& indexedfeature); + const GlyphPositions& face, const IndexedSubfeature& indexedfeature, const std::size_t featureIndex); Point<float> point; uint32_t index; @@ -28,6 +28,7 @@ public: CollisionFeature textCollisionFeature; CollisionFeature iconCollisionFeature; WritingModeType writingModes; + std::size_t featureIndex; }; } // namespace mbgl diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index cf9e784c26..3a2c082ad8 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -87,7 +87,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, } for (const auto& layer : layers) { - layerPaintProperties.emplace(layer->getID(), layer->as<SymbolLayer>()->impl->paint.evaluated); + layerPaintProperties.emplace(layer->getID(), std::make_pair( + layer->as<SymbolLayer>()->impl->iconPaintProperties(), + layer->as<SymbolLayer>()->impl->textPaintProperties() + )); } // Determine and load glyph ranges @@ -96,12 +99,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, auto feature = sourceLayer.getFeature(i); if (!leader.filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); })) continue; + + SymbolFeature ft(std::move(feature)); - SymbolFeature ft; ft.index = i; - auto getValue = [&feature](const std::string& key) -> std::string { - auto value = feature->getValue(key); + auto getValue = [&ft](const std::string& key) -> std::string { + auto value = ft.getValue(key); if (!value) return std::string(); if (value->is<std::string>()) @@ -118,12 +122,12 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, }; if (hasText) { - std::string u8string = layout.evaluate<TextField>(zoom, *feature); + std::string u8string = layout.evaluate<TextField>(zoom, ft); if (layout.get<TextField>().isConstant()) { u8string = util::replaceTokens(u8string, getValue); } - auto textTransform = layout.evaluate<TextTransform>(zoom, *feature); + auto textTransform = layout.evaluate<TextTransform>(zoom, ft); if (textTransform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -144,13 +148,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, if (hasIcon) { ft.icon = util::replaceTokens(layout.get<IconImage>(), getValue); - ft.iconOffset = layout.evaluate<IconOffset>(zoom, *feature); - ft.iconRotation = layout.evaluate<IconRotate>(zoom, *feature) * util::DEG2RAD; } if (ft.text || ft.icon) { - ft.type = feature->getType(); - ft.geometry = feature->getGeometries(); features.push_back(std::move(ft)); } } @@ -229,7 +229,8 @@ void SymbolLayout::prepare(uintptr_t tileUID, const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && layout.get<SymbolPlacement>() == SymbolPlacementType::Line; - for (const auto& feature : features) { + for (auto it = features.begin(); it != features.end(); ++it) { + auto& feature = *it; if (feature.geometry.empty()) continue; std::pair<Shaping, Shaping> shapedTextOrientations; @@ -273,7 +274,9 @@ void SymbolLayout::prepare(uintptr_t tileUID, if (feature.icon) { auto image = spriteAtlas.getIcon(*feature.icon); if (image) { - shapedIcon = shapeIcon(*image, feature); + shapedIcon = shapeIcon(*image, + layout.evaluate<IconOffset>(zoom, feature), + layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); assert((*image).spriteImage); if ((*image).spriteImage->sdf) { sdfIcons = true; @@ -288,15 +291,17 @@ void SymbolLayout::prepare(uintptr_t tileUID, // if either shapedText or icon position is present, add the feature if (shapedTextOrientations.first || shapedIcon) { - addFeature(feature, shapedTextOrientations, shapedIcon, face); + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, face); } + + feature.geometry.clear(); } - features.clear(); compareText.clear(); } -void SymbolLayout::addFeature(const SymbolFeature& feature, +void SymbolLayout::addFeature(const std::size_t index, + const SymbolFeature& feature, const std::pair<Shaping, Shaping>& shapedTextOrientations, const PositionedIcon& shapedIcon, const GlyphPositions& face) { @@ -345,8 +350,10 @@ void SymbolLayout::addFeature(const SymbolFeature& feature, symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout, addToBuffers, symbolInstances.size(), textBoxScale, textPadding, textPlacement, iconBoxScale, iconPadding, iconPlacement, - face, indexedFeature); + face, indexedFeature, index); }; + + const auto& type = feature.getType(); if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) { auto clippedLines = util::clipLines(feature.geometry, 0, 0, util::EXTENT, util::EXTENT); @@ -368,7 +375,7 @@ void SymbolLayout::addFeature(const SymbolFeature& feature, } } } - } else if (feature.type == FeatureType::Polygon) { + } else if (type == FeatureType::Polygon) { for (const auto& polygon : classifyRings(feature.geometry)) { Polygon<double> poly; for (const auto& ring : polygon) { @@ -384,12 +391,12 @@ void SymbolLayout::addFeature(const SymbolFeature& feature, Anchor anchor(poi.x, poi.y, 0, minScale); addSymbolInstance(polygon[0], anchor); } - } else if (feature.type == FeatureType::LineString) { + } else if (type == FeatureType::LineString) { for (const auto& line : feature.geometry) { Anchor anchor(line[0].x, line[0].y, 0, minScale); addSymbolInstance(line, anchor); } - } else if (feature.type == FeatureType::Point) { + } else if (type == FeatureType::Point) { for (const auto& points : feature.geometry) { for (const auto& point : points) { Anchor anchor(point.x, point.y, 0, minScale); @@ -503,6 +510,12 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) keepUpright, iconPlacement, collisionTile.config.angle, symbolInstance.writingModes); } } + + const auto& feature = features.at(symbolInstance.featureIndex); + for (auto& pair : bucket->paintPropertyBinders) { + pair.second.first.populateVertexVectors(feature, bucket->icon.vertices.vertexSize()); + pair.second.second.populateVertexVectors(feature, bucket->text.vertices.vertexSize()); + } } if (collisionTile.config.debug) { diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index dbfdad22d9..491d0078da 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -5,6 +5,7 @@ #include <mbgl/layout/symbol_feature.hpp> #include <mbgl/layout/symbol_instance.hpp> #include <mbgl/text/bidi.hpp> +#include <mbgl/style/layers/symbol_layer_impl.hpp> #include <memory> #include <map> @@ -51,10 +52,12 @@ public: State state = Pending; - std::unordered_map<std::string, style::SymbolPaintProperties::Evaluated> layerPaintProperties; + std::unordered_map<std::string, + std::pair<style::IconPaintProperties::Evaluated, style::TextPaintProperties::Evaluated>> layerPaintProperties; private: - void addFeature(const SymbolFeature&, + void addFeature(const size_t, + const SymbolFeature&, const std::pair<Shaping, Shaping>& shapedTextOrientations, const PositionedIcon& shapedIcon, const GlyphPositions& face); |