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

Clarification needed in step 5 of the text preparation algorithm #8103

Open
jfkthame opened this issue Jul 13, 2022 · 3 comments
Open

Clarification needed in step 5 of the text preparation algorithm #8103

jfkthame opened this issue Jul 13, 2022 · 3 comments

Comments

@jfkthame
Copy link

The text preparation algorithm described in §4.12.5.1.4 of https://html.spec.whatwg.org/multipage/canvas.html#text-styles says:

  1. Form a hypothetical infinitely-wide CSS line box containing a single inline box containing the text text, with its CSS properties set as follows:​
    Property Source
    'direction' direction
    'font' font
    'font-kerning' target's fontKerning
    'font-stretch' target's fontStretch
    'font-variant-caps' target's fontVariantCaps
    'letter-spacing' target's letter spacing
    SVG text-rendering target's textRendering
    'white-space' 'pre'
    'word-spacing' target's word spacing

and with all other properties set to their initial values.

However, this fails to make it clear how the target's fontStretch and fontVariantCaps attributes relate to its font, which (being parsed as a CSS font value) includes font-stretch-css3 and font-variant-css2 components.

Given ctx.font = "condensed 50px Bahnschrift" and ctx.fontStretch = "normal", what is the expected result?

Given ctx.font = "small-caps 50px serif" and ctx.fontVariantCaps = "all-small-caps", what is the expected result?

Given ctx.font = "small-caps 50px serif", does this automatically set ctx.fontVariantCaps to "small-caps"?

Given ctx.font = "50px serif"; ctx.fontVariantCaps = "small-caps", does the value of ctx.font automatically become "small-caps 50px serif"?

Some possible approaches:

(1) font takes precedence: if a stretch and/or caps value is included in the font attribute, it is a fixed part of the font style, and the corresponding separate fontStretch or fontVariantCaps attribute is ignored. So those attributes are only used if the font attribute did not explicitly set a non-normal value.

(2) fontStretch and fontVariantCaps take precedence: these attributes always override whatever may have been set in the font attribute. To avoid breaking existing content that uses e.g. ctx.font = "small-caps 20px serif" and does not mention fontVariantCaps at all, we'll need to define an initial value other than "normal" for these attributes -- something like "unset" or even just an empty string -- so that the font attribute can specify a value and not simply have it overridden by the other attribute's initial value.

(3) Behavior is order-dependent: when the stretch and/or caps value differs between the font attribute and the individual attributes, whichever was set most recently wins. This has two sub-options:

(3a) The context must store the order of setting these attributes, in addition to the current set of values, and save/restore the order along with the values when saving state; or

(3b) Whenever one of these attributes is set, it also automatically updates the other(s) to reflect the new setting, so that the values are consistent with each other. However, the font attribute does not support all the values of fontVariantCaps, so it is unclear to me how this would be managed; there would be some weird asymmetry in the relationship.

Personally, I think either (1) or (2) (or another option not yet proposed...) should be specified The order of setting attributes on the context (3) should not affect the resulting behavior, and neither (3a) nor (3b) are attractive implementation options.

As far as I am aware, currently only the Blink engine implements the fontStretch and fontVariantCaps attributes, and its implementation seems incomplete and confusing (see https://crbug.com/1343549). I think, therefore, that we should not regard this as a model to be adopted, but try to come to a clear resolution that all engines can implement consistently.

@Kaiido
Copy link
Member

Kaiido commented Jul 14, 2022

As a web-dev I think I'd kind of prefer that the behavior of the 2D context matches the CSS one as much as possible.

Would it be an option to add the missing longhands (ctx.fontFamily, ctx.fontSize, ctx.fontStyle, and ctx.fontWeight) and let ctx.font act the same as the CSS shorthand?
So when we update ctx.font all the affected longhands get updated, and when the longhands are updated, ctx.font getter tries to render it or returns "" when it can't, like I believe getComputedStyle(elem).font is supposed to do (though the lack of interop' here is quite problematic, I admit).
If all the longhands are available, I believe ctx.font's getter is less critical and it's ok for it to fail.


Ps: cc @whatwg/canvas and particularly @yiyix

@jfkthame
Copy link
Author

though the lack of interop' here is quite problematic, I admit

Just FYI, the Firefox bug pointed out in your jsfiddle example (exposing an illegal "shorthand" that includes all-small-caps) has recently been fixed (for Firefox 103) in https://bugzilla.mozilla.org/show_bug.cgi?id=1771215.

moz-wptsync-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 4, 2023
…eftests.

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1778910
gecko-commit: d59f1e7c17c5e7a5f12a69fa4ce384bd2a31264f
gecko-reviewers: gfx-reviewers, lsalzman
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jul 4, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567
moz-wptsync-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 6, 2023
…eftests.

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1778910
gecko-commit: def0a0be81f9f1d6b63720a27b69b34ebe15b4e2
gecko-reviewers: gfx-reviewers, lsalzman
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jul 7, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567
moz-wptsync-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 7, 2023
…eftests.

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1778910
gecko-commit: def0a0be81f9f1d6b63720a27b69b34ebe15b4e2
gecko-reviewers: gfx-reviewers, lsalzman
ErichDonGubler pushed a commit to erichdongubler-mozilla/firefox that referenced this issue Jul 7, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567
ErichDonGubler pushed a commit to erichdongubler-mozilla/firefox that referenced this issue Jul 7, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Jul 16, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

UltraBlame original commit: def0a0be81f9f1d6b63720a27b69b34ebe15b4e2
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Jul 16, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

UltraBlame original commit: def0a0be81f9f1d6b63720a27b69b34ebe15b4e2
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Jul 16, 2023
… and add WPT reftests. r=gfx-reviewers,lsalzman

The behavior in some of these cases is open to debate, as the spec is quite unclear;
see whatwg/html#8103. What I've implemented here gives the
same rendering result as Chrome for these tests, so hopefully we can get this clarified
in the spec as well.

Differential Revision: https://phabricator.services.mozilla.com/D182567

UltraBlame original commit: def0a0be81f9f1d6b63720a27b69b34ebe15b4e2
@mysteryDate
Copy link
Contributor

As a web-dev I think I'd kind of prefer that the behavior of the 2D context matches the CSS one as much as possible.

+1 (as a former web dev)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants