maplibre-gl-js icon indicating copy to clipboard operation
maplibre-gl-js copied to clipboard

Character alignment issue when CJK glyphs are mixed with other characters.

Open peaceshi opened this issue 3 years ago • 3 comments

maplibre-gl-js version: 2.1.7

browser: Microsoft Edge 99.0.1150.30(latest stable)

I use localIdeographFontFamily to load the font.

{
            type: "FeatureCollection",
            features: [
              {
                type: "Feature",
                properties: {
                  description: "璃月港A8璃月港\nGgLlIi\n寄了JjPpQqYy寄了"
                },
                geometry: {
                  type: "Point",
                  coordinates: [0, 0]
                }
              }
            ]
          }

image

Seems like mapbox fixed it in a way. But I can find it. https://www.mapbox.com/blog/efficient-pitched-tile-loading-precise-cjk-labels-and-js-promises-mapbox-gl-js-v2-1-1 image

Some useful link: https://github.com/mapbox/mapbox-gl-js/pull/10390 https://github.com/mapbox/mapbox-gl-js/issues/8041 https://github.com/mapbox/mapbox-gl-js/issues/8041#issuecomment-473858431

peaceshi avatar Mar 05 '22 11:03 peaceshi

We can't copy code from mapbox... I'm not sure how to properly solve this, a PR would help a lot in this case.

HarelM avatar Mar 05 '22 12:03 HarelM

https://github.com/mapbox/mapbox-gl-js/pull/10298 I will try PR later.

peaceshi avatar Mar 05 '22 15:03 peaceshi

@peaceshi any updates on this?

HarelM avatar Aug 21 '22 13:08 HarelM

Ping on this. I have built an offline web app that you can run from an USB stick, and if would be awesome if I could use local fonts instead of including all font ranges. Maybe it would be as simple as returning true from _doesCharSupportLocalGlyph if a localFont property is set.

spatialillusions avatar May 11 '23 10:05 spatialillusions

I'm not sure I understand how local fonts are related to this issue... Can you please explain?

HarelM avatar May 11 '23 11:05 HarelM

Sorry, I might have been unclear.

maplibre today got the property localIdeographFontFamily, for locally overriding generation of glyphs to reduce the number of requests for font ranges. This uses a local font to generate the glyphs instead. But like @peaceshi posted, it looks like it creates misalignment between glyphs from local generation and server based glyph ranges.

In the screenshot posted it shows that the other map library introduced another property called localFontFamily, that if used overrides all font settings from the style, and forces generation of all glyphs using the local font, and this solves the misalignment.

As far as I can see in the code, there is a check here https://github.com/maplibre/maplibre-gl-js/blob/a5bdccd5de28479a439bf6d84ca1ed6a4738131d/src/render/glyph_manager.ts#L179 to see if the glyph requested is in CJK ranges, and if not, it simply returns. If I could force that to return true for other glyphs, it would render them using the local font that we have set with localIdeographFontFamily as well. To get it to work in the same way as localFontFamily does, that also uses font weight and other font properties would require some additional work, but would make it possible to render styles without access to any other font ranges at all.

Please let me know if I can give you any additional information.

spatialillusions avatar May 11 '23 14:05 spatialillusions

There is a work being done as part of #2458 which will allow this I believe, it might solve this problem as well, IDK... CC @wipfli

HarelM avatar May 11 '23 14:05 HarelM

@spatialillusions if I understand you correctly, you would like to use the CJK code path for text in all languages and writing systems. #2458 is a proof-of-concept for this. It works OK for latin but I would love to have a bit sharper text first, maybe by doubling the TinySDF resolution as @bdon has experimented with in the past.

wipfli avatar May 12 '23 07:05 wipfli

@bdon you say the easiest would be to double the resolution of everything, right?

wipfli avatar May 12 '23 07:05 wipfli

@spatialillusions if I understand you correctly, you would like to use the CJK code path for text in all languages and writing systems. #2458 is a proof-of-concept for this. It works OK for latin but I would love to have a bit sharper text first, maybe by doubling the TinySDF resolution as @bdon has experimented with in the past.

#2458 goes beyond using TinySDF for all text. This library could remove the CJK-only constraint without worrying about the text segmentation issue. The only regression would be a combining dotted circle under combining diacritics that are already laid out incorrectly anyways.

Doubling TinySDF resolution would be good for parity with Mapbox GL JS, which made that change in v2.1.0 along with adding the localFontFamily option (mapbox/mapbox-gl-js#10298, PR only, no issue available). Apparently some performance optimizations were necessary to offset the cost of the larger sprites.

1ec5 avatar May 19 '23 15:05 1ec5

@bdon you say the easiest would be to double the resolution of everything, right?

@wipfli I think the easiest would be to double the resolution of all glyph textures - it means server-rendered glyphs (read from a 0-255.pbf etc) would be upsampled - this would quadruple the texture memory required for text atlases, but I don't have a good sense if that is a dealbreaker or not.

Otherwise, we could make the texture size conditional on whether the SDF was generated via tinySDF (PoC here: https://github.com/bdon/maplibre-gl-js/tree/bigger-tinysdf) but that complicates the logic elsewhere.

bdon avatar May 21 '23 23:05 bdon

I think if the map runs OK on an older phone, then it should be fine doubling the glyph resolution globally. We can define what old phone means, but for example a galaxy S6 might be a good choice.

wipfli avatar May 22 '23 14:05 wipfli