Mapbox-gl-native: Full "complex text" support: indic scripts, ligatures, kerning, etc.

Created on 18 Jan 2017  路  21Comments  路  Source: mapbox/mapbox-gl-native

GL Native now uses the ICU library to support right-to-left (and bidirectional) text, along with text shaping for languages that use the Arabic script.

  • [x] Bidirectional/right-to-left text support 馃檶
  • [x] Arabic script text shaping 馃檶

There are a number of further features that fall under the category of "complex text" that remain to be addressed:

  • [ ] Shaping for Brahmic/Indic scripts
  • [ ] Shaping with basic OpenType support for ligatures and kerning in Latin fonts
  • [ ] Shaping with support for more advanced typographic features (possibly using Graphite or Apple Advanced Typography)
  • [ ] Language aware line-breaking algorithms. This is an improvement for languages like Chinese or Japanese, where current line breaking is sub-optimal in that it will easily break inside of compound words. Language aware line-breaking is much more important for languages like Thai or Lao where finding acceptable breaking points requires the use of a dictionary.

Harfbuzz for basic shaping

The first two items can be implemented using Harfbuzz. However, a number of changes to our font rendering architecture will be necessary:

  • https://github.com/mapbox/node-fontnik will need a new interface that serves glyphs based on a font-specific glyph ID instead of a generic Unicode codepoint (because complex shaping breaks the 1:1 relationship between codepoint and glyph we're currently relying on).
  • We will need to send font "shaping tables" down to the client for use by Harfbuzz
  • After performing shaping, the client will have to request appropriate glyphs from the server. If the glyphs are unavailable, the client will have to implement the fontstack fallback behavior.

Harfbuzz support is tracked as https://github.com/mapbox/mapbox-gl-native/issues/7528

Advanced typography

