Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 25340120c860b6d135d7b6fc7a36d8cbd17ca0dd
https://github.com/WebKit/WebKit/commit/25340120c860b6d135d7b6fc7a36d8cbd17ca0dd
Author: Ahmad Saleem <[email protected]>
Date: 2026-08-21 (Fri, 21 Aug 2026)
Changed paths:
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.path2d-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.path2d.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.transform-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.transform.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.winding-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.winding.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.path2d-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.path2d.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.transform-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.transform.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker.js
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker-expected.txt
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker.html
A
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker.js
M Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
M Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
Log Message:
-----------
Canvas 2D hit testing and transform mutations should not require the canvas
bitmap
https://bugs.webkit.org/show_bug.cgi?id=322160
rdar://185387739
Reviewed by Kimmo Kinnunen.
isPointInPath(), isPointInStroke(), drawFocusIfNeeded() and all six CTM
mutators opened with `if (!effectiveDrawingContext()) return;`. That runs
buffer() -> allocateImageBuffer(), so a pure geometry query on a fresh
canvas committed width * height * 4 bytes plus an IOSurface. Neither
hit-testing helper uses the context it fetched: Path::contains() is a CG
path query, and PathCG::strokeContains() builds its own GraphicsContext
over the 1x1 scratchContext().
It is also a correctness bug. validateArea() returns false when the area
is zero, so a canvas with a zero width or height has no bitmap at all.
Hit tests therefore returned false for points genuinely inside the path,
and every CTM mutation was silently dropped.
The spec does not permit this. Per the canvas state [1]: "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
same section lists "The current transformation matrix." as the first
component of the drawing state. Nor is the CTM merely a painting input:
"The current transformation matrix is applied to coordinates when
creating the current default path, and when painting text, shapes, and
Path2D objects" [2]. Dropping a mutation therefore corrupts the path as
it is built -- which is what we do, by folding the inverse into m_path --
so the damage does not depend on there being a bitmap to paint into.
Both hit-testing algorithms are likewise pure geometry once the
non-finite check has run [3][4], over inputs that all exist without a
backing store: the current default path, of which "There is only one
current default path, it is not part of the drawing state" [5], the CTM,
and for isPointInStroke() the line styles of the CanvasPathDrawingStyles
mixin. Firefox already behaves this way; Chrome matches our old behavior.
Drop the check outright in the two hit-testing helpers, move the fetch to
the point of use behind `if (auto* c = effectiveDrawingContext())` in the
mutators so the state update happens either way, and hoist the cheap
early-outs above the fetch in drawFocusIfNeededInternal() so the common
unfocused case no longer allocates.
Reordering cannot let state().transform drift from the context CTM:
m_hasCreatedImageBuffer is only cleared by didUpdateCanvasSizeProperties()
on a size change, which also resets the state stack and clears the path.
[1] https://html.spec.whatwg.org/multipage/canvas.html#the-canvas-state
[2] https://html.spec.whatwg.org/multipage/canvas.html#transformations
[3]
https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-ispointinpath
[4]
https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-ispointinstroke
[5] https://html.spec.whatwg.org/multipage/canvas.html#current-default-path
Tests: 2d.path.isPointInPath.nobitmap{,.path2d,.winding,.transform}
2d.path.isPointInStroke.nobitmap{,.path2d,.transform}
Those live under html/canvas/{element,offscreen}/path-objects/ and are
generated by /html/canvas/tools/gentest.py from tools/yaml/path-objects.yaml,
so the seven new YAML entries emit the HTMLCanvasElement, OffscreenCanvas and
worker flavor of each. All 21 baselines are a FAIL before this change.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.path2d-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.path2d.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.transform-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.transform.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.winding-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInPath.nobitmap.winding.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.path2d-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.path2d.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.transform-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/path-objects/2d.path.isPointInStroke.nobitmap.transform.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.path2d.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.transform.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.winding.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInPath.nobitmap.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.path2d.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.transform.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker-expected.txt:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker.html:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/offscreen/path-objects/2d.path.isPointInStroke.nobitmap.worker.js:
Added.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/isPointInPath-without-bitmap-expected.txt:
Removed.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/isPointInPath-without-bitmap.html:
Removed.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/isPointInStroke-without-bitmap-expected.txt:
Removed.
*
LayoutTests/imported/w3c/web-platform-tests/html/canvas/isPointInStroke-without-bitmap.html:
Removed.
* Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawFocusIfNeededInternal):
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::scale):
(WebCore::CanvasRenderingContext2DBase::rotate):
(WebCore::CanvasRenderingContext2DBase::translate):
(WebCore::CanvasRenderingContext2DBase::transform):
(WebCore::CanvasRenderingContext2DBase::setTransform):
(WebCore::CanvasRenderingContext2DBase::resetTransform):
(WebCore::CanvasRenderingContext2DBase::isPointInPathInternal):
(WebCore::CanvasRenderingContext2DBase::isPointInStrokeInternal):
Canonical link: https://commits.webkit.org/319602@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications