Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] don't hide icons if text is an empty string #11206

Merged
merged 1 commit into from
Feb 21, 2018

Conversation

ansis
Copy link
Contributor

@ansis ansis commented Feb 14, 2018

@ansis ansis requested a review from ChrisLoer February 14, 2018 20:23
@ansis ansis force-pushed the fix-empty-string-label branch 2 times, most recently from a4d7ede to 88032a7 Compare February 14, 2018 21:57
@ChrisLoer
Copy link
Contributor

ChrisLoer commented Feb 14, 2018

I think there's actually a very subtle difference from the GL JS logic here.

GL JS says "if you have a collision box, try to place it", and in symbol_layout.js it only adds a collision box if the shaping is non-empty:

https://github.com/mapbox/mapbox-gl-js/blob/692ee23a301210a4a98c56e88c7e77c6ffbe4324/src/symbol/symbol_layout.js#L341-L344

But on gl-native, this new logic says "if you have a non-empty shaping, try to place your CollisionFeature". I think in gl-native we'll actually create a CollisionFeature (and accompanying box, potentially with non-zero size due to padding) even if the shaping is empty:

// if either shapedText or icon position is present, add the feature
if (shapedTextOrientations.first || shapedIcon) {
addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositionMap, tileID, sourceID);
}

// Create the collision features that will be used to check whether this symbol instance can be placed
textCollisionFeature(line_, anchor, shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature, overscaling),
iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature),

Did the new test fail before you made these changes? It seems to me like they may not be necessary (although we should rationalize the behavior between JS and native, I'm starting to think the current native behavior may be more correct?). As it stands, we'll create a collision box but then not use it.

@ansis
Copy link
Contributor Author

ansis commented Feb 15, 2018

@ChrisLoer good point. I need to dig into this more

Did the new test fail before you made these changes?

Yep, the test fails without these changes

@ChrisLoer
Copy link
Contributor

I just added a native ignore for this for #11156, let's remember to take that out when we merge the fix here.

@ansis
Copy link
Contributor Author

ansis commented Feb 21, 2018

Ok, so, there are three cases we care about: no text, empty string of text, text.

native master creates:

  • zero-sized shapings and collision features for no text
  • zero-plus-padding-sized shapings and collision features for empty strings of text

However, they never get used because this is only true when the text is a non-empty string. So while there are internal differences between native master and old -js, they have the same behaviour.


I think it might be fine to continue treating an empty string of text the same as undefined text. Both would never be tested for collisions. Do you see any good reason to start treating empty strings differently?

I pushed a fix that is equivalent to the previous fix but simpler. It just changes the per-bucket data presence check to a per-feature check. If this looks good, I'll change -js to match this approach (which shouldn't change -js behaviour).

Copy link
Contributor

@ChrisLoer ChrisLoer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, sounds good to me, thanks for digging in. I like the simplicity of the new approach, and it should be a cheap lookup even though it's in an inner loop...

🤔 I wish I could think of a better name for "iconWithoutText", it's not really clear that it's focused on whether a collision happens.

As for whether an empty string should be treated as "undefined" vs "defined but 0-length", I feel like "empty string can be a valid/defined string" is generally a more natural convention. If someone defines the text to be set to the result of some variable, they're going to expect "this symbol has text", and not expect there to be different behavior if the variable happens to evaluate to an empty string. But it's hard for me to see how it would make any practical difference in this case.

@ansis ansis merged commit ebb72b9 into master Feb 21, 2018
@ansis ansis deleted the fix-empty-string-label branch February 21, 2018 19:38
@friedbunny friedbunny added Core The cross-platform C++ core, aka mbgl rendering labels Apr 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl rendering
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants