-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable vertical point label placement via 'text-writing-mode' style property #8399
Conversation
Finally managed to run the benchmarks, screenshot linked in the description above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with the symbol placement code, but there's a few nitpicky comments here.
💯 Fo all the render tests!
@@ -319,6 +324,17 @@ class SymbolBucket implements Bucket { | |||
this.sortFeaturesByY = zOrderByViewportY && (layout.get('text-allow-overlap') || layout.get('icon-allow-overlap') || | |||
layout.get('text-ignore-placement') || layout.get('icon-ignore-placement')); | |||
|
|||
if (layout.get('symbol-placement') === 'point') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered doing the duplicate removal during style parsing. That way layer grouping can be done on the de-duped value. As it stands, two layers with all other properties identical, but text-writing-mode
set to ['horizontal']
vs ['horizontal', 'horizontal']
will not be grouped.
With that change, the de-duping can also be done for the style, and not for each tile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like most of this PR I had just copied what @alexshalamov had done in mapbox/mapbox-gl-native#14932, that's why this was done here. I hadn't considered doing it during style parsing (I'm not really familiar with that yet) but what you suggest makes sense to me - I'll look into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asheemmamoowala same is applicable for text-variable-anchor
, duplicates should be removed before layers are grouped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Captured in #8445
@@ -199,7 +200,8 @@ function shapeText(text: Formatted, | |||
left: translate[0], | |||
right: translate[0], | |||
writingMode, | |||
lineCount: lines.length | |||
lineCount: lines.length, | |||
yOffset: -17 // the y offset *should* be part of the font metadata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is confusing to me. If the comment is suggesting that the yOffset
is hard-coded here because it is not currently part of the font metadata, can that be clarified a bit. Is that going to be worked on in a separate ticket?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
src/symbol/placement.js
Outdated
const height = collisionTextBox.y2 - collisionTextBox.y1; | ||
const textBoxScale = symbolInstance.textBoxScale; | ||
|
||
let placedBox = { box: null, offscreen: null }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placedBox
type is Missing flow type annotation. Probably also good to annotate the return type of attemptAnchorPlacement()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my own learning as I am still new to Flow:
- how would this pass Flow tests if some annotation was missing?
- why would we want to annotate
placedBox
but notwidth
height
etc? - If I'm reading correctly, many (most?) of the functions in this module - including
attemptAnchorPlacement()
- were already missing return value annotations. Should they all be added, and if so does it make sense for that to be part of this PR? Seems like it might make more sense to be addressed separately..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how would this pass Flow tests if some annotation was missing?
Flow does not test for missing annotations and cannot test objects/methods that are not annotated. That allows subtle bugs in those areas of code to be introduced without the ability to
why would we want to annotate placedBox but not width height etc?
collisionTextBox
is typed as a SingleCollisionBox
, implying that width
and height
will be treated as number
types.
If I'm reading correctly, many (most?) of the functions in this module [...] were already missing return value annotations. Should they all be added, and if so does it make sense for that to be part of this PR? Seems like it might make more sense to be addressed separately..
I prefer to add annotations to methods when I make a bunch of changes to them - it allows for learning the contracts of a method, and how it is used. But this can also be tackled in a separate PR - as a larger fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks great to me. Some parts are tricky to understand but I think that's just the area of the code. I don't have any suggestions to make things clearer. I think your decision to stick close to the -native pr is great and will make future adjustments easier to do in both projects.
👍
@@ -199,7 +200,8 @@ function shapeText(text: Formatted, | |||
left: translate[0], | |||
right: translate[0], | |||
writingMode, | |||
lineCount: lines.length | |||
lineCount: lines.length, | |||
yOffset: -17 // the y offset *should* be part of the font metadata |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@vakila flagging here too that we should wait to merge this until we address the behavior of Latin characters in vertical point labels |
This reverts commit 069c6f0.
…placement - Add placedOrientation attribute to PlacedSymbol - Add verticalTextBox attributes to SymbolInstance alongside textBox & iconBox
Port changes from gl-native@alexshalamov_wip_vertical_labels (shaping.cpp, quads.cpp glyphs.hpp)
- Add writingModes and allowVerticalPlacement properties to SymbolBucket - Compute writingModes from `text-writing-mode` style property - Determine glyph dependencies based on whether vertical placement is allowed - Rotate symbols as needed
- Add updateVerticalLabels to hide glyphs for unused orientations - Modify updateVariableAnchors to hide unused orientation glyphs when using vertical labels and variable anchors
- Attempt to place vertical/horizontal boxes for each symbol according to writing mode order of preference - Integrate with variable-anchor placement to try each anchor/orientation combination possible - Prefer previously placed orientations & anchors - Hide unplaced orientations
Add yOffset property to shaping objects
Add tests for vertical placement of point labels with: - CJK text with punctuation - multiline mixed CJK/latin text - CJK with embedded Arabic RTL text
This reverts commit 3ff7480.
Latin characters will also be verticalized in LGTM! |
This change forces glyphs whose natural orientation in vertical writing mode is 'sideways' to be rendered in upright orientation (only for non complex text layouts). This is different compared to W3C / browser behavior that is by default, renders glyphs in their respective natural orientation. In the future, there might need to add a new layout property that would control glyph orientation separately (e.g., text-glyph-orientation: natural | upright).
@asheemmamoowala could you please take a look at last two commits? Initially I verticalized all characters that do not have upright glyph orientation, but then, shaped Arabic text became unreadable, so I had to exclude it (and whitespace) from verticalization. Not sure if did it correctly and whether I need to exclude other ranges. |
Thanks @alexshalamov for the updates! I think excluding Arabic from verticalization is indeed the right approach 👍 As you mention, we may ultimately want to also exclude other scripts that don't work well vertically, e.g. Hindi? But I will defer to @asheemmamoowala. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexshalamov The changes to keep all non-complex shaped characters upright look good to me.
Just one request - could you add a test that verifies that Arabic remains in it's natural orientation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexshalamov Before this is finally committed - it would be good to get another set of benchmark results. The benchmarks work with the existing styles so they won't be testing all the new code paths, but it will at least show the impact on existing code.
We have render test for that: Do you think there is a need to add new test?
Sure, I will run tests on Monday and post benchmark results. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think there is a need to add new test?
Sorry I missed that test. No additional tests should be needed.
Benchmark results look good. Is the 1+ms change in SymbolLayout
expected or an anomaly in this run.
The most recent changes look great. |
This PR completes the introduction of the 'text-writing-mode' style property (#8372) and makes use of this property to place point labels vertically if needed.
This is the counterpoint to mapbox/mapbox-gl-native#14932 and is heavily based on those changes.
Notes on the placement algorithm:
See commit messages for more details about changes.
Launch Checklist
cc @alexshalamov @asheemmamoowala @chloekraw @mapbox/gl-native @mapbox/map-design-team @mapbox/studio