@@ -41,7 +41,10 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
41
41
mode(parameters.mode),
42
42
spriteAtlas(spriteAtlas_),
43
43
tileSize(util::tileSize * overscaling),
44
- tilePixelRatio(float (util::EXTENT) / tileSize) {
44
+ tilePixelRatio(float (util::EXTENT) / tileSize),
45
+ textSize(layers.at(0 )->as<SymbolLayer>()->impl->layout.unevaluated.get<TextSize>()),
46
+ iconSize(layers.at(0 )->as<SymbolLayer>()->impl->layout.unevaluated.get<IconSize>())
47
+ {
45
48
46
49
const SymbolLayer::Impl& leader = *layers.at (0 )->as <SymbolLayer>()->impl ;
47
50
@@ -67,12 +70,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
67
70
if (layout.get <TextPitchAlignment>() == AlignmentType::Auto) {
68
71
layout.get <TextPitchAlignment>() = layout.get <TextRotationAlignment>();
69
72
}
70
-
71
- textMaxSize = leader.layout .evaluate <TextSize>(PropertyEvaluationParameters (18 ));
72
-
73
- layout.get <IconSize>() = leader.layout .evaluate <IconSize>(PropertyEvaluationParameters (zoom + 1 ));
74
- layout.get <TextSize>() = leader.layout .evaluate <TextSize>(PropertyEvaluationParameters (zoom + 1 ));
75
-
73
+
76
74
const bool hasTextField = layout.get <TextField>().match (
77
75
[&] (const std::string& s) { return !s.empty (); },
78
76
[&] (const auto &) { return true ; }
@@ -92,7 +90,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
92
90
layer->as <SymbolLayer>()->impl ->textPaintProperties ()
93
91
));
94
92
}
95
-
93
+
96
94
// Determine and load glyph ranges
97
95
const size_t featureCount = sourceLayer.featureCount ();
98
96
for (size_t i = 0 ; i < featureCount; ++i) {
@@ -307,11 +305,20 @@ void SymbolLayout::addFeature(const std::size_t index,
307
305
const GlyphPositions& face) {
308
306
const float minScale = 0 .5f ;
309
307
const float glyphSize = 24 .0f ;
310
-
311
- const float fontScale = layout.get <TextSize>() / glyphSize;
308
+
309
+ const float layoutTextSize = layout.evaluate <TextSize>(zoom + 1 , feature);
310
+ const float layoutIconSize = layout.evaluate <IconSize>(zoom + 1 , feature);
311
+
312
+ // To reduce the number of labels that jump around when zooming we need
313
+ // to use a text-size value that is the same for all zoom levels.
314
+ // This calculates text-size at a high zoom level so that all tiles can
315
+ // use the same value when calculating anchor positions.
316
+ const float textMaxSize = layout.evaluate <TextSize>(18 , feature);
317
+
318
+ const float fontScale = layoutTextSize / glyphSize;
312
319
const float textBoxScale = tilePixelRatio * fontScale;
313
320
const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize;
314
- const float iconBoxScale = tilePixelRatio * layout. get <IconSize>() ;
321
+ const float iconBoxScale = tilePixelRatio * layoutIconSize ;
315
322
const float symbolSpacing = tilePixelRatio * layout.get <SymbolSpacing>();
316
323
const bool avoidEdges = layout.get <SymbolAvoidEdges>() && layout.get <SymbolPlacement>() != SymbolPlacementType::Line;
317
324
const float textPadding = layout.get <TextPadding>() * tilePixelRatio;
@@ -325,6 +332,8 @@ void SymbolLayout::addFeature(const std::size_t index,
325
332
: layout.get <SymbolPlacement>();
326
333
const float textRepeatDistance = symbolSpacing / 2 ;
327
334
IndexedSubfeature indexedFeature = {feature.index , sourceLayerName, bucketName, symbolInstances.size ()};
335
+
336
+
328
337
329
338
auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
330
339
// https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
@@ -347,7 +356,8 @@ void SymbolLayout::addFeature(const std::size_t index,
347
356
348
357
const bool addToBuffers = mode == MapMode::Still || withinPlus0;
349
358
350
- symbolInstances.emplace_back (anchor, line, shapedTextOrientations, shapedIcon, layout, addToBuffers, symbolInstances.size (),
359
+ symbolInstances.emplace_back (anchor, line, shapedTextOrientations, shapedIcon, layout, layoutTextSize,
360
+ addToBuffers, symbolInstances.size (),
351
361
textBoxScale, textPadding, textPlacement,
352
362
iconBoxScale, iconPadding, iconPlacement,
353
363
face, indexedFeature, index );
@@ -422,7 +432,7 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe
422
432
}
423
433
424
434
std::unique_ptr<SymbolBucket> SymbolLayout::place (CollisionTile& collisionTile) {
425
- auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, zoom, sdfIcons, iconsNeedLinear);
435
+ auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear);
426
436
427
437
// Calculate which labels can be shown and when they can be shown and
428
438
// create the bufers used for rendering.
@@ -486,6 +496,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
486
496
iconScale = util::max (iconScale, glyphScale);
487
497
}
488
498
499
+ const auto & feature = features.at (symbolInstance.featureIndex );
489
500
490
501
// Insert final placement into collision tree and add glyphs/icons to buffers
491
502
@@ -495,7 +506,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
495
506
if (glyphScale < collisionTile.maxScale ) {
496
507
for (const auto & symbol : symbolInstance.glyphQuads ) {
497
508
addSymbol (
498
- bucket->text , symbol, placementZoom,
509
+ bucket->text , bucket-> textSizeData , symbol, feature, textSize , placementZoom,
499
510
keepUpright, textPlacement, collisionTile.config .angle , symbolInstance.writingModes );
500
511
}
501
512
}
@@ -506,12 +517,11 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
506
517
collisionTile.insertFeature (symbolInstance.iconCollisionFeature , iconScale, layout.get <IconIgnorePlacement>());
507
518
if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad ) {
508
519
addSymbol (
509
- bucket->icon , *symbolInstance.iconQuad , placementZoom,
520
+ bucket->icon , bucket-> iconSizeData , *symbolInstance.iconQuad , feature, iconSize , placementZoom,
510
521
keepUpright, iconPlacement, collisionTile.config .angle , symbolInstance.writingModes );
511
522
}
512
523
}
513
524
514
- const auto & feature = features.at (symbolInstance.featureIndex );
515
525
for (auto & pair : bucket->paintPropertyBinders ) {
516
526
pair.second .first .populateVertexVectors (feature, bucket->icon .vertices .vertexSize ());
517
527
pair.second .second .populateVertexVectors (feature, bucket->text .vertices .vertexSize ());
@@ -527,7 +537,10 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
527
537
528
538
template <typename Buffer>
529
539
void SymbolLayout::addSymbol (Buffer& buffer,
540
+ SymbolSizeData& sizeData,
530
541
const SymbolQuad& symbol,
542
+ const SymbolFeature& feature,
543
+ const style::DataDrivenPropertyValue<float >& size,
531
544
const float placementZoom,
532
545
const bool keepUpright,
533
546
const style::SymbolPlacementType placement,
@@ -589,6 +602,36 @@ void SymbolLayout::addSymbol(Buffer& buffer,
589
602
minZoom, maxZoom, placementZoom, glyphAngle));
590
603
buffer.vertices .emplace_back (SymbolLayoutAttributes::vertex (anchorPoint, br, tex.x + tex.w , tex.y + tex.h ,
591
604
minZoom, maxZoom, placementZoom, glyphAngle));
605
+
606
+
607
+ size.match (
608
+ [&] (const style::CompositeFunction<float >& fn) {
609
+ const auto sizeVertex = SymbolSizeAttributes::Vertex {
610
+ {{
611
+ static_cast <uint16_t >(fn.evaluate (sizeData.coveringZoomStops ->min , feature, sizeData.defaultSize ) * 10 ),
612
+ static_cast <uint16_t >(fn.evaluate (sizeData.coveringZoomStops ->max , feature, sizeData.defaultSize ) * 10 ),
613
+ static_cast <uint16_t >(fn.evaluate (zoom + 1 , feature, sizeData.defaultSize ) * 10 )
614
+ }}
615
+ };
616
+ auto & vertexVector = sizeData.vertices .get <gl::VertexVector<SymbolSizeAttributes::Vertex>>();
617
+ vertexVector.emplace_back (sizeVertex);
618
+ vertexVector.emplace_back (sizeVertex);
619
+ vertexVector.emplace_back (sizeVertex);
620
+ vertexVector.emplace_back (sizeVertex);
621
+ },
622
+ [&] (const style::SourceFunction<float >& fn) {
623
+ const auto sizeVertex = SymbolSizeAttributes::SourceFunctionVertex {
624
+ {{ static_cast <uint16_t >(fn.evaluate (feature, sizeData.defaultSize ) * 10 ) }}
625
+ };
626
+
627
+ auto & vertexVector = sizeData.vertices .get <gl::VertexVector<SymbolSizeAttributes::SourceFunctionVertex>>();
628
+ vertexVector.emplace_back (sizeVertex);
629
+ vertexVector.emplace_back (sizeVertex);
630
+ vertexVector.emplace_back (sizeVertex);
631
+ vertexVector.emplace_back (sizeVertex);
632
+ },
633
+ [] (const auto &) {}
634
+ );
592
635
593
636
// add the two triangles, referencing the four coordinates we just inserted.
594
637
buffer.triangles .emplace_back (index + 0 , index + 1 , index + 2 );
0 commit comments