Skip to content

Conversation

CedricGuillemet
Copy link
Contributor

@CedricGuillemet CedricGuillemet commented Feb 25, 2025

  • Canvas plugin with more support for Web Canvas API
  • Test PG
  • Small change in Compiler Traverser to support bgfx bundled spirv (instead of our spirv fork) when building bgfx shader tool

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]>
Pheo and others added 6 commits April 8, 2025 13:24
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 and others added 6 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
…nto CanvasTest

# Conflicts:
#	.github/jobs/test_install_win32.yml
#	Apps/UnitTests/Scripts/tests.js
#	Plugins/NativeEngine/CMakeLists.txt
@CedricGuillemet
Copy link
Contributor Author

Comparison PG : https://playground.babylonjs.com/#TKVFSA

@CedricGuillemet CedricGuillemet changed the title Canvas test Canvas plugin Oct 15, 2025
@CedricGuillemet CedricGuillemet marked this pull request as ready for review October 15, 2025 14:28
Copy link
Member

@ryantrem ryantrem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a lot of this has already been reviewed in the side branch, so mostly just commenting on some high level things related to bringing the code into master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a readme.md explaining where this OSS code came from and whether we have modified it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also how nanovg_babylon.* relates to the other files?

#include "Gradient.h"

/*
Most of these context methods are preliminary work. They are currenbly not tested properly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still want this comment? Also there is a typo in it anyway (currenbly).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it's better to add a readme and document the plugin as experimental IMHO.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a readme.md explaining where this came from and if it has any Babylon modifications also?

PRIVATE GraphicsDeviceContext
PRIVATE JsRuntime
PRIVATE SPIRV)
if(BGFX_BUILD_TOOLS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this more? What's this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bgfx shaderc tool needed to be compiled to apply changes in nanovg shaders. But, BN and bgfx need different versions spirv/glslang with different dependencies.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I still don't understand. What does bgfx's shaderc tool have to do with NativeEngine?

Comment on lines 24 to 25
static constexpr int NORMAL_WEIGHT = 400;
static constexpr int BOLD_WEIGHT = 700;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static constexpr int NORMAL_WEIGHT = 400;
static constexpr int BOLD_WEIGHT = 700;
static constexpr const int NORMAL_WEIGHT = 400;
static constexpr const int BOLD_WEIGHT = 700;

FontStyle style{FontStyle::Normal};
int weight{NORMAL_WEIGHT};
float size{10};
std::string family{"sans-serif"};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables should have m_ prefix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even public? I commented on them being public, so if we switch and have get functions, then it seems like they should be m_

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR made all of these variables private?

Comment on lines +20 to +21
float GetSize() const { return size; }
const std::string& GetFamiliy() const { return family; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Spelling, though I would recommend we do it like this.

Suggested change
float GetSize() const { return size; }
const std::string& GetFamiliy() const { return family; }
float Size() const { return size; }
const std::string& Family() const { return family; }

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.

7 participants