Skip to content

Canvas test #1468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 48 commits into
base: master
Choose a base branch
from
Draft

Canvas test #1468

wants to merge 48 commits into from

Conversation

CedricGuillemet
Copy link
Contributor

Draft PR for build/testing validation

CedricGuillemet and others added 30 commits February 6, 2025 11:24
Add `fontBoundingBoxAscent` and `fontBoundingBoxDescent` to textMetrics
- Adds bindings for setting and getting `letterSpacing`
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/letterSpacing
- Adds implementation for setter and getter
Co-authored-by: Ryan Tremblay <[email protected]>
… into CanvasTest

# Conflicts:
#	Polyfills/Canvas/Source/Context.cpp
- https://developer.mozilla.org/en-US/docs/Web/API/Path2D

Adds nanosvg.h for SVG path parsing.
Known missing functionality:
1. `addPath` doesn't accept DOMMatrix transform
2. `roundRect` doesn't accept CSS-style radii array
3. `ellipse` doesn't handle clockwise

Called from BabylonJS/Babylon.js#16221
-
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getTransform
-
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform
-
https://developer.mozilla.org/en-US/docs/Web/API/Path2D/addPath#transform

usage:
```
// Path 2D
let path = new _native.Path2D();
let path2 = new _native.Path2D("M 10,30 A 20, 20 0, 0, 1 50, 30 A 20, 20 0, 0, 1 90, 30 Q 90, 60 50, 90 Q 10, 60 10, 30 z");
path.addPath(path2, { a: 1, b: 0, c: 0, d: 1, e: 400, f: 0 }); // shift right 400
context.stroke(path);
```
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect
Known Issues:
- clipping round rect does not have rounded corners

Co-authored-by: Cedric Guillemet <[email protected]>
Small PR just so later PRs that require modifying nanovg have proper
diffs
- allow NVGPaint to have 2 images (onlye used when text is mixed with
gradient)
- shader update


![image](https://github.com/user-attachments/assets/c0652079-5d45-49c8-acc6-1432c7928c46)
I'll need someone to generate the HSSL shader for me since I'm on Mac.
Currently doesn't support blurred text but can add that in a future PR.

---------

Co-authored-by: Cedric Guillemet <[email protected]>
- Adds example Path2D usage in experience.js.
- Makes Path2D work with .fill as well

![image](https://github.com/user-attachments/assets/18aef1c2-ea8e-48c6-b175-1c1e31e2c0d3)

---------

Co-authored-by: Cedric Guillemet <[email protected]>
CedricGuillemet and others added 14 commits April 4, 2025 17:05
Replaces #1488

- Fix wrongly named `CreateInstance` with `Initialize`
- Canvas/Context unit test
- Implement `GetCanvas`
- Fix parameters and objectReference between Canvas and Context
- Keep and return the object reference created with `getContext`
- Install specified CMake version for Windows platform (see
#1492 )
- Update to Babylon.js 8.0

---------

Co-authored-by: Sergio R. Z. Masson <[email protected]>
…nto CanvasTest

# Conflicts:
#	Polyfills/Canvas/Source/Canvas.cpp
- Supports passing Path2D to Path2D constructor
- Handles >1 args for context.fill
- As
[matanui159](https://github.com/BabylonJS/BabylonNative/issues?q=is%3Apr%20is%3Aopen%20author%3Amatanui159),
as pointed out, `SetHeight`, `SetWidth` clears canvas on browser even if
width/height doesn't change. We re-use framebuffer but clear it in this
scenario.
This improves the handling of the "font" field on the context to
properly parse out weight/style/size. Currently weight and style are
unused since the font map only takes the family name into consideration.
- Adds basic framebuffer manager `FrameBufferPool`, enabling multi-pass
composition in `nanovg_filterstack`
- Wires up `context.filter`
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter
- Incomplete implementation of `blur()`
https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur

This PR takes over @CedricGuillemet's
#1477
Comments from CedricGuillemet#9
addressed before opening this for review. Added comments for the ones
which I haven't addressed.

RenderDoc shows filterstack correctly swapping between render targets
for a 3-iterations (6 pass) blur.:

![image](https://github.com/user-attachments/assets/b758ca18-191c-450f-b63e-823a79221eaa)

Will need to do abit of digging on weights to match how it looks on
browser. Applying filter blur to couple of items in experience.js:

![image](https://github.com/user-attachments/assets/683e5aef-301d-44c6-8fce-c072bd204164)

Also, on Babylon.js side, have raised a PR adding `filter` to context.
BabylonJS/Babylon.js#16424

---------

Co-authored-by: Cedric Guillemet <[email protected]>
Fixes:
- Depth stencil missing. Not optional in nanovg
- Unnecessary texture creation. This was caused by a bad merge
resolution
([link](50697ff))
- Missing `m_available` increment when framebuffer released caused
infinite framebuffer creation

The various warnings about missing stencil bugger and failed to allocate
framebuffer are now gone.
MDN:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/direction
MDN:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getTransform

- Context direction is incomplete. Further investigation is needed on a
solution to deal with ligatures (eg. stb_freetype + harfbuzz?)
- Context getTransform() now returns missing DOMMatrix properties
…nto CanvasTest

# Conflicts:
#	Polyfills/Canvas/Source/Canvas.cpp
#	Polyfills/Canvas/Source/Canvas.h
#	Polyfills/Canvas/Source/Context.cpp
#	Polyfills/Canvas/Source/Context.h
Pheo added 4 commits April 28, 2025 09:02
W3: https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement

- 13-tap gaussian blur for s < 2
- 3-pass box blur for s >= 2

Notes:
- gaussian weights no longer hardcoded. we can optimize by caching
weights.
- box blur handles even vs odd kernel as per W3. sanity limit of 1000px.
- edge sampling set to mirror. this avoids artifacts when blurring close
to edge.

Testing with even-case box blur d=8: `ctx.filter='blur(4px)'`

![image](https://github.com/user-attachments/assets/9b885a9e-c1d3-41c5-b14d-c77bdd2ecc63)
MDN:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect
Adds support for single DOMPoint argument in roundRect (Context, Path2D)
Looks like `nvgRoundedRectVarying` already implemented seperate x/y
radius, so just needed to add extra args


![image](https://github.com/user-attachments/assets/97ba3152-4d2d-4979-91cd-224200b28492)
@ryantrem found that when we load in a replacement font buffer..
the old buffer passed to nvgCreateFontMem is freed and can get corrupted

To solve this, we've made LoadTTFAsync effectively synchronous and don't
allow loading in a duplicate font. We can consider future work to
support safely updating existing fonts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants