Skip to content
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

Labels with unsupported characters use fallback typeface partially #11849

Open
melanieimfeld opened this issue May 4, 2022 · 1 comment
Open

Comments

@melanieimfeld
Copy link

mapbox-gl-js version: 2.8.2

browser: Chrome

Steps to Trigger Behavior

  1. In Studio, open a core style, for example streets
  2. Navigate to the place label component, and set language to local
  3. Change the primary typeface in the place component to something that is visibly different from the fallback font Arial Unicode MS Regular and has a low script coverage, e.g. Sniglet Extrabold
  4. Navigate to these locations and observe the characters:

#7.35/14.749/109.668

#5.65/41.435/53.121

Link to Demonstration

Street style

Expected Behavior

I would expect the entire string to fallback to the fallback typeface Arial Unicode MS Regular that’s defined in the style, like it does in some cases, such as the Arabic script:

Actual Behavior

It appears that in some cases (Latin script related characters?), only unsupported characters fallback whereas the supported characters stay in the primary font. This makes labels look really odd, in particular if the primary and fallback typeface differ visually, which is the case with some branded customer fonts.

@1ec5
Copy link
Contributor

1ec5 commented May 24, 2022

This is a consequence of the overall architecture for server-side font rendering: the client sends the Fonts API a fontstack and gets back PBF of a whole range of codepoints (such as 0–255) with individual characters already substituted. The client doesn’t know which codepoints experienced character substitution. Compounding matters, Vietnamese is spread out among multiple discontiguous codepoint ranges and overlaps with many other alphabets that enjoy better font support.

One possibility would be for the client to request multiple PBFs for each codepoint range, one per font in the fontstack, then perform character substitution on the client side. But this would significantly increase overhead for rendering most languages, and it would still require a change in the Fonts API to allow the last resort font (Arial Unicode MS) to be omitted. It would also further entrench our incorrect assumption of a one-to-one mapping between Unicode codepoints and font glyphs.

In my opinion, it would be better to migrate to client-side-rendered text wherever better font substitution is desired. In the general case, this would require full complex text support: #4009. That’s a very difficult problem because real text shaping libraries are so complex. However, it might be possible to extend the existing TinySDF-based solution for CJK to non-complex writing systems without as much difficulty, as demonstrated in mapbox/mapbox-gl-native#7862 (comment). There are even text layout approaches that probably don’t handle complex text that well but still follow a path along a line, as in the PixiJS-based renderer for RapiD: facebook/Rapid#440. (It even supports emoji along a line.)

/cc @kkaefer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants