triniwiz / nativescript-canvas-plugin

The source is now managed at https://github.com/NativeScript/canvas
Apache License 2.0
31 stars 5 forks source link

Issue with canvg #17

Closed sebj54 closed 4 years ago

sebj54 commented 4 years ago

Description

An error is thrown when using canvg (it is a package used to draw from a SVG, it is very useful with complex shapes and it works with node). It fails even with a very simple SVG (a rectangle in this case).

The exception is about nativeSetMiterLimit everytime, even if the SVG does not have stroke-miterlimit (I don't know if it is relevant :grin:).

An uncaught Exception occurred on "GLThread 5008" thread.
No implementation found for long com.github.triniwiz.canvas.CanvasRenderingContext2D.nativeSetMiterLimit(long, float) (tried Java_com_github_triniwiz_canvas_CanvasRenderingContext2D_nativeSetMiterLimit and Java_com_github_triniwiz_canvas_CanvasRenderingContext2D_nativeSetMiterLimit__JF)

StackTrace:
java.lang.UnsatisfiedLinkError: No implementation found for long com.github.triniwiz.canvas.CanvasRenderingContext2D.nativeSetMiterLimit(long, float) (tried Java_com_github_triniwiz_canvas_CanvasRenderingContext2D_nativeSetMiterLimit and Java_com_github_triniwiz_canvas_CanvasRenderingContext2D_nativeSetMiterLimit__JF)
    at com.github.triniwiz.canvas.CanvasRenderingContext2D.nativeSetMiterLimit(Native Method)
    at com.github.triniwiz.canvas.CanvasRenderingContext2D.access$1100(CanvasRenderingContext2D.java:12)
    at com.github.triniwiz.canvas.CanvasRenderingContext2D$5.run(CanvasRenderingContext2D.java:322)
    at com.github.triniwiz.canvas.GLTextureView$GLThread.guardedRun(GLTextureView.java:1370)
    at com.github.triniwiz.canvas.GLTextureView$GLThread.run(GLTextureView.java:1154)

Which platform(s) does your issue occur on?

Please, provide the following version numbers that your issue occurs with:

{
  "dependencies": {
    "@directus/sdk-js": "^6.1.1",
    "@nstudio/nativescript-checkbox": "^1.0.0",
    "@vue/devtools": "^5.3.3",
    "canvg": "^3.0.6",
    "dotenv": "^8.2.0",
    "nativescript-canvas-plugin": "^0.5.2",
    "nativescript-plugin-firebase": "^10.5.2",
    "nativescript-sentry": "^1.9.1",
    "nativescript-socketio": "^3.3.1",
    "nativescript-toasty": "^3.0.0-alpha.2",
    "nativescript-ui-calendar": "^6.1.0",
    "nativescript-vue": "^2.6.2",
    "nativescript-vue-devtools": "^1.4.0",
    "tns-core-modules": "^6.5.1",
    "vuex": "^3.4.0",
    "xmldom": "^0.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "@vue/cli-plugin-eslint": "^4.3.1",
    "@vue/eslint-config-standard": "^5.1.2",
    "babel-loader": "^8.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "nativescript-dev-webpack": "^1.5.1",
    "nativescript-vue-template-compiler": "^2.6.2",
    "nativescript-worker-loader": "~0.11.0",
    "node-sass": "^4.13.1",
    "vue-loader": "^15.9.1"
  }
}

Please, tell us how to recreate the issue in as much detail as possible.

Code

<template>
    <canvas @ready="loaded" />
</template>

<script>
import Canvg from 'canvg'
import { DOMParser } from 'xmldom'
import testSvg from '~/assets/images/test.svg'

export default {
    methods: {
        loaded({ object }) {
            const canvas = object
            const ctx = canvas.getContext('2d')
            const options = {
                window: null,
                DOMParser,
                ignoreMouse: true,
                ignoreAnimation: true,
            }

            Canvg.fromString(ctx, testSvg, options)
                .render()
        },
    },
}
</script>
<svg width="400" height="110">
  <rect width="300" height="100" fill="rgb(0,0,255)" />
</svg>
triniwiz commented 4 years ago

interesting find 😃will push something soonn

triniwiz commented 4 years ago

Was a silly bug I placed the native method under Java_com_github_triniwiz_canvas_CanvasView vs Java_com_github_triniwiz_canvas_CanvasRenderingContext2D 🤦

sebj54 commented 4 years ago

It happens! :joy:

triniwiz commented 4 years ago

update an try again 😄

sebj54 commented 4 years ago

Thanks for the quick fix!

No more error now but the SVG does not appear. I'll try to make it work, there may be an issue with the SVG itself or canvg's options.

triniwiz commented 4 years ago

Canvg maybe missing some dom reqs you can try installing https://github.com/triniwiz/nativescript-browser-polyfill an requiring it . It should help with some missing dom requirements 🙂

sebj54 commented 4 years ago

Thanks for the suggestion @triniwiz!

I tried but unfortunately it didn't work either. I also tried to use an SVG path with TNSPath2D (like this: https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D#Using_SVG_paths). But It also doesn't work. Is it implemented or am I doing something wrong?

triniwiz commented 4 years ago

Interesting during implementing I used that example I'll look into it soon

sebj54 commented 4 years ago

I did not expect a so quick answer 😅

Here is what I did:

<template>
    <tns-canvas
        @ready="loaded"
        width="566"
        height="574"
    />
</template>

<script>
import { TNSPath2D } from 'nativescript-canvas-plugin'

export default {
    methods: {
        loaded({ object }) {
            const canvas = object
            const ctx = canvas.getContext('2d')

            ctx.strokeStyle = '#63cac9'
            ctx.fillStyle = '#f5f3f4'

            const p = new TNSPath2D('M436.6,729.226l-2.549-1.67-3.428-8.263,2.549-2.2.439-1.934-9.143-5.978-3.868-4.044.615-2.813-1.758-2.462-2.637-.7-7.912,2.9-2.549-1.582-1.934,2.11-6.857-.967-10.637-6.329-2.286,1.582-9.054-2.2-6.242,1.846-5.538-1.055-1.495-3.252-3.956,9.406h-3.78l-2.2,2.462,1.67,5.714,3.6,6.593.528,10.725,6.065,5.275,1.23,5.539,2.2,2.2,3.077-.7,2.725,10.461h.088l6.769-.7,1.934-2.813,1.494,2.637,2.725-1.67,3.692.528.615,2.989,4.132,4.22-.527,2.725-2.549,1.495,9.055.7,10.988-2.637L415.768,752l.263-5.714,15.121-2.989-.352-8.439,2.9-.792Z')

            ctx.stroke(p)
            ctx.fill(p)
        },
    },
}
</script>

And here is the error:

System.err: An uncaught Exception occurred on "main" thread.
System.err: Calling js method contextReady failed
System.err: Error: JNI Exception occurred (SIGABRT).
System.err: =======
System.err: Check the 'adb logcat' for additional information about the error.
System.err: =======
System.err:
System.err:
System.err: StackTrace:
System.err: TNSCanvasRenderingContext2D.stroke(file: node_modules\nativescript-canvas-plugin\TNSCanvasRenderingContext2D.android.js:567:25)
System.err:     at loaded(file: app\components\FranceMap.vue:33:0)
System.err:     at invokeWithErrorHandling(file: node_modules\nativescript-vue\dist\index.js:1863:25)
System.err:     at invoker(file: node_modules\nativescript-vue\dist\index.js:2527:13)
System.err:     at Observable.notify(file: node_modules\@nativescript\core\data\observable\observable.js:110:22)
System.err:     at TNSCanvasBase._readyEvent(file: node_modules\nativescript-canvas-plugin\canvas-plugin.common.js:117:13)
System.err:     at contextReady(file: node_modules\nativescript-canvas-plugin\TNSCanvas.android.js:48:26)
System.err:     at com.tns.Runtime.callJSMethodNative(Native Method)
System.err:     at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1286)
System.err:     at com.tns.Runtime.callJSMethodImpl(Runtime.java:1173)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1160)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1138)
System.err:     at com.tns.Runtime.callJSMethod(Runtime.java:1134)
System.err:     at com.tns.gen.com.github.triniwiz.canvas.CanvasView_Listener.contextReady(CanvasView_Listener.java:18)
System.err:     at com.github.triniwiz.canvas.CanvasView$5.run(CanvasView.java:394)
System.err:     at android.os.Handler.handleCallback(Handler.java:883)
System.err:     at android.os.Handler.dispatchMessage(Handler.java:100)
System.err:     at android.os.Looper.loop(Looper.java:214)
System.err:     at android.app.ActivityThread.main(ActivityThread.java:7356)
System.err:     at java.lang.reflect.Method.invoke(Native Method)
System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491)
System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Maybe you'd like me to open a new issue as this does not concern Canvg?

triniwiz commented 4 years ago

Ok just noticed I forgot to initialize an set the internal native instance so a quick work around should be as follows

// Android
declare var com;
const instance  = new com.github.triniwiz.canvas.CanvasPath2D(thePathString);
const  p = new TNSPath2D(instance);
// iOS
declare var CanvasPath2D;
const instance  = CanvasPath2D.alloc().initWithData(thePathString);
const  p = new TNSPath2D(instance);
sebj54 commented 4 years ago

It totally does the trick, thanks again!

But there seems to have a bug with fillStyle, I only have the stroke drawn with this code:

const canvas = object
const ctx = canvas.getContext('2d')

const instance = new com.github.triniwiz.canvas.CanvasPath2D('M10 10 h 80 v 80 h -80 Z')
const p = new TNSPath2D(instance)

ctx.fillStyle = 'blue'
ctx.strokeStyle = 'red'
ctx.stroke(p)
ctx.fill(p)
triniwiz commented 4 years ago

for fill can you try adding 'nonzero' after the path 

ctx.fill(p,'nonzero')

On Wednesday, May 27, 2020, 7:29 AM, Sébastien JEAN notifications@github.com wrote:

It totally does the trick, thanks again!

But there seems to have a bug with fillStyle, I only have the stroke drawn with this code: const canvas = object const ctx = canvas.getContext('2d')

const instance = new com.github.triniwiz.canvas.CanvasPath2D('M10 10 h 80 v 80 h -80 Z') const p = new TNSPath2D(instance)

ctx.fillStyle = 'blue' ctx.strokeStyle = 'red' ctx.stroke(p) ctx.fill(p) — You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub, or unsubscribe.

sebj54 commented 4 years ago

Once again, it works now! 👌

Two last questions if you permit:

triniwiz commented 4 years ago

1. You can try fillRect it will use with whatever color is in the fillStyle2. Atm with {N} if you try the width/height it returns whatever value was set for the width and height so for e.g the default is auto, 100% would return a length object {value:1,unit:'%'} , a number would be dips and you need px (number * screenScale) , so there if you want to go by the screen size check the platforms module you can use the screenPixels or you can use the canvas object to get the measuredWidth()/measuredHeight() they are the canvas view dimensions in pixels.... another thing you can do is multiple your coordinates by the screenScale 

On Wednesday, May 27, 2020, 7:42 AM, Sébastien JEAN notifications@github.com wrote:

Once again, it works now! 👌

Two last questions if you permit:

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub, or unsubscribe.

sebj54 commented 4 years ago

Thank you very much for your time, I'll try your suggestions for these problems!

Actually, I'm trying to make it work with SVG paths. As far as I can see, it works almost perfectly. The problem I'm facing now is that I can't draw a path containing an arc (with an a in the d attribute of a path). The app "crashes" and never restarts, it's stuck on the splashscreen.

Here is a buggy path:

M492.834 114.952l-3.278-2.609-4.907-.569-4.412-2.212-2.864 1.713-1.483-1.671h-2.263l-3.086.849.019-.028-.665.207-.186.05-.005.008-.07.022-1.222-1.762-3.938-2.4-1.438-2.256-4.974.435-2.742 2.525-6.413.182-1.83-1.279a7.615 7.615 0 00-2.021-2.472 1.674 1.674 0 00-.153-.076c-.038-.019-.092-.032-.125-.048l-.175-.036v.3l-.1-.3a7.973 7.973 0 01-2.755-1.118l-.13-.077-3.059 1.289-.188 2.288-2.86.353-1.932-3.65-1.062-.376v-2.711l-2.758-1.194-.188-4.627-2.051-2.027-4.174-2.029-2.16-.028-.6.407h-1.766l-2.729-2.36-3.155.2-2.42 2.038-.568.9h-3.018l-1.155-1.191h-.349 0-2.776l-3.53-3.917h-4.75l-2.35 2.167-3.322.189-1.147 1.187h-.4 0-.415l-.749-3.578-1.7-1.7-.773-.107v-.005l-1.646-.255-.763-3.824-1.723-1.311-5.362-.578-.938-2.458-1.862-1.214-6.137-.8-.343-4.13.771-.772v-2.045l-3.075-1.944.521-1.914.862-2.143-1.28-1.106 2-1.807v-3.826l-.982-.71h-3.189l-2.021 3-1.836 1.871v4.07l-2.178 1.454-4.264 1.374-2.188.9-2.688-2.115h-4.08l-.585 3.828 1.686 3.2-1.666 1.491-.2 3.163.942 1.529-.7 2.1-2.989 1.6v2.478l-3.646.766-.744 1.967 2.58 1.389-.717 2.5-.6 2.39.136 5.215h.005l.044 1.28-1.019.275-3.334-2.176-2.719 1.163.383 1.823h-3.85l-3.888 2.9v5.579l2.775 1.825.572 1.286-4.277.358-.688 2.193 1.688 1.119-.564.867-1.907.852.507 1.819h2.606l.728 1-1.57 1.066-1.555 4.08-2.927 1.39-1.006 2.168-1.062 1.3.2 1.1-1.507.967-.456 3.057 1.631 1.008.726 2.713-.981 1.775.737 1.709 2.8-.18v.4h-.006v.641l-2.7 1.149-.2 2.446-1.316 1.716-.844 4.06-.459 3.457 1.436 1.176h2.32l4.877 5.1-.6 5.324 3.842 2.964 1.926-1.348 2.892 3.449.375 3.53 2.172 2.924 1.044 2.329 8.075.421 3.716-1.878 1.09 2.04 1.746.239 1.016-2.194 6.253-.181 2.8-1.486.392-2.432h5.323l1.325.748v-.008l1.692.951 3.431 3.675 4.352 5.878-2.6 2.8 1.917 1.3.193 3.474 3.229-.191.771 1.541 2.6.209 1.6-.9 2.938 3.686.488 1.165 4.687-1.062.78-1.9.3.053v-2.132l2.445-1.05 3.121 1.192 2.99-1.213h1.949l.621-4.089 1.271-1.528-2.062-.222-.146-1.839 2.67-.585.186-1.513h2.783v-2.633l2.242-.816-.611-1.622.542-.344 1.442-.875-.752-1.161.487-.3 1.354 1.579 2.271-1.594.569-1.862 3.373-.545.771.606-.188 2.164 2.76 2.115 1.77-.213 1.731-1.367h3.854l2.938 3.322h1.188l1.748-1.086.216-1.143 1.271-.642 1.571 1.042 1.727 1.944 6.189 3.3.021.014.854 1.67 3.2.193 3.4 2.652.505 1.207-.179 2.214-.983 1.818.438 2.745 2.78-.412.52 1.9 1.032 4.44 2.166-.354-.356 1.879 1.6 1.38 7.438-.195 3.9-3.092.188-4.367 2.062-2.655-2.694-3.1-1.257-2.935 1.519-2.074v-4.959l.943-2.3.021-3.938 1.812-2.634-2.007-2.825-.168-5.073h.007l-.021-.462-.007-.208h0l-.021-.356 5.061-9.923.04-.08-.6-5.7 2.338-7.649.582-6.539 5.075-3.707v-2.4l1.814-2.372h1.531l1.938-1.945-.383-3.394 1.667-4.479 3.189-.695z

The problem are these chunks: a7.615 7.615 0 00-2.021-2.472 1.674 1.674 0 00-.153-.076, a7.973 7.973 0 01-2.755-1.118. If I remove these chunks from path string, path drawn is distorded but the app does not crash.

triniwiz commented 4 years ago

Can you. share a screenshot of the distorted drawn path, I might have an idea of what is causing it.

sebj54 commented 4 years ago

I could but don't think it is necessary. The path is distorted only because I removed an arc from it.