Supporting some advanced typography features will require passing through to system libraries (such as Apple's Core Text) or linking in libraries like Graphite. Using advanced typography features would open up some interesting (and possibly unique) options for creating beautiful maps, for instance by using calligraphic typefaces such as a Nastaliq script or Zapfino. Harfbuzz has support for passing shaping calls through to Core Text, so enabling some of these features on iOS might not be too difficult, but any support we added would likely remain highly platform-dependent.

Many advanced typographical features require explicit typographical instructions in addition to the basic Unicode input. Supporting these features would require changes to the style spec and Mapbox Studio to enable designers to take advantage of them. They are beyond the scope of the changes we are currently planning.

Line breaking

Line-breaking can be implemented using ICU, but a standard implementation would require client-side line breaking dictionaries which are likely to be prohibitively large. The proposed implementation is tracked as https://github.com/mapbox/mapbox-gl-native/issues/7362.

Mapbox Classic parity

Mapbox Classic supports basic shaping using Harfbuzz via Mapnik, but I don't believe it has support for language-aware line breaking or advanced typographical features.

Resources

https://github.com/mapbox/mapbox-gl-js/issues/4009 is a paired ticket that tracks making these changes in GL-JS.

@1ec5 @lucaswoj @pveugen

Core Google Maps parity MapKit parity text rendering

Most helpful comment

HarfBuzz do support advanced typography through its support for OpenType. Apple Advanced Typography (AAT) is an alternative technology to OpenType that is only supported by Apple, and thus not widely used outside of Apple own fonts. HarfBuzz actually can support AAT on Apple platforms by using Core Text API, so using HarfBuzz should give you OpenType support on all platforms and additionally AAT support on Apple ones.

All 21 comments

Thank you for this great en-devour. Bravo. ..This is long waited news... Could you please mention, when would it be ready for public to use? when is the publish date? Can you post some screenshots of final rendering in Arabic lang? I am more interested in Persian Language which is similar to Arabic. RTL and almost similar alphabets.

@Kashian happy to oblige with a screenshot from Iran:

before-after-mashhad

Planned availability of Arabic/Bidirectional support:

  • As a plugin for gl-js in v0.32.1 (released Jan 26 2017)
  • In iOS SDK 3.5.0 (no firm date, but should be early 2017)
  • In Android SDK 5.0.0 (no firm date, but should be early 2017)

The changes are not yet available in the Mapbox GL Qt Submodule (https://github.com/mapbox/mapbox-gl-native/issues/7777).

If you鈥檙e interested in trying out this functionality ahead of time on a mobile or desktop platform, check out our instructions for building the SDKs yourself:

https://github.com/mapbox/mapbox-gl-native/tree/master/platform/android#contributing-to-the-sdk
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/ios/INSTALL.md
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/macos/INSTALL.md

For trying out the functionality in gl-js, see https://github.com/mapbox/mapbox-gl-js/pull/3758#issuecomment-273591724

Note that either Harfbuzz and Core Text would get us support for Unicode supplementary planes (mapbox/mapbox-gl-js#4001) almost for free. (Support for full-color emoji would likely require significant work beyond the scope of this ticket.)

HarfBuzz do support advanced typography through its support for OpenType. Apple Advanced Typography (AAT) is an alternative technology to OpenType that is only supported by Apple, and thus not widely used outside of Apple own fonts. HarfBuzz actually can support AAT on Apple platforms by using Core Text API, so using HarfBuzz should give you OpenType support on all platforms and additionally AAT support on Apple ones.

@khaledhosny You know way more than I do about HarfBuzz and text shaping, so please forgive my imprecise description of "advanced typography". I haven't yet worked on the problem enough to know how to describe it properly! I'm using "advanced typography" as kind of a placeholder term for "nice to have" functionality like support for AAT. Some things HarfBuzz supports out of the box still might not get picked up in our initial implementation since we're going to try to work with a subset of font tables (I'm thinking of the MATH table as an example: something relatively straightforward to support with HarfBuzz but still something that we might not support in a first pass).

I just wanted to make sure things are clear :)

The biggest OpenType tables (after glyf and CFF) are usually GPOS an GSUB, I don鈥檛 think there will be that much gain dropping most of the other tables. AAT tables are very unlikely to be seen in the wild (unless one is dealing with Apple system fonts), so I鈥檇 not bother with them. Graphite are unlikely to be seen either, but when a font have them they are usually required, so I鈥檇 keep them unless Graphite support in HarfBuzz is not enabled. MATH is actually one of the tables that are good to go, math support in HarfBuzz is low level building blocks that are only usable by dedicated math layout engine, HarfBuzz itself does not do any math layout. Just my 2 Egyptian piastres.

@ChrisLoer and I paired on the coretext-hack branch to perform complex text shaping using system fonts on iOS and macOS:

before after

before after

_Compare the before and after with the system-rendered text in the popover._

HarfBuzz should do that as well, you don't need separate CoreText backend.

Yes, we鈥檙e also exploring HarfBuzz + FreeType versus TinySDF + Core Text: https://github.com/mapbox/mapbox-gl-native/issues/7862#issuecomment-346879662 #7528.

As @behdad mentioned in https://github.com/mapbox/mapbox-gl-native/issues/7774#issuecomment-362929990, we are also using harfbuzz coretext context here.

@1ec5 I tried to implement this on my app. I cloned coretext hack branch. Now I have a tile server running. Now how to tell to use system font? I have style.json file. what should be the font name written in style.json?

@nafis042 Although I'm excited you're playing around with it, unfortunately we can't really support the "coretext hack" branch -- it was a proof-of-concept, but there are many things on that branch that are simply broken. It would not be appropriate for any production app. For what it's worth, the demo is meant to work with the macosapp build target (from xcode with make xproj), and shouldn't require special configuration beyond that.

any timeline for indic language support?

any timeline for indic language support?

Unfortunately, no. It's still on our backlog, but no specific plans.

If you have a cool project that's blocked by the lack of Indic language support, it'd be great to hear a quick description. Although it's clearly functionality we want to support, we don't have a library of concrete examples of what kinds of maps/apps this would unlock.

Any updates on this? I still see the issue happening:
image

@hakimelek Is that screenshot taken from Mapbox GL JS? If so you need to enable the RTL text plugin, example is here: https://www.mapbox.com/mapbox-gl-js/example/mapbox-gl-rtl-text/

@ChrisLoer Thanks! I will give a shot. I am using react-mapbox-gl but it seems like it's easy to support RTL in there with the plugin.

Waiting for two long years to get solution for

Shaping for Brahmic/Indic scripts

Probably @ChrisLoer forgot about 1 Billion user of Indic Language.

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@1ec5 Hopefully some good news is coming from mapbox regarding complex indic language visualization

Hi Guys,
While I was able to use the plugin for RTL, I still unable to see hebrew for street/city names.
like this one for example:
https://www.madlan.co.il/local/转诇%20讗讘讬讘%20讬驻讜/FOR_SALE?source=source_search

appriciate your tips
DY

Was this page helpful?
0 / 5 - 0 ratings