# CSS Painting API Level 1

## Editor’s Draft, 1 January 1970

This version:
  https://drafts.css-houdini.org/css-paint-api-1/
Latest published version:
  http://www.w3.org/TR/css-paint-api-1/
Previous Versions:
  https://www.w3.org/TR/2018/WD-css-paint-api-1-20180410/
  https://www.w3.org/TR/2016/WD-css-paint-api-1-20160607/
Feedback:
  public-houdini@w3.org with subject line “`[css-paint-api] … message topic …`” (archives)
Editors:
  Ian Kilpatrick
  Dean Jackson
Former Editor:
  Shane Stephens
Issue Tracking:
  GitHub Issues

Copyright © 1970 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.

## Abstract

An API for allowing web developers to define a custom CSS <image> with javascript, which will respond to style and size changes. See EXPLAINER.

## Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

GitHub Issues are preferred for discussion of this specification. When filing an issue, please put the text “css-paint-api” in the title, preferably like this: “[css-paint-api] …summary of comment…”. All issues and comments are archived.

This document was produced by the CSS Working Group.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

## 1. Introduction

The paint stage of CSS is responsible for painting the background, content and highlight of a box based on that box’s size (as generated by the layout stage) and computed style.

This specification describes an API which allows developers to paint a part of a box in response to size / computed style changes with an additional <image> function.

Note: In a future version of the spec, support could be added for defining the clip, global alpha, filter on a portion of a box (for example on the background layers).

## 2. Paint Worklet

The `paintWorklet` attribute allows access to the `Worklet` responsible for all the classes which are related to painting.

The `paintWorklet`'s worklet global scope type is `PaintWorkletGlobalScope`.

    partial namespace CSS {
        [SameObject] readonly attribute Worklet paintWorklet;
    };

A `PaintWorkletGlobalScope` is a global execution context of the `paintWorklet`.

A `PaintWorkletGlobalScope` has a `devicePixelRatio` property which is identical to the Window.`devicePixelRatio` property.

    [Global=(Worklet,PaintWorklet),Exposed=PaintWorklet]
    interface PaintWorkletGlobalScope : WorkletGlobalScope {
        void registerPaint(DOMString name, VoidFunction paintCtor);
        readonly attribute unrestricted double devicePixelRatio;
    };

The `PaintRenderingContext2DSettings` contains the settings for the rendering context associated with the paint canvas. The `PaintRenderingContext2DSettings` provides a supported subset of canvas rendering context 2D settings. In the future, it may be extended to support color management in paint canvas.

    dictionary PaintRenderingContext2DSettings {
        boolean alpha = true;
    };

Note: The shape of the class should be:

    class MyPaint {
        static get inputProperties() { return ['--foo']; }
        static get inputArguments() { return ['<color>']; }
        static get contextOptions() { return {alpha: true}; }

        paint(ctx, size, styleMap) {
            // Paint code goes here.
        }
    }

## 3. Concepts

A paint definition is a struct which describes the information needed by the `PaintWorkletGlobalScope` about the author defined <image> (which can be referenced by the <paint()> function). It consists of:

- class constructor which is the class constructor.

- paint function which is the paint Function callback function type.

- constructor valid flag.

- input properties which is a list of `DOMStrings`.

- A PaintRenderingContext2DSettings object.

A document paint definition is a struct which describes the information needed by the document about the author defined <image> function (which can be referenced by the paint function). It consists of:

- A input properties which is a list of `DOMStrings`.

- A input argument syntaxes which is a list of syntax definitions.

- A PaintRenderingContext2DSettings object.

## 4. Registering Custom Paint

The document has a map of document paint definitions. Initially this map is empty; it is populated when `registerPaint(name, paintCtor)` is called.

A `PaintWorkletGlobalScope` has a map of paint definitions. Initially this map is empty; it is populated when `registerPaint(name, paintCtor)` is called.

A `PaintWorkletGlobalScope` has a map of paint class instances. Initially this map is empty; it is populated when draw a paint image is invoked by the user agent.

Instances of paint classes in the paint class instances map may be disposed and removed from the map by the user agent at any time. This may be done when a <paint()> function no longer is used, or the user agent needs to reclaim memory.

When the `registerPaint(name, paintCtor)` method is called, the user agent must run the following steps:

1. If the name is an empty string, throw a TypeError and abort all these steps.

2. Let paintDefinitionMap be `PaintWorkletGlobalScope`'s paint definitions map.

3. If paintDefinitionMap[name] exists throw a "`InvalidModificationError`" `DOMException` and abort all these steps.

4. Let inputProperties be an empty `sequence<DOMString>`.

5. Let inputPropertiesIterable be the result of Get(paintCtor, "inputProperties").

6. If inputPropertiesIterable is not undefined, then set inputProperties to the result of converting inputPropertiesIterable to a `sequence<DOMString>`. If an exception is thrown, rethrow the exception and abort all these steps.

7. Filter inputProperties so that it only contains supported CSS properties and custom properties.

Note: The list of CSS properties provided by the input properties getter can either be custom or native CSS properties.

Note: The list of CSS properties may contain shorthands.

Note: In order for a paint image class to be forwards compatible, the list of CSS properties can also contains currently invalid properties for the user agent. For example `margin-bikeshed-property`.

8. Let inputArguments be an empty `sequence<DOMString>`.

9. Let inputArgumentsIterable be the result of Get(paintCtor, "inputArguments").

10. If inputArgumentsIterable is not undefined, then set inputArguments to the result of converting inputArgumentsIterable to a `sequence<DOMString>`. If an exception is thrown, rethrow the exception and abort all these steps.

11. Let inputArgumentSyntaxes be an empty list.

12. For each item in inputArguments perform the following substeps:

    1. Attempt to consume a syntax definition from item. If failure was returned, throw a TypeError and abort all these steps. Otherwise, let parsedSyntax be the returned syntax definition.

    2. Append parsedSyntax to inputArgumentSyntaxes.

13. Let contextOptionsValue be the result of Get(paintCtor, "contextOptions").

14. Let paintRenderingContext2DSettings be the result of converting contextOptionsValue to a `PaintRenderingContext2DSettings`. If an exception is thrown, rethrow the exception and abort all these steps.

    Note: Setting `paintRenderingContext2DSettings.alpha` is `false` allows user agents to anti-alias text in addition to performing "visibility" optimizations, e.g. not painting an image behind the paint image as the paint image is opaque.

15. If the result of IsConstructor(paintCtor) is false, throw a TypeError and abort all these steps.

16. Let prototype be the result of Get(paintCtor, "prototype").

17. If the result of Type(prototype) is not Object, throw a TypeError and abort all these steps.

18. Let paintValue be the result of Get(prototype, "paint").

19. Let paint be the result of converting paintValue to the Function callback function type. Rethrow any exceptions from the conversion.

20. Let definition be a new paint definition with:

    - class constructor being paintCtor.

    - paint function being paint.

    - constructor valid flag being true.

    - input properties being inputProperties.

    - PaintRenderingContext2DSettings object being paintRenderingContext2DSettings.

21. Set paintDefinitionMap[name] to definition.

22. Queue a task to run the following steps:

    1. Let documentPaintDefinitionMap be the associated document’s document paint definitions map.

    2. Let documentDefinition be a new document paint definition with:

       - input properties being inputProperties.

       - input argument syntaxes being inputArgumentSyntaxes.

       - PaintRenderingContext2DSettings object being paintRenderingContext2DSettings.

    3. If documentPaintDefinitionMap[name] exists, run the following steps:

       1. Let existingDocumentDefinition be the result of get documentPaintDefinitionMap[name].

       2. If existingDocumentDefinition is `"invalid"`, abort all these steps.

       3. If existingDocumentDefinition and documentDefinition are not equivalent, (that is input properties, input argument syntaxes, and PaintRenderingContext2DSettings object are different), then:

          Set documentPaintDefinitionMap[name] to `"invalid"`.

          Log an error to the debugging console stating that the same class was registered with different `inputProperties`, `inputArguments`, or `paintRenderingContext2DSettings`.

    4. Otherwise, set documentPaintDefinitionMap[name] to documentDefinition.

Note: The list of input properties should only be looked up once, the class doesn’t have the opportunity to dynamically change its input properties.

Note: In a future version of the spec, the author could have the ability to receive a different type of RenderingContext. In particular the author may want a WebGL rendering context to render 3D effects. There are complexities in setting up a WebGL rendering context to take the `PaintSize` and `StylePropertyMap` as inputs.

## 5. Paint Notation

    paint() = paint( <ident>, <declaration-value>? )

The <paint()> function is an additional notation to be supported by the <image> type.

    <style>
        .logo { background-image: paint(company-logo); }
        .chat-bubble { background-image: paint(chat-bubble, blue); }
    </style>

For the cursor property, the <paint()> function should be treated as an invalid image and fallback to the next supported <image>.

At computed value time the <paint()> function does not need to match the grammar registered by `registerPaint()`. Instead this will result in an invalid image when the parsing occurs inside draw a paint image.

## 6. The 2D rendering context

    [Exposed=PaintWorklet]
    interface PaintRenderingContext2D {
    };
    PaintRenderingContext2D includes CanvasState;
    PaintRenderingContext2D includes CanvasTransform;
    PaintRenderingContext2D includes CanvasCompositing;
    PaintRenderingContext2D includes CanvasImageSmoothing;
    PaintRenderingContext2D includes CanvasFillStrokeStyles;
    PaintRenderingContext2D includes CanvasShadowStyles;
    PaintRenderingContext2D includes CanvasRect;
    PaintRenderingContext2D includes CanvasDrawPath;
    PaintRenderingContext2D includes CanvasDrawImage;
    PaintRenderingContext2D includes CanvasPathDrawingStyles;
    PaintRenderingContext2D includes CanvasPath;

Note: The `PaintRenderingContext2D` implements a subset of the `CanvasRenderingContext2D` API. Specifically it doesn’t implement the `CanvasImageData`, `CanvasUserInterface`, `CanvasText`, or `CanvasTextDrawingStyles` APIs.

A `PaintRenderingContext2D` object has a output bitmap. This is initialised when the object is created. The size of the output bitmap is the concrete object size of the object it is rendering to.

A `PaintRenderingContext2D` object also has an alpha flag, which can be set to true or false. Initially, when the context is created, its alpha flag must be set to true. When a `PaintRenderingContext2D` object has its alpha flag set to false, then its alpha channel must be fixed to 1.0 (fully opaque) for all pixels, and attempts to change the alpha component of any pixel must be silently ignored.

The size of the output bitmap does not necessarily represent the size of the actual bitmap that the user agent will use internally or during rendering. For example, if the visual viewport is zoomed the user agent may internally use bitmaps which correspond to the number of device pixels in the coordinate space, so that the resulting rendering is of high quality.

Additionally the user agent may record the sequence of drawing operations which have been applied to the output bitmap such that the user agent can subsequently draw onto a device bitmap at the correct resolution. This also allows user agents to re-use the same output of the output bitmap repeatably while the visual viewport is being zoomed for example.

Whenever `"currentColor"` is used as a color in the `PaintRenderingContext2D` API, it is treated as opaque black.

The code below will produce a solid black rectange.

    registerPaint('currentcolor', class {
        paint(ctx, size) {
            ctx.fillStyle = 'currentColor';
            ctx.fillRect(0, 0, size.width, size.height);
        }
    });

When the user agent is to create a PaintRenderingContext2D object for a given width, height, and paintRenderingContext2DSettings, it must run the following steps:

1. Create a new `PaintRenderingContext2D`.

2. Set bitmap dimensions for the context’s output bitmap to the rounded values of width and height.

3. Set the `PaintRenderingContext2D`'s alpha flag to paintRenderingContext2DSettings’s `alpha`.

4. Return the new `PaintRenderingContext2D`.

Note: The initial state of the rendering context is set inside the set bitmap dimensions algorithm, as it invokes reset the rendering context to its default state and clears the output bitmap.

### 6.1. Drawing a CSSImageValue

The `CanvasImageSource` typedef is extended to also include the `CSSImageValue` type to be used as an image source.

For interfaces which use the `CanvasDrawImage` mixin:

- When a `CanvasImageSource` object represents an `CSSImageValue`, the result of invoking the value’s underlying image algorithm must be used as the source image for the purposes of `drawImage`.

Note: This should eventually be moved to the canvas section of the HTML specification. See Issue 819.

## 7. Drawing an image

If a <paint()> function image for a box is within the visual viewport, the user agent must display an image output from an invocation of the draw a paint image algorithm.

Note: The user agent doesn’t have to run draw a paint image each frame for a <paint()> function within the visual viewport. It can cache results, (potentially using additional invalidation steps) to display the correct image output.

Note: The user agent can optionally defer drawing images which are outside the visual viewport.

If an author updates a style inside a `requestAnimationFrame`, e.g.

    requestAnimationFrame(function() {
        element.styleMap.set('--custom-prop-invalidates-paint', 42);
    });

And the `element` is inside the visual viewport, the user agent is required to draw a paint image and display the result for the current frame.

The draw a paint image function is invoked by the user agent during the object size negotiation algorithm which is responsible for rendering an <image>, with snappedConcreteObjectSize defined as follows. Let concreteObjectSize be the concrete object size of the box. The snappedConcreteObjectSize is usually the same as the concreteObjectSize. However, the user agent may adjust the size such that it paints to pixel boundaries. If it does, the user agent should adjust the snappedConcreteObjectSize by the proportional change from its original size such that the <paint()> function can adjust the drawing accordingly.

For the purposes of the object size negotiation algorithm, the paint image has no intrinsic dimensions.

Note: In a future version of the spec, the author could have the ability to specify the intrinsic dimensions of the paint image. This will probably be exposed as a callback allowing the author to define static intrinsic dimensions or dynamically updating the intrinsic dimensions based on computed style and size changes.

The `PaintSize` object represents the size of the image that the author should draw. This is the snappedConcreteObjectSize given by the user agent.

Note: See CSS Images 3 §5.4 Examples of CSS Object Sizing for examples on how the concrete object size is calculated.

The draw a paint image function may be speculatively invoked by the user agent at any point, with any snappedConcreteObjectSize. The resulting image is not displayed.

Note: User agents may use any heuristic to speculate a possible future value for snappedConcreteObjectSize, for example speculating that the size remains unchanged.

Note: Although the image is not displayed, it may still be cached, and subsequent invocations of <paint()> may use the cached image.

    [Exposed=PaintWorklet]
    interface PaintSize {
        readonly attribute double width;
        readonly attribute double height;
    };

When the user agent wants to draw a paint image of a <paint()> function for a box into its appropriate stacking level (as defined by the property the CSS property its associated with), given snappedConcreteObjectSize it must run the following steps:

1. Let paintFunction be the <paint()> function on the box which the user agent wants to draw.

2. Let name be the first argument of the paintFunction.

3. Let documentPaintDefinitionMap be the associated document’s document paint definitions map.

4. If documentPaintDefinitionMap[name] does not exist, let the image output be an invalid image and abort all these steps.

5. Let documentDefinition be the result of get documentPaintDefinitionMap[name].

6. If documentDefinition is `"invalid"`, let the image output be an invalid image and abort all these steps.

7. Let inputArgumentSyntaxes be documentDefinition’s input argument syntaxes.

8. Let inputArguments be the list of all the paintFunction arguments after the "paint name" argument.

9. If inputArguments do not match the registered grammar given by inputArgumentSyntaxes, let the image output be an invalid image and abort all these steps.

   This step may fail in the following cases:

       // paint.js
       registerPaint('failing-argument-syntax', class {
           static get inputArguments() { return ['<length>']; }
           paint(ctx, size, styleMap, args) { /* paint code here. */ }
       });

       <style>
           .example-1 {
               background-image: paint(failing-argument-syntax, red);
           }
           .example-2 {
               background-image: paint(failing-argument-syntax, 1px, 2px);
           }
       </style>
       <div class=example-1></div>
       <div class=example-2></div>
       <script>
           CSS.paintWorklet.addModule('paint.js');
       </script>

   `example-1` produces an invalid image as `"red"` does not match the registered grammar.

   `example-2` produces an invalid image as there are too many function arguments.

10. Let workletGlobalScope be a `PaintWorkletGlobalScope` from the list of worklet’s WorkletGlobalScopes from the paint `Worklet`, following the rules defined in § 7.1 Global Scope Selection.

    The user agent may also create a WorkletGlobalScope at this time, given the paint `Worklet`.

11. Run invoke a paint callback given name, inputArguments, snappedConcreteObjectSize, workletGlobalScope optionally in parallel.

    Note: If the user agent runs invoke a paint callback on a thread in parallel, it should select a paint worklet global scope which can be used on that thread.

When the user agent wants to invoke a paint callback given name, inputArguments, snappedConcreteObjectSize, and workletGlobalScope, it must run the following steps:

1. Let paintDefinitionMap be workletGlobalScope’s paint definitions map.

