Skip to content
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

Question: Use node-canvas without node (aka from native code) #2481

Open
vExcess opened this issue Jan 8, 2025 · 2 comments
Open

Question: Use node-canvas without node (aka from native code) #2481

vExcess opened this issue Jan 8, 2025 · 2 comments

Comments

@vExcess
Copy link

vExcess commented Jan 8, 2025

I want to use HTML Canvas outside of JavaScript. Is it possible to use the node-canvas library directly from C++ instead of using it from JavaScript? Going through the code it looks like NAPI code is fairly ingrained into the C++ code and not just a surface layer binding.

Being able to use HTML Canvas from native code instead of having to directly use Cairo which is much more low level would make my life much easier.

@chearon
Copy link
Collaborator

chearon commented Jan 8, 2025

I wouldn't call Cairo lower-level than JS canvas. Other than the fact that Cairo uses C data structures and calling conventions, it's pretty much the same API. I definitely wouldn't try to call NAPI/JS from C++ if you're already in native code.

@vExcess
Copy link
Author

vExcess commented Jan 13, 2025

Because I can't use node-canvas outside of JavaScript, I've been working on porting node-canvas from C++ to Dart and I've found an odd bug.

If I call ctx.roundRect(x, y, w, h, [r, r, r, r]) the expected output is that all radiuses are rounded, but only the upper left radius is rounded as is seen in the left half of the attached screenshot.

I looked into the implementation for Context2d::RoundRect and find

auto top = upperLeft.x + upperRight.x;
    auto right = upperRight.y + lowerRight.y;
    auto bottom = lowerRight.x + lowerLeft.x;
    auto left = upperLeft.y + lowerLeft.y;
    auto scale = std::min({ width / top, height / right, width / bottom, height / left });
    if (scale < 1.) {
      upperLeft.x *= scale;
      upperLeft.y *= scale;
      upperRight.x *= scale;
      upperRight.x *= scale;
      lowerLeft.y *= scale;
      lowerLeft.y *= scale;
      lowerRight.y *= scale;
      lowerRight.y *= scale;
    }

Is it intended for both the x and y of the upper left corner to be scaled, but only the x component of upperRight and only the y component of lowerLeft and lowerRight to be scaled? I can't imagine why that would be the intended behavior.

I tried scaling both the x and y component of all corners like so

upperLeft.x *= scale;
  upperLeft.y *= scale;
  upperRight.x *= scale;
  upperRight.y *= scale;
  lowerLeft.x *= scale;
  lowerLeft.y *= scale;
  lowerRight.x *= scale;
  lowerRight.y *= scale;

And after my change I retested the code and now all corners of roundRect are properly rounded as is seen in the right half of the attached screenshot.

Image

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

No branches or pull requests

2 participants