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

Preview of MapLibre text rendering overhaul #1149

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft

Conversation

1ec5
Copy link
Member

@1ec5 1ec5 commented Aug 21, 2024

In 1ec5/maplibre-gl-js#1, I’ve been prototyping an overhaul of text rendering in MapLibre GL JS to support the rest of the Unicode character repertoire including rarer CJKV characters, correctly shape Indic and other complex text, respect variant selectors, place combining diacritics over base characters, improve bidirectional text support, render (silhouettes of) emoji, wrap lines by word in Thai and Khmer, and more.

This branch replaces the MapLibre GL JS dependency with that branch so that interested members of the public can conveniently test-drive the improved text rendering and layout functionality in the context of OSM Americana. There are some caveats to be aware of:

  • I haven’t optimized performance at all, so there may be a perceptible increase in memory usage or loading time.
  • I haven’t attempted to match the stylesheet’s fontstack names to locally installed fonts or provide more attractive fonts locally.
  • I haven’t addressed ligatures beyond Indic text, so various Arabic alphabets besides Arabic probably still have misshapen glyphs.

Please leave any feedback about the improved text processing in 1ec5/maplibre-gl-js#1. Thanks!

Before After
那市镇 (Na Hang)
那🌫️市镇
那𧯄市镇 (Na Hang)
那𧯄市镇
Naypyitaw Naypyitaw
आउटर सर्किल आउटर सर्किल
ශ්රී ලංකාව
ශ්රී ලංකාව
ශ්‍රී ලංකාව
ශ්‍රී ලංකාව
ކޮންގޯ (ދިމިޤްރާޠީ ޖުމްހޫރިއްޔާ), ހިންދު ކަނޑު ކޮންގޯ (ދިމިޤްރާޠީ ޖުމްހޫރިއްޔާ), ހިންދު ކަނޑު
มหาสมุทรอ  ินเด ีย
มหาสมุทรอ ินเด ีย
มหาสมุทรอินเดีย
มหาสมุทรอินเดีย
ภาคตะนาวศรี
ภาคตะนาวศรี

ภาค/ตะนาว/ศรี
ภาค
ตะนาว
ศรี
sməqʷəʔelə həw̓aləm̓ew̓txʷ
sməqʷəʔelə həw’aləm’ew’txʷ
sməqʷəʔelə həw̓aləm̓ew̓txʷ
sməqʷəʔelə həw̓aləm̓ew̓txʷ
We Puro
We 🌫️ Puro
We ❤️ Puro
We ❤️ Puro
hotel 79
hotel 79 🌫️
hotel 79 👍🏿
hotel 79 👍🏿
Garten von Czernowitz / Чернівці
Garten von Czernowitz / Чернівці 🌫️
Garten von Czernowitz / Чернівці 🇺🇦
Garten von Czernowitz / Чернівці 🇺🇦
One Foot Island
One Foot Island 🌫️🌫️🌫️
One Foot Island ⭐️⭐️⭐️
One Foot Island ⭐️⭐️⭐️

This is an improvement over the status quo for Mapnik-based renderers as well. Many computers come with fallback fonts with larger repertoires than what these renderers specify, and browsers use dictionaries to break lines more intelligently in languages that don’t use spaces.

OSM Carto Americana before and after
臺北市/立聯合/醫院和/平婦幼/院區婦/幼院址
臺北市
立聯合
醫院和
平婦幼
院區婦
幼院址
臺北市立聯/合醫院和平/婦幼院區/婦幼院址
臺北市立聯
合醫院和平
婦幼院區
婦幼院址


臺北市立/聯合醫院/和平婦幼院/區婦幼院址
臺北市立
聯合醫院
和平婦幼院
區婦幼院址
�������� ����
�������� ����
🌫️🌫️🌫️🌫️ 🌫️🌫️🌫️🌫️🌫️🌫️🌫️🌫️
🌫️🌫️🌫️🌫️ 🌫️🌫️🌫️🌫️🌫️🌫️🌫️🌫️

𐴀𐴝𐴐𐴞𐴥𐴑𐴧𐴝 𐴉𐴝𐴌𐴝
𐴀𐴝𐴐𐴞𐴥𐴑𐴧𐴝 𐴉𐴝𐴌𐴝
������������������� �������� «�𝐵�-�𝐸𝑅𝑀»
������������������� �������� «�𝐵�-�𝐸𝑅𝑀»
«-»
«-»

𝘋𝘌𝘙𝘔𝘈𝘛𝘖𝘒𝘖𝘚𝘔𝘌𝘛𝘖𝘓𝘖𝘎𝘠𝘈 𝘖𝘙𝘛𝘈𝘓𝘠𝘎𝘠 «𝒪𝐵𝒰-𝒟𝐸𝑅𝑀»
𝘋𝘌𝘙𝘔𝘈𝘛𝘖𝘒𝘖𝘚𝘔𝘌𝘛𝘖𝘓𝘖𝘎𝘠𝘈 𝘖𝘙𝘛𝘈𝘓𝘠𝘎𝘠 «𝒪𝐵𝒰-𝒟𝐸𝑅𝑀»
(������������)
(������������)
( )
( )

