summaryrefslogtreecommitdiff
path: root/src/mbgl/layout
diff options
context:
space:
mode:
authorAnand Thakker <anandthakker@users.noreply.github.com>2017-04-06 15:29:59 -0400
committerGitHub <noreply@github.com>2017-04-06 15:29:59 -0400
commit693c9f3641b3189b4cd439049904c95a516ae609 (patch)
tree8341a16f57ff184a2fe9e085c490e8762eb206ce /src/mbgl/layout
parentf9cc044357d60dd5cf15ba951384529f88802089 (diff)
downloadqtlocation-mapboxgl-693c9f3641b3189b4cd439049904c95a516ae609.tar.gz
[core] Add DDS support for {text,icon}-size (#8593)
* Update gl-js and generate style code * Factor out packUint8Pair() helper function * Draft implementation of DDS for {text,icon}-size Ports https://github.com/mapbox/mapbox-gl-js/pull/4455 * Fix text-size/composite-function-line-placement test * Refactor to PaintPropertyBinders-like strategy * Dedupe gl::Program construction * Use exponential function base for interpolation * Dedupe coveringZoomStops method * Fixup tests * Fix CI errors (hidden within #if block)
Diffstat (limited to 'src/mbgl/layout')
-rw-r--r--src/mbgl/layout/symbol_instance.cpp8
-rw-r--r--src/mbgl/layout/symbol_instance.hpp1
-rw-r--r--src/mbgl/layout/symbol_layout.cpp43
-rw-r--r--src/mbgl/layout/symbol_layout.hpp17
4 files changed, 49 insertions, 20 deletions
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 8bdc528bbb..2a3bf068c1 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -10,6 +10,7 @@ SymbolInstance::SymbolInstance(Anchor& anchor,
const std::pair<Shaping, Shaping>& shapedTextOrientations,
const PositionedIcon& shapedIcon,
const SymbolLayoutProperties::Evaluated& layout,
+ const float layoutTextSize,
const bool addToBuffers,
const uint32_t index_,
const float textBoxScale,
@@ -26,15 +27,18 @@ SymbolInstance::SymbolInstance(Anchor& anchor,
hasText(shapedTextOrientations.first || shapedTextOrientations.second),
hasIcon(shapedIcon),
+
// 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),
featureIndex(featureIndex_) {
+
+
// Create the quads used for rendering the icon and glyphs.
if (addToBuffers) {
if (shapedIcon) {
- iconQuad = getIconQuad(anchor, shapedIcon, line, layout, iconPlacement, shapedTextOrientations.first);
+ iconQuad = getIconQuad(anchor, shapedIcon, line, layout, layoutTextSize, iconPlacement, shapedTextOrientations.first);
}
if (shapedTextOrientations.first) {
auto quads = getGlyphQuads(anchor, shapedTextOrientations.first, textBoxScale, line, layout, textPlacement, face);
@@ -55,6 +59,8 @@ SymbolInstance::SymbolInstance(Anchor& anchor,
} else {
writingModes = WritingModeType::None;
}
+
+
}
} // namespace mbgl
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 70ebfeefa2..efe6cb05aa 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -17,6 +17,7 @@ public:
const std::pair<Shaping, Shaping>& shapedTextOrientations,
const PositionedIcon& shapedIcon,
const style::SymbolLayoutProperties::Evaluated&,
+ const float layoutTextSize,
const bool inside,
const uint32_t index,
const float textBoxScale,
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 978caabd70..907e60a598 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -50,7 +50,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
mode(parameters.mode),
spriteAtlasMapIndex(_spriteAtlasMapIndex),
tileSize(util::tileSize * overscaling),
- tilePixelRatio(float(util::EXTENT) / tileSize) {
+ tilePixelRatio(float(util::EXTENT) / tileSize),
+ textSize(layers.at(0)->as<SymbolLayer>()->impl->layout.unevaluated.get<TextSize>()),
+ iconSize(layers.at(0)->as<SymbolLayer>()->impl->layout.unevaluated.get<IconSize>())
+ {
const SymbolLayer::Impl& leader = *layers.at(0)->as<SymbolLayer>()->impl;
@@ -77,11 +80,6 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
layout.get<TextPitchAlignment>() = layout.get<TextRotationAlignment>();
}
- textMaxSize = leader.layout.evaluate<TextSize>(PropertyEvaluationParameters(18));
-
- layout.get<IconSize>() = leader.layout.evaluate<IconSize>(PropertyEvaluationParameters(zoom + 1));
- layout.get<TextSize>() = leader.layout.evaluate<TextSize>(PropertyEvaluationParameters(zoom + 1));
-
const bool hasText = has<TextField>(layout) && !layout.get<TextFont>().empty();
const bool hasIcon = has<IconImage>(layout);
@@ -298,11 +296,20 @@ void SymbolLayout::addFeature(const std::size_t index,
const GlyphPositions& glyphs) {
const float minScale = 0.5f;
const float glyphSize = 24.0f;
-
- const float fontScale = layout.get<TextSize>() / glyphSize;
+
+ const float layoutTextSize = layout.evaluate<TextSize>(zoom + 1, feature);
+ const float layoutIconSize = layout.evaluate<IconSize>(zoom + 1, feature);
+
+ // 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 fontScale = layoutTextSize / glyphSize;
const float textBoxScale = tilePixelRatio * fontScale;
const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize;
- const float iconBoxScale = tilePixelRatio * layout.get<IconSize>();
+ const float iconBoxScale = tilePixelRatio * layoutIconSize;
const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>();
const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line;
const float textPadding = layout.get<TextPadding>() * tilePixelRatio;
@@ -316,7 +323,7 @@ void SymbolLayout::addFeature(const std::size_t index,
: layout.get<SymbolPlacement>();
const float textRepeatDistance = symbolSpacing / 2;
IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, bucketName, symbolInstances.size()};
-
+
auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
// https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
// +-------------------+ Symbols with anchors located on tile edges
@@ -338,7 +345,9 @@ void SymbolLayout::addFeature(const std::size_t index,
const bool addToBuffers = mode == MapMode::Still || withinPlus0;
- symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout.evaluate(zoom, feature), addToBuffers, symbolInstances.size(),
+ symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon,
+ layout.evaluate(zoom, feature), layoutTextSize,
+ addToBuffers, symbolInstances.size(),
textBoxScale, textPadding, textPlacement,
iconBoxScale, iconPadding, iconPlacement,
glyphs, indexedFeature, index);
@@ -413,7 +422,7 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe
}
std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) {
- auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, zoom, sdfIcons, iconsNeedLinear);
+ auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear);
// Calculate which labels can be shown and when they can be shown and
// create the bufers used for rendering.
@@ -477,6 +486,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
iconScale = util::max(iconScale, glyphScale);
}
+ const auto& feature = features.at(symbolInstance.featureIndex);
// Insert final placement into collision tree and add glyphs/icons to buffers
@@ -486,7 +496,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
if (glyphScale < collisionTile.maxScale) {
for (const auto& symbol : symbolInstance.glyphQuads) {
addSymbol(
- bucket->text, symbol, placementZoom,
+ bucket->text, *bucket->textSizeBinder, symbol, feature, placementZoom,
keepUpright, textPlacement, collisionTile.config.angle, symbolInstance.writingModes);
}
}
@@ -497,12 +507,11 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get<IconIgnorePlacement>());
if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad) {
addSymbol(
- bucket->icon, *symbolInstance.iconQuad, placementZoom,
+ bucket->icon, *bucket->iconSizeBinder, *symbolInstance.iconQuad, feature, placementZoom,
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());
@@ -518,7 +527,9 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
template <typename Buffer>
void SymbolLayout::addSymbol(Buffer& buffer,
+ SymbolSizeBinder& sizeBinder,
const SymbolQuad& symbol,
+ const SymbolFeature& feature,
const float placementZoom,
const bool keepUpright,
const style::SymbolPlacementType placement,
@@ -580,6 +591,8 @@ void SymbolLayout::addSymbol(Buffer& buffer,
minZoom, maxZoom, placementZoom, glyphAngle));
buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, tex.x + tex.w, tex.y + tex.h,
minZoom, maxZoom, placementZoom, glyphAngle));
+
+ sizeBinder.populateVertexVector(feature);
// add the two triangles, referencing the four coordinates we just inserted.
buffer.triangles.emplace_back(index + 0, index + 1, index + 2);
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index d79ccb3273..4ec84f0f58 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -6,6 +6,7 @@
#include <mbgl/layout/symbol_instance.hpp>
#include <mbgl/text/bidi.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
+#include <mbgl/programs/symbol_program.hpp>
#include <memory>
#include <map>
@@ -64,9 +65,15 @@ private:
// Adds placed items to the buffer.
template <typename Buffer>
- void addSymbol(Buffer&, const SymbolQuad&, float scale,
- const bool keepUpright, const style::SymbolPlacementType, const float placementAngle,
- WritingModeType writingModes);
+ void addSymbol(Buffer&,
+ SymbolSizeBinder& sizeBinder,
+ const SymbolQuad&,
+ const SymbolFeature& feature,
+ float scale,
+ const bool keepUpright,
+ const style::SymbolPlacementType,
+ const float placementAngle,
+ WritingModeType writingModes);
const std::string sourceLayerName;
const std::string bucketName;
@@ -75,7 +82,6 @@ private:
const MapMode mode;
style::SymbolLayoutProperties::PossiblyEvaluated layout;
- float textMaxSize;
uintptr_t spriteAtlasMapIndex; // Actually a pointer to the SpriteAtlas for this symbol's layer, but don't use it from worker threads!
@@ -84,6 +90,9 @@ private:
bool sdfIcons = false;
bool iconsNeedLinear = false;
+
+ style::TextSize::UnevaluatedType textSize;
+ style::IconSize::UnevaluatedType iconSize;
std::vector<SymbolInstance> symbolInstances;
std::vector<SymbolFeature> features;