2. If paintDefinitionMap[name] does not exist, run the following steps:

   1. Queue a task to run the following steps:

      1. Let documentPaintDefinitionMap be the associated document's document paint definitions map.

      2. Set documentPaintDefinitionMap[name] to `"invalid"`.

      3. The user agent should log an error to the debugging console stating that a class wasn’t registered in all `PaintWorkletGlobalScope`s.

   2. Let the image output be an invalid image and abort all these steps.

   Note: This handles the case where there could be a paint worklet global scope which didn’t receive the `registerPaint(name, paintCtor)` for name (however another global scope did). A paint callback which is invoked on the other global scope could succeed, but wont succeed on a subsequent frame when draw a paint image is called.

3. Let definition be the result of get paintDefinitionMap[name].

4. Let paintClassInstanceMap be workletGlobalScope’s paint class instances map.

5. Let paintInstance be the result of get paintClassInstanceMap[|name]|. If paintInstance is null, run the following steps:

   1. If the constructor valid flag on definition is false, let the image output be an invalid image and abort all these steps.

   2. Let paintCtor be the class constructor on definition.

   3. Let paintInstance be the result of Construct(paintCtor).

      If construct throws an exception, set the definition’s constructor valid flag to false, let the image output be an invalid image and abort all these steps.

   4. Set paintClassInstanceMap[name] to paintInstance.

6. Let inputProperties be definition’s input properties.

7. Let styleMap be a new `StylePropertyMapReadOnly` populated with only the computed value's for properties listed in inputProperties.

8. Let renderingContext be the result of create a PaintRenderingContext2D object given:

   - "width" - The width given by snappedConcreteObjectSize.

   - "height" - The height given by snappedConcreteObjectSize.

   - "paintRenderingContext2DSettings" - The PaintRenderingContext2DSettings object given by definition.

   Note: The renderingContext is not be re-used between invocations of paint. Implicitly this means that there is no stored data, or state on the renderingContext between invocations. 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.

   Note: Implicitly this also means that renderingContext is effectively "neutered" after a paint method is complete. The author code may hold a reference to renderingContext and invoke methods on it, but this will have no effect on the current image, or subsequent images.

9. Let paintSize be a new `PaintSize` initialized to the width and height defined by snappedConcreteObjectSize.

10. At this stage the user agent may re-use an image from a previous invocation if paintSize, styleMap, inputArguments are equivalent to that previous invocation. If so let the image output be that cached image and abort all these steps.

    In the example below, both `div-1` and `div-2` have paint functions which have equivalent javascript arguments. A user-agent can cache the result of one invocation and use it for both elements.

        // paint.js
        registerPaint('simple', class {
            paint(ctx, size) {
                ctx.fillStyle = 'green';
                ctx.fillRect(0, 0, size.width, size.height);
            }
        });

        <style>
            .div-1 {
                width: 50px;
                height: 50px;
                background-image: paint(simple);
            }
            .div-2 {
                width: 100px;
                height: 100px;

                background-size: 50% 50%;
                background-image: paint(simple);
            }
        </style>
        <div class=div-1></div>
        <div class=div-2></div>
        <script>
            CSS.paintWorklet.addModule('paint.js');
        </script>

11. Let paintFunctionCallback be definition’s paint function.

12. Invoke paintFunctionCallback with arguments «renderingContext, paintSize, styleMap, inputArguments», and with paintInstance as the callback this value.

    If paintFunctionCallback does not complete within an acceptable time (as determined by the user agent, i.e. it is a "long running script") the user agent may terminate the script, let the image output be an invalid image, and abort all these steps.

    Note: User agents could provide tooling within their debugging tools to show authors how expensive their paint classes are. User agents could also how an "unresponsive script" dialog in this case if appropriate.

13. The image output is to be produced from the renderingContext given to the method.

    If an exception is thrown the let the image output be an invalid image.

Note: The contents of the resulting image are not designed to be accessible. Authors can communicate any useful information through the standard accessibility APIs.

### 7.1. Global Scope Selection

When the user agent needs to select a `PaintWorkletGlobalScope` from the paint worklet’s WorkletGlobalScopes list it must:

- Select from at least two `PaintWorkletGlobalScope`s, unless the user agent is under memory constraints.

- Not re-use the same `PaintWorkletGlobalScope` more than 1000 times in a row.

  Note: The 1000 limit was picked as a high upper bound, this limit may improve (downwards) over time.

Note: These rules exist to ensure that authors do not rely on being able to store state on the global object or non-regeneratable state on the class. See Worklets 1 §1.2 Code Idempotency.

## 8. Examples

### 8.1. Example 1: Colored Circle

The example below makes use of the fact that <paint()> functions are able to be animated. E.g. when the textarea is focused in the example below, the `--circle-color` property will transition from `deepskyblue` to `purple`.

This ability isn’t limited to just transitions, it also applies to CSS animations, and the Web Animations API.

    <!DOCTYPE html>
    <style>
      #example {
        --circle-color: deepskyblue;

        background-image: paint(circle);
        font-family: sans-serif;
        font-size: 36px;
        transition: --circle-color 1s;
      }

      #example:focus {
        --circle-color: purple;
      }
    </style>

    <textarea id="example">
      CSS is awesome.
    </textarea>

    <script>
        CSS.registerProperty({
          name: '--circle-color',
          syntax: '<color>',
          initialValue: 'black',
          inherits: false
        });
        CSS.paintWorklet.addModule('circle.js');
    </script>

    // circle.js
    registerPaint('circle', class {
      static get inputProperties() { return ['--circle-color']; }
      paint(ctx, geom, properties) {
        // Change the fill color.
        const color = properties.get('--circle-color');
        ctx.fillStyle = color.cssText;

        // Determine the center point and radius.
        const x = geom.width / 2;
        const y = geom.height / 2;
        const radius = Math.min(x, y);

        // Draw the circle \o/
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
        ctx.fill();
      }
    });

### 8.2. Example 2: Image Placeholder

