You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The paint stage of CSS is responsible for painting the background, content and highlight of an element based on that element's geometry (as generated by the layout stage) and computed style.
41
+
The paint stage of CSS is responsible for painting the background, content and highlight of an
42
+
box based on that box's geometry (as generated by the layout stage) and computed style.
42
43
43
-
This specification describes an API which allows developers to paint a part of an element in response to geometry / computed style changes.
44
+
This specification describes an API which allows developers to paint a part of an box in
45
+
response to geometry / computed style changes with an additional <<image>> function.
44
46
45
-
Note: In a future version of the spec, support may be added for defining the clip, global alpha, filter on a portion of an element (for example on the background layers).
47
+
Note: In a future version of the spec, support may be added for defining the clip, global alpha,
48
+
filter on a portion of an box (for example on the background layers).
46
49
47
50
Paint Invalidation {#paint-invalidation}
48
51
========================================
49
52
50
-
A <a>document</a> has an associated <b>paint name to input properties map</b>. Initially it is empty and is populated when {{registerPaint(name, paintCtor)}} is called.
53
+
A <a>document</a> has an associated <dfn>paint name to input properties map</dfn>. Initially it is
54
+
empty and is populated when {{registerPaint(name, paintCtor)}} is called.
51
55
52
-
Each <<paint()>> function for a fragment has an associated <b>paint valid flag</b>. It may be either <dfn>paint-valid</dfn> or <dfn>paint-invalid</dfn>. It is initially set to <a>paint-invalid</a>.
56
+
Each <<paint()>> function for a box has an associated <dfn>paint valid flag</dfn>. It may be either
57
+
<dfn>paint-valid</dfn> or <dfn>paint-invalid</dfn>. It is initially set to <a>paint-invalid</a>.
53
58
54
-
When the geometry (as determined by layout) of a <var>fragment</var> changes, each <<paint()>> function's <b>paint valid flag</b> should be set to <a>paint-invalid</a>.
59
+
When the geometry (as determined by layout) of a |box| changes, each <<paint()>> function's <a>paint
60
+
valid flag</a> should be set to <a>paint-invalid</a>.
55
61
56
-
When the computed style for an element changes, the user agent must run the following steps:
57
-
1. For each <<paint()>> function on the element, perform the following substeps:
58
-
1. Let <var>name</var> be the first argument of the <<paint()>> function.
59
-
2. Let <var>inputProperties</var> be the result of performing a lookup in <b>paint name to input properties map</b> with |name| as the key.
60
-
3. For each <var>property</var> in |inputProperties|, if the |property|'s <a>computed value</a> has changed, set the <b>paint valid flag</b> on the |fragment| to <a>paint-invalid</a>.
62
+
When the computed style for an |box| changes, the user agent must run the following steps:
63
+
1. For each <<paint()>> function on the |box|, perform the following substeps:
64
+
1. Let |paintFunction| be the current <<paint()>> function on the |box|.
61
65
62
-
[[#drawing-an-image]] results in the <b>paint valid flag</b> for a <<paint()>> function to be set to <a>paint-valid</a>.
66
+
2. Let |name| be the first argument of the <<paint()>> function.
63
67
64
-
Note: In a future version of the spec, support may be added for partial invalidation.
65
-
The user agent will be able to specify a region of the rendering context which needs to be re-painted by the paint class.
68
+
3. Let |inputProperties| be the result of lookuping up |name| on <a>paint name to input
69
+
properties map</a>.
70
+
71
+
4. For each |property| in |inputProperties|, if the |property|'s <a>computed value</a> has
72
+
changed, set the <a>paint valid flag</a> on the |paintFunction| to <a>paint-invalid</a>.
73
+
74
+
Performing <a>draw a paint image</a> results in the <a>paint valid flag</a> for a <<paint()>>
75
+
function on a box to be set to <a>paint-valid</a>.
76
+
77
+
Note: In a future version of the spec, support may be added for partial invalidation. The user agent
78
+
will be able to specify a region of the rendering context which needs to be re-painted by the
79
+
paint class.
66
80
67
81
Paint Worklet {#paint-worklet}
68
82
==============================
69
83
70
84
The {{paintWorklet}} attribute allows access to the {{Worklet}} responsible for all the classes
71
85
which are related to painting.
72
86
73
-
The {{paintWorklet}}'s <b>worklet global scope type</b> is {{PaintWorkletGlobalScope}}.
87
+
The {{paintWorklet}}'s <a>worklet global scope type</a> is {{PaintWorkletGlobalScope}}.
The {{PaintWorkletGlobalScope}} has a map of <b>name to paint instance map</b>. Initially this map is empty; it is populated when {{registerPaint(name, paintCtor)}} is called.
95
-
96
105
<div class='note'>
97
106
Note: This is how the class should look.
98
107
<pre class='idl'>
@@ -103,25 +112,53 @@ The {{PaintWorkletGlobalScope}} has a map of <b>name to paint instance map</b>.
103
112
</pre>
104
113
</div>
105
114
106
-
When the <dfn method for=PaintWorkletGlobalScope>registerPaint(<var>name</var>, <var>paintCtor</var>)</dfn> method is called, the user agent <em>must</em> run the following steps:
107
-
1. If the |name| is not a valid <<ident>>, <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
108
-
2. If the |name| exists as a key in the <b>name to paint instance map</b>, <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
109
-
3. If the result of <a>IsConstructor</a>(argument=|paintCtor|) is false, <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
110
-
4. Let <var>prototype</var> be the result of <a>Get</a>(O=|paintCtor|, P="prototype").
111
-
5. If the result of <a>IsCallable</a>(argument=<a>Get</a>(O=|prototype|, P="paint")) is false, <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
112
-
6. Let <var>inputProperties</var> be the result of <a>Get</a>(O=|paintCtor|, P="inputProperties").
113
-
7. If the result of <a>IsArray</a>(argument=|inputProperties|) is false, <a>throw</a> a <a>NotSupportedError</a> and abort all these steps.
114
-
8. Add the key-value pair (|name| - |inputProperties|) to the <b>paint name to input properties map</b> of the associated <a>document</a>.
115
-
9. Let <var>paintInstance</var> be the result of <a>Construct</a>(|paintCtor|).
116
-
10. Add the key-value pair (|name| - |paintInstance|) to the <b>name to paint instance map</b> of the {{PaintWorkletGlobalScope}}.
And the <code>element</code> is inside the visual viewport, the user agent <em>msut</em><a>draw
248
+
a paint image</a> and display the result on the current frame.
249
+
</div>
250
+
251
+
The {{Geometry}} object represents the geometry of the image that the author should draw.
252
+
193
253
<pre class='idl'>
194
254
[Exposed=Worklet]
195
255
interface Geometry {
@@ -198,69 +258,84 @@ interface Geometry {
198
258
};
199
259
</pre>
200
260
201
-
If a <<paint()>> function for a fragment is <a>paint-invalid</a> and the fragment is within the visual viewport,
202
-
then user agent <em>must</em><a>draw an image</a> for the current frame.
261
+
When the user agent wants to <dfn>draw a paint image</dfn> of a <<paint()>> function for a |box|
262
+
into its appropriate stacking level (as defined by the property the CSS property it's associated
263
+
with), given it's |concreteObjectSize| (<a>concrete object size</a>) it <em>must</em> run the
264
+
following steps:
265
+
1. Let |paintFunction| be the current <<paint()>> function on the |box|.
203
266
204
-
Note: The user agent may choose to <a>draw an image</a> for <<paint()>> functions not within the visual viewport.
267
+
2. If the <a>paint valid flag</a> for the |paintFunction| is <a>paint-valid</a> the user agent
268
+
<em>may</em> use the drawn image from the previous invocation. If so it <em>may</em> abort
269
+
all these steps and use the previously drawn image.
205
270
206
-
When the user agent wants to <dfn>draw an image</dfn> of a <<paint()>> for a <var>fragment</var> into its appropriate stacking level (as defined by the property the CSS property it's associated with) it <em>must</em> run the following steps:
207
-
1. If the <b>paint valid flag</b> for the <<paint()>> function on the |fragment| is <a>paint-valid</a> the user agent <em>may</em> use the drawn image from the previous invocation.
208
-
If so it can abort all these steps.
271
+
Note: The user agent for implementation reasons may also continue with all these steps in
272
+
this case. It can do this every frame, or multiple times per frame.
209
273
210
-
Note: The user agent for implementation reasons may also continue with all these steps in this case. It can do this every frame, or multiple times per frame.
274
+
3. Let |name| be the first argument of the |paintFunction|.
211
275
212
-
2. Let <var>name</var> be the first argument of the <<paint()>> function.
276
+
4. Let |workletGlobalScope| be a {{PaintWorkletGlobalScope}} from the list of <a>worklet's
277
+
WorkletGlobalScopes</a> from the paint {{Worklet}}.
213
278
214
-
3. If no paint class was registered with |name|, the resulting image output will be an <a>invalid image</a> and the user agent must abort all these steps.
279
+
The user agent <em>may</em> also <a>create a WorkletGlobalScope</a> given the paint
280
+
{{Worklet}} and use that.
215
281
216
-
4. Let <var>inputProperties</var> be the result of looking up |name| on the associated <a>document</a>'s <b>paint name to input properties map</b>.
282
+
Note: The user agent <em>may</em> use any policy for which {{PaintWorkletGlobalScope}} to
283
+
select or create. It may use a single {{PaintWorkletGlobalScope}} or multiple and
284
+
randomly assign between them.
217
285
218
-
5. Let <var>styleMap</var> be a new {{StylePropertyMap}} populated with <em>only</em> the <a>computed value</a>'s for properties listed in |inputProperties|.
286
+
5. If no paint constructor exists on |workletGlobalScope|'s <a>paint name to constructor map</a>
287
+
with key |name|, the resulting image output will be an <a>invalid image</a> and the user
288
+
agent must abort all these steps.
219
289
220
-
6. Let <var>renderingContext</var> be the result of <a>create a PaintRenderingContext2D object</a> given:
221
-
- "width" - The width of the |fragment|.
222
-
- "height" - The height of the |fragment|.
290
+
6. Let |paintInstance| be the result of looking up |name| on |workletGlobalScope|'s <a>paint
291
+
name to instance map</a>. If |paintInstance| is null run the following substeps:
292
+
1. Let |paintCtor| be the result of looking up |name| on <a>paint name to constructor
293
+
map</a>.
223
294
224
-
Note: The |renderingContext| must not be re-used between invocations of paint. Implicitly this means that there is no stored data, or state on the |renderingContext| between invocations.
225
-
For example you can't setup a clip on the context, and expect the same clip to be applied next time the paint method is called.
295
+
2. Let |paintInstance| be the result of <a>Construct</a>(|paintCtor|).
226
296
227
-
7. Let <var>geometry</var> be a new {{Geometry}} initialized to the width and height of the |fragment|.
297
+
3. Add the key-value pair (|name| - |paintInstance|) to the <a>paint name to instance
298
+
map</a> of the |workletGlobalScope|.
228
299
229
-
8. Let |workletGlobalScope| be a {{PaintWorkletGlobalScope}} from the list of <b>worklet's
230
-
WorkletGlobalScopes</b> from the paint {{Worklet}}.
300
+
7. Let |inputProperties| be the result of looking up |name| on the associated <a>document</a>'s
301
+
<a>paint name to input properties map</a>.
231
302
232
-
The user agent <em>may</em>also<a>create a WorkletGlobalScope</a> given the paint
233
-
{{Worklet}} and use that.
303
+
8. Let |styleMap| be a new {{StylePropertyMap}} populated with <em>only</em>the<a>computed
304
+
value</a>'s for properties listed in |inputProperties|.
234
305
235
-
Note: The user agent <em>may</em> use any policy for which {{PaintWorkletGlobalScope}} to
236
-
select or create.
237
-
238
-
9. Let |classInstance| be the result of performing a lookup in <b>name to paint instance map</b>
239
-
with |name| as the key.
306
+
9. Let |renderingContext| be the result of <a>create a PaintRenderingContext2D object</a> given:
307
+
- "width" - The width given by |concreteObjectSize|.
308
+
- "height" - The height given by |concreteObjectSize|.
Note: The user agent should consider long running paint functions similar to long running script in the main execution context.
251
-
For example, they should show a "unresponsive script" dialog or similar.
252
-
In addition user agents should provide tooling within their debugging tools to show authors how expensive their paint classes are.
326
+
12. The image output is to be produced from the |renderingContext| given to the method.
253
327
254
-
Note: The contents of the image are not designed to be accessible. Authors should communicate any useful information through the standard accessibility APIs.
328
+
If an exception is <a>thrown</a> the resulting image output will be an <a>invalid image</a>.
255
329
256
-
Issue(w3c/css-houdini-drafts#24): Determine how to side-load images or other data.
330
+
13. Set the <a>paint valid flag</a> for the |paintFunction| to <a>paint-valid</a>.
257
331
258
-
Issue: What information should we provide for read-modify-write use-cases?
259
-
Are read-modify-write use-cases important for v1?
260
-
For example, if you are sliding the previous paint output out?
261
-
For providing the previous paint output we should provide an ImageBitmap if you ask.
332
+
Note: The user agent <em>should</em> consider long running paint functions similar to long running
333
+
script in the main execution context. For example, they <em>should</em> show a "unresponsive
334
+
script" dialog or similar. In addition user agents <em>should</em> provide tooling within their
335
+
debugging tools to show authors how expensive their paint classes are.
262
336
263
-
Issue: Describe what happens if a callback doesn't hit a frame timing boundary. I.e. just renders a transparent image instead?
337
+
Note: The contents of the resulting image are not designed to be accessible. Authors <em>should</em>
338
+
communicate any useful information through the standard accessibility APIs.
0 commit comments