Re: [w3ctag/design-reviews] Canvas Text Metrics for Editing, Art and Design (Issue #1095)

fmalita left a comment (w3ctag/design-reviews#1095)

Thanks for reviewing @jyasskin!

> * The example code passes `end`=`text.length`, which is the number of code _units_, but the [algorithm](https://whatpr.org/html/11000/canvas.html#dom-textcluster-start) throws an exception if it exceeds the number of code _points_. Since the emoji each take 2 code units to represent a code point, this should throw. However, [`Intl.Segmenter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/segment/Segments/containing) operates in terms of code units, and it's important to be consistent with that here, so you should probably update your algorithm to use code units too.

Good catch, that looks like an unintended discrepancy.  Agreed that consistency with `Intl.Segmenter` is desirable, plus working with code points would introduce some extra client friction.

We should update the spec PR to use code units.

Interestingly, the Chromium prototype impl is already [using code units](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/canvas/text_metrics.cc;drc=6b12aa08faf21efc74ac0d0a036eed90f8a3fc50;l=523), thus the example doesn't throw.  You can see it running live [here](https://codepen.io/fmalita/pen/LEVJBKo) if you launch Chromium with `--enable-experimental-web-platform-features`.

(The example does require a minor tweak to match the current spec PR: `TextCluster.begin` has been renamed to `TextCluster.start`.)


> * We see that the "fi" ligature is getting a single color. We suspect that counts as "their corresponding glyphs cannot be broken down any further" in your spec.

Indeed, the focus is on glyph clusters (as produced by the text shaping engine/text preparation algorithm) that cannot be subdivided any further without breaking the user-perceived "character".  They roughly correspond to grapheme clusters, but they also include ligatures because those are single glyphs that cannot be subdivided (I've heard some of our font folks refer to them as "glyphemes").

One thing we should probably emphasize in these docs is that `TextCluster`s are constructed in the glyph (post-shaping) domain, and are indirectly related to the Unicode domain.


>   1. The explainer refers to these TextClusters as "grapheme clusters" in a couple places, but ["Grapheme clusters are not the same as ligatures."](https://unicode.org/reports/tr29/#:~:text=Grapheme%20clusters%20are%20not%20the%20same%20as%20ligatures.)

Point taken, some of the explainers are using loose (or possibly outdated) terminology - we should update them.  Note that the spec PR avoids any mention of graphemes and sticks to the accurate description.


>   2. One of your use cases for this API is for caret positioning, but the caret has to be able to be positioned between the "f" and "i" in that ligature.

Since ligatures are single glyphs, there is no way to get the partial font metrics required for accurate mid-ligature positioning.  AFAIK most editors don't support mid-ligature positioning, and the ones that do rely on approximations/heuristics.

At a high level, this seems to fall onto clients: if caret positioning is important, they should use fonts without ligatures, or disable ligatures during text shaping.  (Whether that latter part is achievable with Canvas is a good question... AFAICT, unlike CSS,  there is no way to explicitly disable ligatures with Canvas APIs.  I found [this](https://github.com/fserb/canvas2D/blob/master/spec/text-modifiers.md) old proposal that could be extended for `font-variant-ligatures`, but that's a separate effort.  @schenney-chromium)

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/1095#issuecomment-2985628808
You are receiving this because you are subscribed to this thread.

Message ID: <w3ctag/design-reviews/issues/1095/2985628808@github.com>

Received on Wednesday, 18 June 2025 20:42:05 UTC