It is possible for an author to use paint to draw a placeholder image while an image is being loaded.

    <!DOCTYPE html>
    <style>
    #example {
        --image: url('#someUrlWhichIsLoading');
        background-image: paint(image-with-placeholder);
    }
    </style>

    <div id="example"></div>

    <script>
        CSS.registerProperty({
            name: '--image',
            syntax: '<image> | none',
            initialValue: 'none',
        });
        CSS.paintWorklet.addModule('image-placeholder.js');
    </script>

    // image-placeholder.js
    registerPaint('image-with-placeholder', class {
        static get inputProperties() { return ['--image']; }
        paint(ctx, geom, properties) {
            const img = properties.get('--image');

            switch (img.state) {
                case 'ready':
                    // The image is loaded! Draw the image.
                    ctx.drawImage(img, 0, 0, geom.width, geom.height);
                    break;
                case 'pending':
                    // The image is loading, draw some mountains.
                    drawMountains(ctx);
                    break;
                case 'invalid':
                default:
                    // The image is invalid (e.g. it didn’t load), draw a sad face.
                    drawSadFace(ctx);
                    break;
            }
        }
    });

### 8.3. Example 3: Arcs

    <!DOCTYPE html>
    <style>
    #example {
      width: 200px;
      height: 200px;

      background-image:
        paint(arc, purple, 0.4turn, 0.8turn, 40px, 15px),
        paint(arc, blue, -20deg, 170deg, 30px, 20px),
        paint(arc, red, 45deg, 220deg, 50px, 10px);
    }
    </style>

    <div id="example"></div>

    <script>
        CSS.paintWorklet.addModule('arc.js');
    </script>

    // arc.js
    registerPaint('arc', class {
      static get inputArguments() {
        return [
          '<color>',
          '<angle>',  // startAngle
          '<angle>',  // endAngle
          '<length>', // radius
          '<length>', // lineWidth
        ];
      }

      paint(ctx, geom, _, args) {
        ctx.strokeStyle = args[0].cssText;

        // Determine the center point.
        const x = geom.width / 2;
        const y = geom.height / 2;

        // Convert the start and end angles to radians.
        const startAngle = this.convertAngle(args[1]) - Math.PI / 2;
        const endAngle = this.convertAngle(args[2]) - Math.PI / 2;

        // Convert the radius and lineWidth to px.
        const radius = this.convertLength(args[3]);
        const lineWidth = this.convertLength(args[4]);

        ctx.lineWidth = lineWidth;

        ctx.beginPath();
        ctx.arc(x, y, radius, startAngle, endAngle, false);
        ctx.stroke();
      }

      convertAngle(angle) {
        switch (angle.unit) {
          case 'deg':
            return angle.value * Math.PI / 180;
          case 'rad':
            return angle.value;
          case 'grad':
            return angle.value * Math.PI / 200;
          case 'turn':
            return angle.value * Math.PI / 0.5;
          default:
            throw Error(`Unknown angle unit: ${angle.unit}`);
        }
      }

      convertLength(length) {
        switch (length.type) {
          case 'px':
            return length.value;
          default:
            throw Error(`Unkown length type: ${length.type}`);
        }
      }
    });

### 8.4. Example 4: Different Colors (based on size)

    <h1>
        Heading 1
    </h1>
    <h1>
        Another heading
    </h1>

    <style>
    h1 {
        background-image: paint(heading-color);
    }
    </style>

    <script>
        CSS.paintWorklet.addModule('heading-color.js');
    </script>

    // heading-color.js
    registerPaint('heading-color', class {
        static get inputProperties() { return []; }
        paint(ctx, geom, properties) {
            // Select a color based on the width and height of the image.
            const width = geom.width;
            const height = geom.height;
            const color = colorArray[(width * height) % colorArray.length];

            // Draw just a solid image.
            ctx.fillStyle = color;
            ctx.fillRect(0, 0, width, height);
        }
    });

### 8.5. Example 5: Drawing outside an element’s area

It is possible to draw outside an element’s area by using the border-image property.

    <style>
    #overdraw {
        --border-width: 10;

        border-style: solid;
        border-width: calc(var(--border-width) * 1px);

        border-image-source: paint(overdraw);
        border-image-slice: 0 fill;
        border-image-outset: calc(var(--border-width) * 1px);

        width: 200px;
        height: 200px;
    }
    </style>
    <div id="overdraw"></div>
    <script>
        CSS.paintWorklet.addModule('overdraw.js');
    </script>

    // overdraw.js
    registerPaint('overdraw', class {
        static get inputProperties() { return ['--border-width']; }
        paint(ctx, geom, properties) {
            const borderWidth = parseInt(properties.get('--border-width'));
            ctx.shadowColor = 'rgba(0,0,0,0.25)';
            ctx.shadowBlur = borderWidth;

            ctx.fillStyle = 'rgba(255, 255, 255, 1)';
            ctx.fillRect(borderWidth,
                         borderWidth,
                         geom.width - 2 * borderWidth,
                         geom.height - 2 * borderWidth);
        }
    });

## 9. Security Considerations

There are no known security issues introduced by these features.

## 10. Privacy Considerations

- The timing of paint callbacks can be used as a high-bandwidth channel for detecting "visited" state for links. (details) This is not a fundamentally new privacy leak, as visited state leaks from many interactions, but absent any further mitigations, this is a particularly high-bandwidth channel of the information.

  No official mitigations are planned at this time, as this privacy leak needs to be addressed more directly to fix all such channels.

## 11. Changes

Changes since the 9 August 2018 CR publication:

- Filtered the list of input properties to a paint worklet to be only known or custom properties.

- Added alpha flag to `PaintRenderingContext2D` to control whether the rendering surface is forced opaque or allows transparency.

- Fix definition for the size of the output bitmap:

  > The size of the output bitmap is the concrete object size of the object it is rendering to size of the fragment it is rendering .

## Conformance

### Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.

