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

CJK punctuation collapsing as part of shaping? #4651

Open
drott opened this issue Apr 3, 2024 · 4 comments
Open

CJK punctuation collapsing as part of shaping? #4651

drott opened this issue Apr 3, 2024 · 4 comments

Comments

@drott
Copy link
Collaborator

drott commented Apr 3, 2024

https://drafts.csswg.org/css-text-4/#fullwidth-collapsing discusses punctuation collapsing and reducing spacing dependent on context and punctuation sequences.

This is shipped in Chrome from M123, improves CJK typography related to punctuation sequences, is controlled by the text-spacing-trim property, and currently done as an implementation on the layout engine side.

This blog post illustrates the feature: https://developer.chrome.com/blog/css-i18n-features#cjk_punctuation_kerning_text-spacing-trim

As a discussion starter, without having sufficiently looked into this myself to form an opinion: Are there parts of this functionality that could be done and would be architecturally in the right place in the shaping library? This might help with adoption in other browsers as well. Or is this more of an application level feature?

CC @kojiishi

@behdad
Copy link
Member

behdad commented Apr 3, 2024

CC @jfkthame

@jfkthame
Copy link
Collaborator

In my mind, all the text-spacing-trim stuff belongs as an application-level feature, with too much higher-level context involved to be a good fit for the shaping library.

@kojiishi
Copy link
Contributor

I remember I briefly chatted with @behdad for the possibility of emulating the chws feature when it's missing in the font, but we didn't discuss deeper. In short, I think doing this in the shaping engine allows more detailed control of the feature, but it has some challenges, technically, and may need to change where the border between apps and the shaping layer is, as @jfkthame pointed out.

The feature consists of three different types of the glyph metrics adjustments.

  1. Between a pair of glyphs.
  2. At the start of a line.
  3. At the end of a line.

Technically speaking, 1 is covered by the chws feature if it exists, so it should be doable in the shaping layer. 2 and 3 needs apps to give the context to the shaping engine. Adding two flags may be easy, but it also means that apps might want to know the need of reshaping before shaping, similar to unsafe-to-break. I'm not sure how easy/hard this part is.

Other technical challenges as far as I understand are:

  • The positioning engine needs to know the original Unicode code point, which the current HarfBuzz doesn't carry along with the glyph ID as far as I understand?
  • For when it's at the font boundaries, apps need to give pre-/post-context. I'm not sure if this is doable in the current HarfBuzz API?
  • After it determined that the trimming should be applied to a glyph, there are two ways to trim it; a) apply halt, b) trim by adjusting position/advance. Blink currently implements only a), but the spec allows both. To do b), HarfBuzz needs to know the ink bounding box. Computing ink bounding box is one of the most expensive operations. Blink tries hard to minimize it (that's why the Blink's initial implementation doesn't support it). If we were doing b), this needs careful design to minimize it across apps and HarfBuzz.
  • There will be some font/glyph properties that should be cached for the performance.

Do these changes fit well for the shaping layer?

@behdad
Copy link
Member

behdad commented May 21, 2024

Other technical challenges as far as I understand are:

  • The positioning engine needs to know the original Unicode code point, which the current HarfBuzz doesn't carry along with the glyph ID as far as I understand?

HarfBuzz does provide "cluster" mappings to the original text.

  • For when it's at the font boundaries, apps need to give pre-/post-context. I'm not sure if this is doable in the current HarfBuzz API?

hb_buffer can carry pre-/post-context text.

  • After it determined that the trimming should be applied to a glyph, there are two ways to trim it; a) apply halt, b) trim by adjusting position/advance. Blink currently implements only a), but the spec allows both. To do b), HarfBuzz needs to know the ink bounding box. Computing ink bounding box is one of the most expensive operations. Blink tries hard to minimize it (that's why the Blink's initial implementation doesn't support it). If we were doing b), this needs careful design to minimize it across apps and HarfBuzz.
  • There will be some font/glyph properties that should be cached for the performance.

Do these changes fit well for the shaping layer?

I suggest pursuing solutions using OpenType features only.

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

4 participants