From f400a4132017f9008d413d3c23b8dd38c6406be4 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Gravel title
elementuse
elementtext-rendering
property
@@ -63246,6 +63251,9 @@ callback BlobCallback = undefined (Blob? blob);
when invoked, must run these steps:flood-color
propertyflood-opacity
property
If layer-count is not zero, then throw an
+ "InvalidStateError
" DOMException
.
If this canvas
element's bitmap's origin-clean flag is set to false, then throw a
"SecurityError
" DOMException
.
If layer-count is not zero, then throw an
+ "InvalidStateError
" DOMException
.
If this canvas
element's bitmap's origin-clean flag is set to false, then throw a
"SecurityError
" DOMException
.
A CanvasRenderingContext2D
object has an output bitmap that
is initialized when the object is created.
CanvasRenderingContext2D
output bitmap can be replaced and restored
+ by calls to beginLayer and endLayer, with the drawing state stack
+ keeping track of all active nested output bitmaps. The
+ CanvasRenderingContext2D
object has a layer-count integer that is initially set to zero,
+ keeping track of the number of opened nested layers. To access the content of the context's
+ output bitmap, the steps for reading the context output bitmap must be
+ used.
+
The output bitmap has an origin-clean flag, which can be set to true or false. Initially, when one of these bitmaps is created, its cases, this will be more memory efficient.
The bitmap of a canvas
element is the one bitmap that's pretty much always going
- to be needed in practice. The output bitmap of a rendering context, when it has one,
- is always just an alias to a canvas
element's bitmap.
canvas
element's bitmap. When layers are
+ opened, implementations must behave as if draw calls operate on a separate output
+ bitmap that gets composited to the parent output bitmap when the layer is
+ closed. If the canvas
element's bitmap needs to be presented while layers are opened,
+ layers are automatically closed, so that their content gets drawn to the context's output
+ bitmap. The drawing state stack is then restored, reopening all pending
+ layers before the script execution could resume.
Additional bitmaps are sometimes needed, e.g. to enable fast drawing when the canvas is being painted at a different size than its natural size, @@ -63978,8 +64019,9 @@ context.fillRect(100,0,50,50); // only this square remains
Objects that implement the CanvasState
interface maintain a stack of drawing
- states. Drawing states consist of:
Objects that implement the CanvasState
interface maintain a stack of drawing states.
+ Drawing states consist of:
imageSmoothingQuality
.The rendering context's bitmaps are not part of the drawing state, as they
- depend on whether and how the rendering context is bound to a canvas
element.
The rendering context's bitmaps are not part of the drawing state
+ (with the exception of layer's parentOutputBitmap
), as they depend on whether and how
+ the rendering context is bound to a canvas
element.
Objects that implement the CanvasState
mixin have a context lost boolean, that is initialized to false
@@ -64030,8 +64074,8 @@ context.fillRect(100,0,50,50); // only this square remains
Pops the top state on the stack, restoring the context to that state.
context.reset()
Resets the rendering context, which includes the backing buffer, the drawing state stack, - path, and styles.
Resets the rendering context, which includes the backing buffer, the drawing state + stack, path, and styles.
context.isContextLost()
Returns true if the rendering context was lost. Context loss can occur due to driver @@ -64042,11 +64086,26 @@ context.fillRect(100,0,50,50); // only this square remains
The save()
method
- steps are to push a copy of the current drawing state onto the drawing state stack.
The restore()
- method steps are to pop the top entry in the drawing state stack, and reset the drawing state it
- describes. If there is no saved state, then the method must do nothing.
If the drawing state stack is empty, + return.
If the canvas layer state at the top of the drawing state stack
+ is not null, throw an "InvalidStateError
"
+ DOMException
.
Let previousDrawingStates be the result of popping the drawing state stack.
Set all current drawing states to the values they have + in previousDrawingStates.
The reset()
method steps are to reset the rendering context to its default state.
Empty the list of subpaths in context's current default path.
Clear the context's drawing state stack.
Clear the context's drawing state stack.
Set the context's layer-count to + zero.
Reset everything that drawing state consists of to their initial values.
Objects that implement the CanvasLayers
mixin have methods (defined in this
+ section) for managing output bitmap layers.
Layers are opened and closed using beginLayer + and endLayer. When a layer is opened, the context + output bitmap is aliased to that layer's output bitmap, such that all + draw calls performed while the layer is active will effectively render onto the layer's + output bitmap. When endLayer is called, + the layer's output bitmap gets rendered to the parent's output bitmap + using the filter specified in beginLayer.
+ +The drawing state stack keeps track of opened layers by holding canvas layer + state structs containing the following items:
+ +parentOutputBitmap
, the layer's parent
+ output bitmap.xmlFilterList
, the layer's XML filter list.The layer rendering states are the subset of the drawing states that are applied to a layer's + output bitmap when it's drawn to its parent output bitmap. The + layer rendering states are:
+shadowOffsetX
,
+ shadowOffsetY
,
+ shadowBlur
,
+ shadowColor
Because the layer rendering states are applied on the layer's output, + they cannot also be applied to the layer's content, or else, they would be applied twice. These + states are therefore set to their default value when opening a layer.
+ +The transformation matrix and imageSmoothingEnabled
are not part of
+ the layer rendering states because if the layer's output was to be transformed or
+ smoothed, it would require resampling of the layer's output bitmap, lowering picture
+ quality for every layer nesting levels. It's better to transform and smooth the innermost layer
+ content and draw pixels directly to their final coordinate.
Filters specified via context.filter are not part of the layer rendering + states and are therefore not applied on the layer's output bitmap. The preferred way to + specify filters is to use beginLayer. Using + context.filter is inefficient because it + requires each individual draw call to be wrapped in a layer. It's better to make this cost + explicit by using beginLayer.
+ +The clipping region is the only state that gets applied to both the layer content + and the layer's output bitmap. As such, it's treated as a special case and is not + included in the layer rendering states.
+CanvasFilterInput
is used for describing SVG filters using JavaScript. A
+ CanvasFilterInput
object can be converted to an equivalent XML filter list. An XML filter list is a list of
+ XML element data for filters that fully describes an SVG filter network.
context.beginLayer([ { [ filter: filterInput ] }
+ ])
Pushes the current state onto the stack and starts a new layer. While a layer is active, + all draw calls are performed on a separate surface, which will later be drawn as a whole to the + canvas (or parent layer) when the layer is closed.
+ +If the filter
member is
+ specified, the filter effect is applied to the layer's resulting texture as it's drawn to the
+ parent output bitmap.
Filters are specified as a single CanvasFilterPrimitive
, or a list of
+ CanvasFilterPrimitive
to chain filter effects. CanvasFilterPrimitive
+ objects have a name
property, whose value is one of the supported
+ filter names, and additional properties corresponding to the settings of the filter. These
+ latter properties are the same as the XML attribute names when using the corresponding SVG
+ filter.
context.endLayer()
Pops the top state on the stack, restores the context to that state and draws the layer's
+ resulting texture to the parent surface (the canvas or the parent layer). The layer's filter
, if specified, gets applied,
+ along with the global rendering states as they were when beginLayer was called.
The beginLayer()
method steps are:
Let settings be the result of converting options to the dictionary type
+ BeginLayerOptions
. (This can throw an exception.)
Let currentOutputBitmap be the context's current + output bitmap
Let layerOutputBitmap be a newly created output bitmap, + initialized with the same size and color space + as `currentOutputBitmap` and with an origin-clean flag set to true.
Let xmlFilter be the result of running the steps for building an XML filter list + given settings["filter"].
Let layerState be a new canvas layer state object, initialized + with currentOutputBitmap and xmlFilter.
Run the steps of the save
method.
+
+
Reset the context's layer rendering states to their default value.
Set the canvas layer state at the top of the drawing state stack + to layerState.
Set the context's current output bitmap to + layerOutputBitmap
Increment layer-count by one.
The endLayer()
method steps are:
If the drawing state stack is empty, then
+ throw an "InvalidStateError
" DOMException
.
Let layerState be the canvas layer state at the top of the + drawing state stack.
If layerState is null, throw an "InvalidStateError
"
+ DOMException
.
Let layerOutputBitmap be the context's current + output bitmap
Let parentOutputBitmap be
+ layerState["parentOutputBitmap
"]
If layerOutputBitmap is marked as not origin-clean, then set the origin-clean flag of parentOutputBitmap + to false.
Set the context's current output bitmap to + parentOutputBitmap
Let filteredLayerOutputBitmap be the result of applying
+ layerState["xmlFilterList
"] to layerOutputBitmap using the
+ steps to apply an XML filter list.
Let parentDrawingStates be the result of popping the drawing state stack.
Reset all context drawing states to their default + values, then set the current layer rendering states and the clipping + region to the values stored in parentDrawingState.
Draw filteredLayerOutputBitmap onto the context's current + output bitmap using the steps outlined in the drawing model.
Set all current drawing states to the values they have + in parentDrawingStates.
Decrement layer-count by one.
For legacy reasons, calling restore()
+ when the drawing state stack is empty is a no-op. The addition of the layer API
+ however introduced several new potential pitfalls. For instance, scripts like context.save(); context.endLayer();
or context.beginLayer();
+ context.restore();
are problematic. They are symptomatic of web page bugs and user agents
+ cannot silently fix these bugs on behalf of the page (e.g. did the page intend to call
+ endLayer()
instead of restore()
, or is there a missing save()
?) For that reason, invalid API sequences involving
+ layers throw exceptions to make the issue clear to web developers.
The steps for building an XML + filter list require the following definitions:
+ +The supported filter names are
+ "colorMatrix
",
+ "componentTransfer
",
+ "convolveMatrix
",
+ "dropShadow
" and
+ "gaussianBlur
".
+
+
The XML element data for filters is a struct, with the following items:
+ +A string name
An ordered map of strings to strings attributes
A list of XML element data for filters children
To get the IDL type for a canvas filter attribute attrName:
+ +Let type be the type listed for attrName in Filter + Effects.
If type is "false | true
", then return boolean
.
If type is "list of <number>s
", then return sequence<double>
.
If type is "<number>
", then return double
.
If type is "<integer>
", then return long long
.
If type is "<number-optional-number>
", then
+ return (double or sequence<double>)
.
Return DOMString
.
To generate an XML value from a key, + value pair: + +
Let type be the result of getting the IDL type for a canvas filter + attribute for key.
Let idlValue be the result of converting value to type.
If type is (double or sequence<double>)
,
+ value is a sequence<double>
and value doesn't have two elements,
+ throw a TypeError
exception.
Let xmlValue be the result of converting idlValue to an ECMAScript value, and
+ then converting that result to a DOMString
.
Return xmlValue.
The steps for building an + XML filter list given + filters are:
+ +Let xmlFilters be an empty list.
If filters is null, then set filters to « ».
If filters is a CanvasFilterPrimitive
, then set filters
+ to « filters ».
For each filterDict of filters:
+ +If filterDict["name
"] does not exist, then throw a TypeError
exception.
Let filterName be the value of filterDict["name
"].
If filterName is not one of supported filter names, then + continue.
Let xmlName be the concatenation of "fe
", the first
+ code unit of filterName converted to ASCII uppercase,
+ and all code units of filterName after the first
+ one.
Let xmlFilter be a new XML element data for filters whose name is xmlName, whose attributes is an empty ordered map, and whose children is an empty list.
Append xmlFilter to + xmlFilters.
For each key → value of + filterDict:
+ +If any of the following are true:
+ +key is not the local name of an attribute listed for the filter + primitive given by xmlName
key is the local name of a core attribute
key is the local name of a presentation attribute other
+ than "flood-color
" and "flood-opacity
"
key is the local name of a filter primitive + attribute
key contains U+003A (:)
then continue.
+If key is one of "funcR
", "funcG
", "funcB
", "funcA
":
Set value to the result of
+ converting value to record<DOMString,
+ any>
.
Let xmlTransferName be the concatenation of "fe
",
+ the first code unit of key converted to ASCII
+ uppercase, and all code units of key
+ after the first one.
Let transferFunction be a new XML element data for filters + whose name is xmlTransferName, whose + attributes is an empty ordered map, and whose + children is an empty list.
For each transferName → transferValue of value:
+ +Let transferFunctionValue be the result of generating an XML value from transferName + and transferValue.
Set transferFunction's attributes[transferName] to + transferFunctionValue.
Append transferFunction to xmlFilter's children.
Otherwise:
+ +Let attrXMLValue be the result of generating an XML value from key and + value.
Set xmlFilter's attributes[key] to + attrXMLValue.
The steps to apply an XML filter list to an image given an XML filter list filters are:
+Let image be the source image
For each filter of filters:
+Let svgFilter be an SVG filter, obtained by mapping each attributes of the filter XML filter list to the SVG equivalent.
Render image using svgFilter, creating + filteredImage
Let image be an alias to filteredImage
Return image.
The following example will create a layer with a colorMatrix
+ filter that swaps the green and red channels, then blurs the result by 5 pixels:
// canvas is a reference to a <canvas> element
+const context = canvas.getContext('2d');
+context.beginLayer({filter: [
+ {
+ name: 'colorMatrix',
+ type: 'matrix',
+ values: [
+ 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0
+ ],
+ },
+ {
+ name: 'gaussianBlur',
+ stdDeviation: 5,
+ }
+]});
+ Currently, CanvasFilterInput
s can only be linear sequences of
+ filters. Full filter graphs are a planned expansion of this feature.
Before any operations could access the canvas
element's bitmap pixels, the
+ drawing state stack must be flushed so that all pending layers are closed and
+ rendered to their parent output bitmap all the way to the canvas
+ element's bitmap. The steps for flushing the drawing state stack are:
Save the context's current drawing state in the drawing state
+ stack by running the save()
method
+ steps.
Let stackBackup be an empty list.
While the drawing state stack is not empty:
Prepend the drawing state at the top of + the drawing state stack to stackBackup.
If the canvas layer state at the top of the drawing state stack
+ is not empty, run the endLayer()
method
+ steps.
Otherwise, run the restore()
method
+ steps.
return stackBackup.
Given stackBackup which was returned when flushing the drawing state + stack, the drawing state stack can be restored to the state it was before it + was flushed by running the steps for restoring the drawing state stack:
+ +For each stateEntry of + stateBackup:
Push stateEntry onto the drawing state + stack.
Restore the context's current drawing state by running the restore()
method steps.
The steps for reading the context output bitmap are:
+ +Let drawingStateStackBackup be the result of flushing the drawing state + stack.
Let resultBitmap be a reference on the context output + bitmap.
Run the steps for restoring the drawing state stack, given + drawingStateStackBackup.
Return resultBitmap.
HTMLCanvasElement
OffscreenCanvas
If image has either a horizontal dimension or a vertical dimension
- equal to zero, then throw an "InvalidStateError
"
- DOMException
.
If the rendering context associated with image has a layer-count different than zero, then throw an
+ "InvalidStateError
" DOMException
.
If image has either a horizontal dimension or a vertical dimension
+ equal to zero, then throw an "InvalidStateError
"
+ DOMException
.
ImageBitmap
VideoFrame
If either the sw or sh arguments are zero, then throw an
"IndexSizeError
" DOMException
.
If layer-count is not zero, then throw an
+ "InvalidStateError
" DOMException
.
If the CanvasRenderingContext2D
's origin-clean flag is set to false, then throw a
"SecurityError
" DOMException
.
If IsDetachedBuffer(buffer) is true, then throw an
"InvalidStateError
" DOMException
.
If layer-count is not zero, then throw an
+ "InvalidStateError
" DOMException
.
If dirtyWidth is negative, then let dirtyX be dirtyX+dirtyWidth, and let dirtyWidth be equal
@@ -69533,6 +70122,13 @@ interface OffscreenCanvas : EventTarget {
internal slot is set to true, then return a promise rejected with an
"InvalidStateError
" DOMException
.
If this OffscreenCanvas
object's context mode is 2d and the rendering context's layer-count is not zero, then return a promise
+ rejected with an "InvalidStateError
"
+ DOMException
.
If this OffscreenCanvas
object's context mode is 2d and the rendering context's OffscreenCanvasRenderingContext2D {
};
OffscreenCanvasRenderingContext2D includes CanvasState;
+OffscreenCanvasRenderingContext2D includes CanvasLayers;
OffscreenCanvasRenderingContext2D includes CanvasTransform;
OffscreenCanvasRenderingContext2D includes CanvasCompositing;
OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing;
@@ -139132,6 +139729,7 @@ INSERT INTERFACES HERE
Jasper Bryant-Greene,
Jasper St. Pierre,
Jatinder Mann,
+ Jean-Philippe Gravel,
Jean-Yves Avenard,
Jed Hartman,
Jeff Balogh,