Advisements are normative sections styled to evoke special attention and are set apart from other normative text with `<strong class="advisement">`, like this: UAs MUST provide an accessible alternative.

### Conformance classes

Conformance to this specification is defined for three conformance classes:

style sheet
  A CSS style sheet.
renderer
  A UA that interprets the semantics of a style sheet and renders documents that use them.
authoring tool
  A UA that writes a style sheet.

A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.

A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)

An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.

### Partial implementations

So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

#### Implementations of Unstable and Proprietary Features

To avoid clashes with future stable CSS features, the CSSWG recommends following best practices for the implementation of unstable features and proprietary extensions to CSS.

### Non-experimental implementations

Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.

To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.

Further information on submitting testcases and implementation reports can be found from on the CSS Working Group’s website at http://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.

## Index

### Terms defined by this specification

- alpha
  - dfn for PaintRenderingContext2D, in §6
  - dict-member for PaintRenderingContext2DSettings, in §2
- class constructor, in §3
- constructor valid flag, in §3
- create a PaintRenderingContext2D object, in §6
- devicePixelRatio, in §2
- document paint definition, in §3
- document paint definitions, in §4
- draw a paint image, in §7
- height, in §7
- input argument syntaxes, in §3
- input properties
  - dfn for document paint definition, in §3
  - dfn for paint definition, in §3
- invoke a paint callback, in §7
- output bitmap, in §6
- paint(), in §5
- paint class instances, in §4
- paint definition, in §3
- paint definitions, in §4
- paint function, in §3
- PaintRenderingContext2D, in §6
- PaintRenderingContext2DSettings, in §2
- PaintRenderingContext2DSettings object
  - dfn for document paint definition, in §3
  - dfn for paint definition, in §3
- PaintSize, in §7
- paintWorklet, in §2
- PaintWorkletGlobalScope, in §2
- registerPaint(name, paintCtor), in §4
- width, in §7

https://drafts.csswg.org/css-backgrounds-3/#propdef-border-image Referenced in:

- 8.5. Example 5: Drawing outside an element’s area

https://drafts.csswg.org/css-cascade-4/#computed-value Referenced in:

- 5. Paint Notation
- 7. Drawing an image

https://drafts.csswg.org/css-display-3/#box Referenced in:

- 7. Drawing an image (2)

https://drafts.csswg.org/css-images-4/#invalid-image Referenced in:

- 5. Paint Notation (2)
- 7. Drawing an image (2) (3) (4) (5) (6) (7) (8) (9) (10)

https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value Referenced in:

- 5. Paint Notation

https://drafts.csswg.org/css-syntax-3/#function Referenced in:

- 3. Concepts
- 4. Registering Custom Paint

https://drafts.css-houdini.org/css-typed-om-1/#cssimagevalue Referenced in:

- 6.1. Drawing a CSSImageValue (2)

https://drafts.css-houdini.org/css-typed-om-1/#stylepropertymap Referenced in:

- 4. Registering Custom Paint

https://drafts.css-houdini.org/css-typed-om-1/#stylepropertymapreadonly Referenced in:

- 7. Drawing an image

https://drafts.csswg.org/css-ui-4/#propdef-cursor Referenced in:

- 5. Paint Notation

https://drafts.csswg.org/css-values-4/#comb-comma Referenced in:

- 5. Paint Notation

https://drafts.csswg.org/css-values-4/#typedef-ident Referenced in:

- 5. Paint Notation

https://drafts.csswg.org/css-values-4/#mult-opt Referenced in:

- 5. Paint Notation

https://drafts.csswg.org/css-variables-1/#custom-property Referenced in:

- 4. Registering Custom Paint

https://drafts.csswg.org/css-images-3/#typedef-image Referenced in:

- Unnumbered Section
- 1. Introduction
- 3. Concepts (2)
- 5. Paint Notation (2)
- 7. Drawing an image

https://drafts.csswg.org/css-images-3/#concrete-object-size Referenced in:

- 6. The 2D rendering context
- 7. Drawing an image (2)

https://drafts.csswg.org/css-images-3/#intrinsic-dimensions Referenced in:

- 7. Drawing an image (2) (3) (4)

https://drafts.csswg.org/css-images-3/#object-size-negotiation Referenced in:

- 7. Drawing an image (2)

https://drafts.csswg.org/cssom-1/#namespacedef-css Referenced in:

- 2. Paint Worklet

https://drafts.csswg.org/cssom-1/#supported-css-property Referenced in:

- 4. Registering Custom Paint

https://drafts.csswg.org/cssom-view-1/#dom-window-devicepixelratio Referenced in:

- 2. Paint Worklet

https://dom.spec.whatwg.org/#concept-document Referenced in:

- 3. Concepts
- 4. Registering Custom Paint (2)
- 7. Drawing an image (2)

https://html.spec.whatwg.org/multipage/canvas.html#canvascompositing Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawimage Referenced in:

- 6. The 2D rendering context
- 6.1. Drawing a CSSImageValue

https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawpath Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasfillstrokestyles Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasimagedata Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesmoothing Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesource Referenced in:

- 6.1. Drawing a CSSImageValue (2)

https://html.spec.whatwg.org/multipage/canvas.html#canvaspath Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvaspathdrawingstyles Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasrect Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasrenderingcontext2d Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasshadowstyles Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasstate Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvastext Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvastextdrawingstyles Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvastransform Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#canvasuserinterface Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-drawimage Referenced in:

- 6.1. Drawing a CSSImageValue

https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel Referenced in:

- 7. Drawing an image (2)

https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

https://html.spec.whatwg.org/multipage/canvas.html#reset-the-rendering-context-to-its-default-state Referenced in:

- 6. The 2D rendering context

https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-set-bitmap-dimensions Referenced in:

- 6. The 2D rendering context (2)

https://infra.spec.whatwg.org/#list-append Referenced in:

- 4. Registering Custom Paint

https://infra.spec.whatwg.org/#list-empty Referenced in:

- 4. Registering Custom Paint

https://infra.spec.whatwg.org/#map-exists Referenced in:

- 4. Registering Custom Paint (2)
- 7. Drawing an image (2)

https://infra.spec.whatwg.org/#list-iterate Referenced in:

- 4. Registering Custom Paint

https://infra.spec.whatwg.org/#map-get Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

https://infra.spec.whatwg.org/#list Referenced in:

- 3. Concepts (2) (3)
- 4. Registering Custom Paint
- 7. Drawing an image
- 7.1. Global Scope Selection

https://infra.spec.whatwg.org/#ordered-map Referenced in:

- 4. Registering Custom Paint (2) (3) (4)

https://infra.spec.whatwg.org/#map-set Referenced in:

- 4. Registering Custom Paint (2) (3)
- 7. Drawing an image (2)

https://infra.spec.whatwg.org/#struct Referenced in:

- 3. Concepts (2)

https://heycam.github.io/webidl/#idl-DOMException Referenced in:

- 4. Registering Custom Paint

https://heycam.github.io/webidl/#idl-DOMString Referenced in:

- 2. Paint Worklet

https://heycam.github.io/webidl/#Exposed Referenced in:

- 2. Paint Worklet
- 6. The 2D rendering context
- 7. Drawing an image

https://heycam.github.io/webidl/#Global Referenced in:

- 2. Paint Worklet

https://heycam.github.io/webidl/#invalidmodificationerror Referenced in:

- 4. Registering Custom Paint

https://heycam.github.io/webidl/#SameObject Referenced in:

- 2. Paint Worklet

https://heycam.github.io/webidl/#VoidFunction Referenced in:

- 2. Paint Worklet

https://heycam.github.io/webidl/#idl-boolean Referenced in:

- 2. Paint Worklet

https://heycam.github.io/webidl/#dfn-callback-function Referenced in:

- 3. Concepts
- 4. Registering Custom Paint

https://heycam.github.io/webidl/#dfn-callback-this-value Referenced in:

- 7. Drawing an image

https://heycam.github.io/webidl/#web-idl-arguments-list-converting Referenced in:

- 4. Registering Custom Paint (2) (3) (4)

https://heycam.github.io/webidl/#idl-double Referenced in:

- 7. Drawing an image (2)

https://heycam.github.io/webidl/#invoke-a-callback-function Referenced in:

- 7. Drawing an image

https://heycam.github.io/webidl/#dfn-throw Referenced in:

- 4. Registering Custom Paint (2) (3) (4) (5) (6) (7)
- 7. Drawing an image

https://heycam.github.io/webidl/#idl-unrestricted-double Referenced in:

- 2. Paint Worklet

https://drafts.css-houdini.org/worklets/#worklet Referenced in:

- 2. Paint Worklet (2) (3)
- 7. Drawing an image (2)

https://drafts.css-houdini.org/worklets/#workletglobalscope Referenced in:

- 2. Paint Worklet

https://drafts.css-houdini.org/worklets/#create-a-workletglobalscope Referenced in:

- 7. Drawing an image

https://drafts.css-houdini.org/worklets/#worklet-global-scope-type Referenced in:

- 2. Paint Worklet

https://drafts.css-houdini.org/worklets/#worklets-workletglobalscopes Referenced in:

- 7. Drawing an image
- 7.1. Global Scope Selection

### Terms defined by reference

- [css-backgrounds-3] defines the following terms:
  - border-image
- [css-cascade-4] defines the following terms:
  - computed value
- [css-display-3] defines the following terms:
  - box
- [css-images-4] defines the following terms:
  - invalid image
- [css-syntax-3] defines the following terms:
  - <declaration-value>
  - function
- [css-typed-om-1] defines the following terms:
  - CSSImageValue
  - StylePropertyMap
  - StylePropertyMapReadOnly
- [css-ui-4] defines the following terms:
  - cursor
- [css-values-4] defines the following terms:
  - ,
  - <ident>
  - ?
- [css-variables-1] defines the following terms:
  - custom property
- [css3-images] defines the following terms:
  - <image>
  - concrete object size
  - intrinsic dimensions
  - object size negotiation
- [cssom-1] defines the following terms:
  - CSS
  - supported css property
- [cssom-view-1] defines the following terms:
  - devicePixelRatio
- [DOM] defines the following terms:
  - document
- [HTML] defines the following terms:
  - CanvasCompositing
  - CanvasDrawImage
  - CanvasDrawPath
  - CanvasFillStrokeStyles
  - CanvasImageData
  - CanvasImageSmoothing
  - CanvasImageSource
  - CanvasPath
  - CanvasPathDrawingStyles
  - CanvasRect
  - CanvasRenderingContext2D
  - CanvasShadowStyles
  - CanvasState
  - CanvasText
  - CanvasTextDrawingStyles
  - CanvasTransform
  - CanvasUserInterface
  - drawImage
  - in parallel
  - queue a task
  - reset the rendering context to its default state
  - set bitmap dimensions
- [INFRA] defines the following terms:
  - append
  - empty
  - exist
  - for each
  - get
  - list
  - map
  - set
  - struct
- [WebIDL] defines the following terms:
  - DOMException
  - DOMString
  - Exposed
  - Global
  - InvalidModificationError
  - SameObject
  - VoidFunction
  - boolean
  - callback function
  - callback this value
  - converting
  - double
  - invoke
  - throw
  - unrestricted double
- [worklets-1] defines the following terms:
  - Worklet
  - WorkletGlobalScope
  - create a workletglobalscope
  - worklet global scope type
  - worklet's workletglobalscopes

## References

### Normative References