(𝘎𝘳𝘶𝘣𝘦𝘯𝘸𝘦𝘪𝘩𝘦𝘳)
(𝘎𝘳𝘶𝘣𝘦𝘯𝘸𝘦𝘪𝘩𝘦𝘳)

If you see misshapen Burmese text, it may be due to an encoding issue in OSM data rather than a text rendering glitch on the client side. For example, this swimming pool shows up as “​ေရပန္​းဥယ်ဥ္” because the name in OSM is Zawgyi-encoded. Transforming it to the Unicode equivalent, “ရေပန်းဥယျဉ်”, would cause it to render just fine.

Zawgyi Unicode
​ေရပန္​းဥယ်ဥ္
​ေရပန္​းဥယ်ဥ္
ရေပန်းဥယျဉ်
ရေပန်းဥယျဉ်

Fixes #827.

@1ec5 1ec5 self-assigned this Aug 21, 2024
Comment on lines 45 to 59
npm install --include=dev
git clone https://github.com/1ec5/maplibre-gl-js.git --branch=complex-text-50 --depth=1
cd maplibre-gl-js/
npm install --include=dev
npm run build-dist
cd ../
npm link ./maplibre-gl-js/
cd shieldlib/
npm link ../maplibre-gl-js
cd ../
npm run build
Copy link
Member Author

Choose a reason for hiding this comment

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

If you want to run the application locally, you’ll need to run something like this on the command line.

Copy link
Member Author

Choose a reason for hiding this comment

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

If you’re wondering why I don’t just do npm install --save 1ec5/maplibre-gl-js#complex-text-50 and check in the changes to package.js, it seems like it would require more invasive changes to this codebase:

> [email protected] build:code
> tsx scripts/build

✘ [ERROR] Could not resolve "maplibre-gl/dist/maplibre-gl.css"

    src/bare_americana.js:3:7:
      3 │ import "maplibre-gl/dist/maplibre-gl.css";
        ╵        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "maplibre-gl/dist/maplibre-gl.css" as external to exclude it from the
  bundle, which will remove this error.

✘ [ERROR] Could not resolve "maplibre-gl"

    src/shieldtest.js:4:28:
      4 │ import * as maplibregl from "maplibre-gl";
        ╵                             ~~~~~~~~~~~~~

  You can mark the path "maplibre-gl" as external to exclude it from the bundle, which will remove
  this error.

✘ [ERROR] Could not resolve "maplibre-gl"

    src/americana.js:9:28:
      9 │ import * as maplibregl from "maplibre-gl";
        ╵                             ~~~~~~~~~~~~~

  You can mark the path "maplibre-gl" as external to exclude it from the bundle, which will remove
  this error.

✘ [ERROR] Could not resolve "maplibre-gl/dist/maplibre-gl.css"

    src/americana.js:10:7:
      10 │ import "maplibre-gl/dist/maplibre-gl.css";
         ╵        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "maplibre-gl/dist/maplibre-gl.css" as external to exclude it from the
  bundle, which will remove this error.

✘ [ERROR] Could not resolve "maplibre-gl"

    src/js/map_builder.ts:19:64:
      19 │ import maplibregl, { Map, MapOptions, StyleSpecification } from "maplibre-gl";
         ╵                                                                 ~~~~~~~~~~~~~

  You can mark the path "maplibre-gl" as external to exclude it from the bundle, which will remove
  this error.

✘ [ERROR] Could not resolve "maplibre-gl"

    src/search.js:3:28:
      3 │ import * as maplibregl from "maplibre-gl";
        ╵                             ~~~~~~~~~~~~~

  You can mark the path "maplibre-gl" as external to exclude it from the bundle, which will remove
  this error.

✘ [ERROR] Could not resolve "maplibre-gl"

    src/js/legend_control.js:8:28:
      8 │ import * as maplibregl from "maplibre-gl";
        ╵                             ~~~~~~~~~~~~~

  You can mark the path "maplibre-gl" as external to exclude it from the bundle, which will remove
  this error.


  shieldlib/dist/index.js       32.0kb
  shieldlib/dist/index.js.map  150.9kb

⚡ Done in 12ms
7 errors
ERROR: "build:code" exited with 1.

Comment on lines -474 to -481
"(\u200B",
"(\u2068",
{ "font-scale": 0.8 },
// GL JS lacks support for bidirectional isolating characters, so use a
// character from the localized name to insulate the parentheses from the
// embedded text's writing direction. Make it so small that GL JS doesn't
// bother rendering it.
["concat", ["slice", ["var", "localizedName"], 0, 1], " "],
{ "font-scale": 0.001 },
Copy link
Member Author

Choose a reason for hiding this comment

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

We can remove the hacky workaround from #592 (comment), now that the new text segmentation code correctly interprets bidirectional isolating characters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internationalization maplibre Needs maplibre feature or expertise
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unicode ligatures and combining characters not displaying properly
1 participant