-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Add a lang
IDL Attribute to CanvasTextDrawingStyles, and clarify "direction" on same
#10873
base: main
Are you sure you want to change the base?
Conversation
Also clean up what "inherit" means for direction.
@AndresRPerez12, @annevk, @fserb, @Kaiido Note that currently Chromium does not resolve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for tackling this!
I personally think it's great this hidden inheritance is finally made explicit, and having a way to set it on the context directly is a big plus.
source
Outdated
incorrect (including using property-independent style sheet syntax like 'inherit' or 'initial'), | ||
then it must be ignored, without assigning a new font value. <ref>CSS</ref></p> | ||
must be assigned to the context, with the primary language set to the <span | ||
data-x="dom-context-2d-lang-used-value">used-value</span> for <code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work to define the used value here? What if I don't ever set the font
attribute, but set the lang
one. Will my default sans-serif font be able to get this used value?
Would it work better if it was called in text preparation algo instead?
+Nit: might be better as "used value" (without the "-") for easing search in page
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will take a look at what happens in Chromium for a non-defined font, but regardless I will update this to make it clear what happens when there is no defined font. And yes to moving it to the text preparation algorithm (and the direction resolution) because it does indeed need to be dynamic. I was wondering about the right way to ensure that dynamic changes were handled, and you've answered my question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this some more, this section going through getters and setters defines how the font is determined, while the text preparation algorithm
says
Let font be the current font of target, as given by that object's font attribute.
The current font
is never really defined. With that in mind, given that the lang
is an input into the font selection process (at least in Chromium), I think the description of how to determine the lang
belongs here, just after the font source determination method.
I will add text to clarify that the language applies even for the default font (which it does in Chromium), and also that any inherited value is snapshot when an offscreen canvas is created and for canvas elements is snapshot when the font or lang attributes are set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the new version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be aware that https://whatpr.org/html/10873/canvas.html doesn't reflect the last commit's changes. Don't know why.
source
Outdated
and with system fonts being computed to explicit values. If the new value is syntactically | ||
incorrect (including using property-independent style sheet syntax like 'inherit' or 'initial'), | ||
then it must be ignored, without assigning a new font value. <ref>CSS</ref></p> | ||
must be assigned to the context, with the primary language set to the <span |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "primary language" here the same as CSS's content language?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was intending it to mean the "primary language" as used in https://html.spec.whatwg.org/multipage/dom.html#the-lang-and-xml:lang-attributes. The solution is to convert that linked reference to a definition and then refer to the definition in the canvas change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This concept has been cleaned up.
source
Outdated
attribute for="CanvasTextDrawingStyles"><code data-x="dom-context-2d-lang">lang</code></dfn> | ||
IDL attribute. On setting, <code data-x="dom-context-2d-lang">lang</code> must be | ||
a <span data-x="attr-lang">valid BCP 47 language tag</span> or the string "inherit". | ||
To determine the <dfn data-x="dom-context-2d-lang-used-value">used value</dfn> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It's a bit confusing to have this algo so close to the setter step. (Actually inside of it since there is no rendered return). It makes it look like it's called at that time only and thus doesn't make "inherit"
dynamic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I'll move it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decided against a move because of the way the font setting is described, and because this is input to the font, not the text preparation steps.
Thanks for the very quick first round of review. I'll make the changes and update the PR. |
source
Outdated
@@ -66410,15 +66426,56 @@ worker.postMessage(offscreenCanvas, [offscreenCanvas]);</code></pre> | |||
Notice that the font is only loaded inside the worker, and not in the document context.</p> | |||
</div> | |||
|
|||
<p>The choice of fonts and glyphs within a font may vary according to the <dfn | |||
attribute for="CanvasTextDrawingStyles"><code data-x="dom-context-2d-lang">lang</code></dfn> | |||
IDL attribute. On setting, <code data-x="dom-context-2d-lang">lang</code> must be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be mentioned explicitly that if the string used for setting is invalid, then the stored value in the context doesn't change? For most other CanvasTextDrawingStyles
it isn't needed as they are defined using IDL enums, but for the attributes that need parsing, like letterSpacing
, the setter steps are outlined and therefore it's clear that an invalid value results in the attribute not being changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the HTML lang attribute it is explicitly said that "unknown" values should be passed through unchanged. I believe that's because it's hard to write validation for locale strings. Anyways, I think here we also need to just accept whatever is given.
I plan to get this updated in the coming week. One issue is a lack of testing coverage for offscreen canvas objects transferred from HTML canvas, needed to the the "inherit" attribute value. I filed web-platform-tests/wpt#49987 to get that added to wpt, and I think I'll try to do the work for it. |
source
Outdated
<ol> | ||
<li><p>If <var>object</var>'s <span>font style source object</span> is a <code>canvas</code> | ||
element, then return the element's <span data-x="attr-lang">lang atribute | ||
value</span>.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should return https://html.spec.whatwg.org/#language. The lang
attribute can be specified in the ancestor chain.
source
Outdated
|
||
<li><p>If <var>global</var> is a <code>Window</code> object, then return the | ||
<span data-x="attr-lang">lang attribute</span> from <var>global</var>'s | ||
<span data-x="concept-document-window">associated <code>Document</code></span>.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates race conditions. We could snapshot the language when we create the worker, but I suspect it's not worth the complexity. On the fence as to whether it's worth doing when we create an OffscreenCanvas
from a <canvas>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's easy enough to snapshot the language when the OffscreenCanvas is created, at least in Chromium. I think we should snapshot for all OffscreenCanvas objects to keep things easy to understand. And we should only update the value for a canvas element when the lang attribute is set, plus at creation.
It's moderately expensive to look up the language because it requires walking up the DOM tree evaluated a bunch of conditionals. So snapshotting is also a performance win.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the new version for snapshotting language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates race conditions. We could snapshot the language when we create the worker, but I suspect it's not worth the complexity. On the fence as to whether it's worth doing when we create an
OffscreenCanvas
from a<canvas>
.
Why would that create race conditions? Could you please give an example.
I've finally updated the PR. Please take another look. The WHATNOT meeting 2 weeks from now is my target to discuss this, and hopefully approve the algorithms, if not the exact language. |
The whole snapshot thing seems super complex and probably surprising for web-authors. Given that Note: The current default behavior doesn't seem interoperable, where Chrome actually uses the updated |
I agree it's somewhat confusing, but every time I tried to come up with something more intuitive I failed. In particular, for things that affect the font, Chromium currently re-resolves the font each time one of those things changes. Hence Chrome is currently updating for the lang value (though I would have to look at how invalidation works in that case in the current code). Codifying that is hard because there's no definitive time when the font gets resolved. Maybe "changes in the inherited lang must be applied before the font is next used to render text or metrics" which is essentially the direction behavior.
There is no easy way for authors to get the "computed value" for the language of an element. That's Issue #7039 that Anne linked to. In practice , WebKit and Chromium both have the CSS Removing And then if you allow a special initial value, then how do you reset to that initial value? Drop
I just changed Chrome to use inherit-at-creation for |
source
Outdated
<p>The choice of fonts and glyphs within a font may vary according to the <dfn | ||
attribute for="CanvasTextDrawingStyles"><code data-x="dom-context-2d-lang">lang</code></dfn> | ||
IDL attribute. On setting, <code data-x="dom-context-2d-lang">lang</code> must be | ||
a <span data-x="attr-lang">valid BCP 47 language tag</span> or the string "inherit". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't actually define what the setter does.
I recommend looking at letterSpacing
and wordSpacing
. We want the same kind of language for lang
and direction
with the distinction between public API and internal state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, I think.
New version up. Thanks, as always, for the reviews. |
<p>Objects that implement the <code>CanvasTextDrawingStyles</code> interface have a <dfn attribute | ||
for="CanvasTextDrawingStyles"><code data-x="dom-context-2d-lang">lang</code></dfn> attribute | ||
that controls localization of the font. The <code data-x="dom-context-2d-lang">lang</code> IDL | ||
attribute, on getting, must return the current value. The <code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple issues here:
- "The lang getter steps are to return ..."
- It needs to return the value of some internal concept, similar to what
letterSpacing
does. - It should probably be its own paragraph. We no longer really define getters and setters and concepts all in one paragraph.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I did "2" as you meant.
data-x="dom-context-2d-lang">lang</code> setter steps are:</p> | ||
|
||
<ol> | ||
<li><p>Change the current value to the new value.</p></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to manipulate an internal concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean here. Has the last set of edits addressed this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. If you look at the letterSpacing
getter it is defined as follows:
The letterSpacing getter steps are to return the serialized form of this's letter spacing.
"letter spacing" there is the internal concept. That is what's missing here. The internal concept can have the same name as the getter, but it is distinct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we're talking about the setter here. I feel I'm being slow, but is this sort of what you mean (sans links):
The lang setter steps are to set the value and update the internal font language
I think we agree that the value in lang
is the string that round-trips, while the internal font language really is internal and not visible to authors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's about both the getter and the setter. If the internal font language is the concept you could rewrite the getter as:
The language getter steps are to return this's internal font language.
(Note that you need to use "this" as well. We need to know where to find this internal concept after all.)
Next round of edits are done. This process will help me a lot when doing my next PR. |
<li><p>Change the current value to the new value.</p></li> | ||
<li><p>If the value is "<code data-x="dom-context-2d-direction-inherit">inherit</code>", then</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably perform the same checks as in https://whatpr.org/html/10873/dom.html#the-lang-and-xml:lang-attributes so that it's limited to BCP 47 allowed values and the special inherit value (, and maybe ""
?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it says it must be valid, but then it says:
If the resulting value is not a recognized language tag, then it must be treated as an unknown language having the given language tag, distinct from all other languages. For the purposes of round-tripping or communicating with other services that expect language tags, user agents should pass unknown language tags through unmodified, and tagged as being BCP 47 language tags, so that subsequent services do not interpret the data as another type of language description. [[BCP47]](https://whatpr.org/html/10873/references.html#refsBCP47)
So maybe say it must be valid but the UA must still pass invalid values through unmodified?
It starts to look a lot better to me (modulo the internal value used by the getter and setter, I guess). I still think that
I'm not sure how relevant it is for the canvas context |
For offscreen canvasses the best thing still seems to be snapshot at creation, as I have it in the latest draft and as I just landed, with tests, for For canvas elements, the dynamic behavior seems right and I deliberately did not define it in the latest draft, just as it is not defined for Or we can switch to "initial". What do others think? |
After sleeping on it, I think I prefer the existing "inherit" dynamic update behavior because it seems authors would expect it to reflect dynamic changes in a canvas element, with some value to having |
There is no way to localize the fonts used in HTML Canvas text rendering and metrics when using an
OffscreenCanvas
, and there is no information in the spec about how to determine the primary language even for regular 2D canvas (though implementations seem to agree to use the canvas element'slang
attribute and use the default locale from the HTTP header for Offscreen). This proposal adds alang
IDL attribute toCanvasTextDrawingStyles
, which is mixed into bothCanvasRenderingContext2D
andOffscreenCanvasRenderingContext2D
.The changes in this PR define how the language for font resolution should be chosen for canvas contexts and applies the same treatment to the
inherit
value for thedirection
IDL attribute which is currently not well defined.See the discussion in issue #10862.
/acknowledgements.html ( diff )
/canvas.html ( diff )