[CSS-BACKGROUNDS-3]
  Bert Bos; Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 17 October 2017. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-4]
  Elika Etemad; Tab Atkins Jr.. CSS Cascading and Inheritance Level 4. 28 August 2018. CR. URL: https://www.w3.org/TR/css-cascade-4/
[CSS-DISPLAY-3]
  Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 28 August 2018. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-IMAGES-4]
  Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Image Values and Replaced Content Module Level 4. 13 April 2017. WD. URL: https://www.w3.org/TR/css-images-4/
[CSS-SYNTAX-3]
  Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 20 February 2014. CR. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TYPED-OM-1]
  Shane Stephens; Tab Atkins Jr.; Naina Raisinghani. CSS Typed OM Level 1. 10 April 2018. WD. URL: https://www.w3.org/TR/css-typed-om-1/
[CSS-UI-4]
  Florian Rivoal. CSS Basic User Interface Module Level 4. 22 December 2017. WD. URL: https://www.w3.org/TR/css-ui-4/
[CSS-VALUES-4]
  Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 31 January 2019. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VARIABLES-1]
  Tab Atkins Jr.. CSS Custom Properties for Cascading Variables Module Level 1. 3 December 2015. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS3-IMAGES]
  Elika Etemad; Tab Atkins Jr.. CSS Image Values and Replaced Content Module Level 3. 17 April 2012. CR. URL: https://www.w3.org/TR/css3-images/
[CSSOM-1]
  Simon Pieters; Glenn Adams. CSS Object Model (CSSOM). 17 March 2016. WD. URL: https://www.w3.org/TR/cssom-1/
[CSSOM-VIEW-1]
  Simon Pieters. CSSOM View Module. 17 March 2016. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
  Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
  Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/
[WORKLETS-1]
  Ian Kilpatrick. Worklets Level 1. 7 June 2016. WD. URL: https://www.w3.org/TR/worklets-1/

## IDL Index

    partial namespace CSS {
        [SameObject] readonly attribute Worklet paintWorklet;
    };

    [Global=(Worklet,PaintWorklet),Exposed=PaintWorklet]
    interface PaintWorkletGlobalScope : WorkletGlobalScope {
        void registerPaint(DOMString name, VoidFunction paintCtor);
        readonly attribute unrestricted double devicePixelRatio;
    };

    dictionary PaintRenderingContext2DSettings {
        boolean alpha = true;
    };

    [Exposed=PaintWorklet]
    interface PaintRenderingContext2D {
    };
    PaintRenderingContext2D includes CanvasState;
    PaintRenderingContext2D includes CanvasTransform;
    PaintRenderingContext2D includes CanvasCompositing;
    PaintRenderingContext2D includes CanvasImageSmoothing;
    PaintRenderingContext2D includes CanvasFillStrokeStyles;
    PaintRenderingContext2D includes CanvasShadowStyles;
    PaintRenderingContext2D includes CanvasRect;
    PaintRenderingContext2D includes CanvasDrawPath;
    PaintRenderingContext2D includes CanvasDrawImage;
    PaintRenderingContext2D includes CanvasPathDrawingStyles;
    PaintRenderingContext2D includes CanvasPath;

    [Exposed=PaintWorklet]
    interface PaintSize {
        readonly attribute double width;
        readonly attribute double height;
    };

#dom-css-paintworklet Referenced in:

- 2. Paint Worklet (2) (3)

#paintworkletglobalscope Referenced in:

- 2. Paint Worklet (2) (3)
- 3. Concepts
- 4. Registering Custom Paint (2) (3)
- 7. Drawing an image (2)
- 7.1. Global Scope Selection (2) (3)

#dom-paintworkletglobalscope-devicepixelratio Referenced in:

- 2. Paint Worklet

#dictdef-paintrenderingcontext2dsettings Referenced in:

- 2. Paint Worklet (2)
- 4. Registering Custom Paint

#dom-paintrenderingcontext2dsettings-alpha Referenced in:

- 6. The 2D rendering context

#paint-definition Referenced in:

- 4. Registering Custom Paint

#paint-definition-class-constructor Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#paint-definition-paint-function Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#paint-definition-constructor-valid-flag Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image (2)

#paint-definition-input-properties Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#paint-definition-paintrenderingcontext2dsettings-object Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#document-paint-definition Referenced in:

- 4. Registering Custom Paint

#document-paint-definition-input-properties Referenced in:

- 4. Registering Custom Paint (2)

#document-paint-definition-input-argument-syntaxes Referenced in:

- 4. Registering Custom Paint (2)
- 7. Drawing an image

#document-paint-definition-paintrenderingcontext2dsettings-object Referenced in:

- 4. Registering Custom Paint (2)

#document-paint-definitions Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image (2)

#paint-definitions Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#paint-class-instances Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image

#dom-paintworkletglobalscope-registerpaint Referenced in:

- 2. Paint Worklet
- 4. Registering Custom Paint (2)
- 5. Paint Notation
- 7. Drawing an image

#funcdef-paint Referenced in:

- 3. Concepts
- 4. Registering Custom Paint
- 5. Paint Notation (2) (3)
- 7. Drawing an image (2) (3) (4) (5) (6)
- 8.1. Example 1: Colored Circle

#paintrenderingcontext2d Referenced in:

- 6. The 2D rendering context (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19)
- 11. Changes

#paintrenderingcontext2d-output-bitmap Referenced in:

- 6. The 2D rendering context (2) (3) (4) (5) (6)

#paintrenderingcontext2d-alpha Referenced in:

- 6. The 2D rendering context

#create-a-paintrenderingcontext2d-object Referenced in:

- 7. Drawing an image

#paintsize Referenced in:

- 4. Registering Custom Paint
- 7. Drawing an image (2)

#draw-a-paint-image Referenced in:

- 4. Registering Custom Paint
- 5. Paint Notation
- 7. Drawing an image (2) (3) (4) (5) (6)

#invoke-a-paint-callback Referenced in:

- 7. Drawing an image (2)