Open alanchenboy opened 1 month ago
Thanks for taking the time to open this design proposal.
Can you clarify the relation between this property and glyphs
? It is not clear when one should be selected over the other.
Also, will using this require some configuration in the rendering part? special build? a plugin?
We don't have other style properties that has external requirements in order to work as far as I know...
We would use Harfbuzz for text shaping in MapLibre Native by default, so no special plugins would be required.
Wouldn't this require a special build? Or is the default build comes with Harfbuzz and you can reduce build size if you need, but this would be the special build - i.e without it?
The latter: we would enable it by default, although it would be possible to drop out if you have binary size constraints and you make your own builds. The default build is the 'kitchen sink' build. Most users don't care that much about binary size.
Thank you for the proposal @alanchenboy. Can we add to the proposal a way to load glyph SDFs from a server?
When rasterizing glyphs on the client with TinySDF, i.e., make gray-scale image then convert to SDF with Felzenszwalb/Huttenlocher distance transform, the visual quality is lower than when using font maker or similar which operates directly on Bezier curves to get the SDFs...
This approach means that if a font is defined here by font-face, then the selected Unicode point will be shaped with Harfbuzz and then rasterized with FreeType. In addition to rendering complex fonts, this also has the implicit benefit of saving traffic by the font files actually smaller than the pre-rendered pbf files.
Exactly! Additionally, if we have an API to define server-generated SDF glyphs we can benefit from:
The API could maybe look something like this:
"font-faces": [
{
"text-font": ["Noto Sans Regular"],
"font-files": [
{
"url": "https://alanchenboy.github.io/harfbuzzResource/fonts/Noto%20Sans%20Regular/khmer.ttf",
"unicode-range": [
"U+1780-17FF"
],
"glyphs": "https://alanchenboy.github.io/harfbuzzResource/glyphs//Noto%20Sans%20Regular/khmer/{range}.pbf"
},
{
"url":"https://alanchenboy.github.io/harfbuzzResource/fonts/Noto%20Sans%20Regular/myanmar.ttf",
"unicode-range": [
"U+1000-109F", "U+A9E0-0xA9FF", "U+AA60-0xAA7F"
],
"glyphs": "https://alanchenboy.github.io/harfbuzzResource/glyphs//Noto%20Sans%20Regular/myanmar/{range}.pbf"
},
{
"url":"https://alanchenboy.github.io/harfbuzzResource/fonts/Noto%20Sans%20Regular/devanagari.ttf",
"unicode-range": [
"U+0900-097F", "U+A8E0-0xA8FF"
],
"glyphs": "https://alanchenboy.github.io/harfbuzzResource/glyphs//Noto%20Sans%20Regular/devanagari/{range}.pbf"
}
]
}
],
Some fonts have several hundred glyphs so it might make sense to split the glyphs up into ranges of 256 like we do with normal MapLibre fonts. The difference to normal fonts would be that the index is actually the glyph index from the font .ttf file and not simply the unicode codepoint.
Bezier-based SDF generation which is more precision and looks better than TinySDF-based SDF generation
FYI, maplibre/maplibre-gl-js#4564 would lean more heavily on TinySDF, and I have a half-baked idea in https://github.com/maplibre/maplibre-gl-js/pull/4564#discussion_r1730061958 to use it exclusively if the top-level glyphs
property is missing (which is currently an error). The idea would be to rely on Web Fonts (or the native equivalent) for any custom fonts, without requiring any MapLibre-specific server-side changes.
Design Proposal: Flexible font define in style
Motivation
MapLibre inherits the font pbf design from Mapbox, this is a limit to rendering complex text. We must let the core reach the font file to finish shaping and rendering complex text like Indic, Khmer, Burmese, etc.
Proposed Change
The design looks like CSS unicode-range with font-face,
full style: https://alanchenboy.github.io/harfbuzzResource/hindi.json
API Modifications
A new feature for complex font rendering, it's transparent for the map users.
Here is an example of how to render complex text on the native side.
https://github.com/maplibre/maplibre-native/pull/1439.
Migration Plan and Compatibility
N/A
Rejected Alternatives
N/A