godot icon indicating copy to clipboard operation
godot copied to clipboard

ImageLoaderSVG: Couldn't set target on ThorVG canvas.

Open Crystalwarrior opened this issue 2 years ago • 5 comments

Godot version

4.0.beta16

System information

Windows 10, Vulkan, NVIDIA GeForce GTX 1050

Issue description

Importing SVG's from Kenney.NL fails with the following message:

  ImageLoaderSVG: Couldn't set target on ThorVG canvas.
  core/io/image_loader.cpp:101 - Error loading image: res://assets/icons/skull.svg
  editor/editor_file_system.cpp:2004 - Error importing 'res://assets/icons/skull.svg'.

Steps to reproduce

  1. Grab icons from Kenney.NL here: https://www.kenney.nl/assets/board-game-icons
  2. Try importing an .svg from it
  3. The process will fail: image

Minimal reproduction project

N/A

Crystalwarrior avatar Jan 31 '23 22:01 Crystalwarrior

kenney_boardgameicons.zip

Image called skull.

skull

@mgrudzinska Here's a test case if you're interested.

image

fire avatar Feb 01 '23 06:02 fire

@fire thanks for info :)

I see that the problem is that there's no viewbox attrib. We have pr solving this, but it has to be rebase/updated. Sorry for that. I'll take care of that today.

But still these svgs are a bit wired, because they are shifted and only part of the picture is visible - like the skull.svg you sent, that's not the whole skull... is that what you'd expect? I checked some other svg viewers and none of them showed the whole skull.

mgrudzinska avatar Feb 01 '23 13:02 mgrudzinska

I confirm that firefox shows the skull offset too.

fire avatar Feb 02 '23 00:02 fire

:timer_clock: :timer_clock: :timer_clock: E.g. all the vector files from https://www.kenney.nl/assets/prototype-textures have the same issue. A quick »emergency« solution is to open the images in Inkscape, press sh+ctrl+r (resize page to selection) and overwrite the svg...

grafik

krita-menu

capnm avatar Mar 08 '23 18:03 capnm

@capnm I'll try to make the pr ready asap - it is after rev and waiting for some changes.

mgrudzinska avatar Mar 09 '23 01:03 mgrudzinska

https://github.com/thorvg/thorvg/pull/1318

@capnm please check the results - without the viewBox/viewPort info only a part of the pict is drawn. I've checked other svg viewers and haven't find any, that would draw the whole pict. Please comment on that.

mgrudzinska avatar Mar 10 '23 23:03 mgrudzinska

@capnm please check the results - without the viewBox/viewPort info only a part of the pict is drawn. I've checked other svg viewers and haven't find any, that would draw the whole pict. Please comment on that.

@mgrudzinska Edit, edit, edit :) I think showing only the part is correct from the standard perspective if the image already has the width/height atribute. It could be an image bug, but you can use it on purpose.

e.g. in your PR test images:

test1.svg
<svg width="400" height="200" viewBox="0 0 200 ">
      <linearGradient id="Gradient1" x1="0" x2="30%" y1="0" y2="40" gradientUnits="userSpaceOnUse">
      <stop offset="0%" stop-color="red" />
      <stop offset="50%" stop-color="black" stop-opacity="0" />
      <stop offset="100%" stop-color="green" />
    </linearGradient>

  <path fill="blue" d="M 0 0 h 400 v 400 z" opacity="0.1"/>
  <path fill="green" d="M 0 400  h 400 v -400 z"/>
    <path stroke="none" fill="url(#Gradient1)" d="M0 0 L100 0 100 100 0 100 0 0"/>
    <path fill="none" stroke="#00ff00" stroke-width="1" d="M0 0 L 100 100"/>
</svg>

When I recalculate the image width/height, it then brings in the app the access to hidden parts of the image. Maybe the lib could have (later) an option for this, Gogot could then have it in the export settings.

I built Godot together with thorvg tip and your PR, the Kenney images are now recognized,

Screenshot

grafik

but the clipping makes it unusable.

texture_01.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs/>
  <g>
    <path stroke="none" fill="#333335" d="M0 0 L1024 0 1024 1024 0 1024 0 0"/>
    <path stroke="none" fill="#FFFFFF" d="M1023 1 L513 1 513 511 1023 511 1023 1 M1 1 L1 511 511 511 511 1 1 1 M1 1023 L511 1023 511 513 1 513 1 1023 M0 0 L1024 0 1024 1024 0 1024 0 0 M1023 1023 L1023 513.05 513 513 513 1023 1023 1023"/>
    <path stroke="none" fill="#FFFFFF" fill-opacity="0.2" d="M257 1024 L256 1024 256 769 0 769 0 768 256 768 256 257 0 257 0 256 256 256 256 0 257 0 257 256 768 256 768 0 769 0 769 256 1024 256 1024 257 769 257 769 768 1024 768 1024 769 769 769 769 1024 768 1024 768 769 257 769 257 1024 M257 768 L768 768 768 257 257 257 257 768"/>
...
    <path fill="none" stroke="#FFFFFF" stroke-width="2" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="3" d="M32 76 L200 76"/>
  </g>
</svg>

grafik

Gnome Image viewer : grafik

capnm avatar Mar 11 '23 08:03 capnm

@capnm I've updated the pr, but it's still under rev

mgrudzinska avatar Mar 13 '23 00:03 mgrudzinska

@mgrudzinska I haven't had a chance to read through the code yet, had only a quick look at the SVG specs and Godot results with the last pr. The spec is, as you said, very css specific. Here, he also suggests, missing SVG size attributes should mean auto, so the whole image here, Godot now shows only 1x1 px image. Edit: or after a new copy randomly 1001x1001 px (+1px)

https://docs.google.com/presentation/d/1POUiroOBbLmXYlQKf0pIR8zVkHWH9jRVN-w8A4aNsIk/edit#slide=id.g1e19b0d66_285

prototype_textures_orig_vec.zip cc0

capnm avatar Mar 13 '23 08:03 capnm

@mgrudzinska I haven't had a chance to read through the code yet, had only a quick look at the SVG specs and Godot results with the last pr. The spec is, as you said, very css specific. Here, he also suggests, missing SVG size attributes should mean auto, so the whole image here, Godot now shows only 1x1 px image.

I missed this, I'll solve this asap and let you know

mgrudzinska avatar Mar 13 '23 22:03 mgrudzinska

Do you or someone know what should be done from the Godot side and/or what the intent is for ThorVG generated image, with zero svg or viewBox width/height attributes? If I'm reading the debugger backtraces correctly, Godot is currently getting an image with a width or height of zero, which results in error. In html/css context, which we don't have here, the intent is to not render the image. I think ThorVG should provide a transparent area in the image size or also as by auto the whole image in this case. :thinking:

https://www.w3.org/TR/SVG2/coords.html#ViewBoxAttribute tx_svg.zip

capnm avatar Mar 14 '23 04:03 capnm

@capnm I didn't take a look in a godot code. the problem with incorrect size should be solved in the last commit. these are two separate cases:

  • svgs with viewbox="1 2 300 0" (height=0) - nothing should be rendered - as I understand this is handled in godot correctly, right?
  • svgs with width="0" or height="0" - there is a problem? If so, I'd like to handel the latter in the same way as the former - although it's not exactly the svg standard - I'll consult this with guys, just need to know whether it solves the problem

mgrudzinska avatar Mar 15 '23 00:03 mgrudzinska

@capnm I didn't take a look in a godot code. the problem with incorrect size should be solved in the last commit.

The current outcomes in the case of an empty svg tag -> image size + 1px:

Screenshot

Bildschirmfoto von 2023-03-15 06-40-33

capnm avatar Mar 15 '23 08:03 capnm

these are two separate cases:

* svgs with `viewbox="1 2 300 0"` (height=0) - nothing should be rendered - as I understand this is handled in godot correctly, right?

* svgs with `width="0"` or `height="0"` - there is a problem?
  If so, I'd like to handel the latter in the same way as the former - although it's not exactly the svg standard - I'll consult this with guys, just need to know whether it solves the problem

I'm just considering using Godot in our classes, so I'm looking at the errors now more from a philosophical side :)

E.g. Gnome image viewer shows by 0's in svg width or height and by viewbox(0 0 0 0) without svg's width and height - a 1x1 px image. In other cases, the full sized image.

I assume that Godot doesn't have access to the image data or the full size values. Guess: he is trying to create a zero size symbol here, giving out lots of internal errors and marking the image as broken. With zeros in the size, 1 px placeholder (+ documentation) could fix the issue... :thinking:

@fire ?

Screenshots

Bildschirmfoto von 2023-03-15 05-38-59

grafik

null.zip

capnm avatar Mar 15 '23 08:03 capnm

I think defaulting to a 1x1 image is better usability than fail looping, but I have not thought through the consequences.

fire avatar Mar 15 '23 16:03 fire

The other option could be to remove everything from the SVG tag (this case works now, @mgrudzinska is almost there!) and render an equally sized transparent image (this would represent something similar to the "do not render" in the SVG standard) or the provided image (optionally?).

capnm avatar Mar 15 '23 17:03 capnm

I'm quite sure, that for the t3.svg (viewBox="0 0 200 0") for the latest version of the corresponding pr (after changes pushed yesterday) you should get ERR_INVALID_DATA from the picture->load api. Let us discuss whether it's the best approach. we could render an empty scene and then both apis result in success.

for t8.svg (width="0") setting the canvas target won't return success, but you know the width and height values so you can set whatever values you want if some of them is zero. both as before - let us discuss this, because maybe we should handle this case exactly like the above...

mgrudzinska avatar Mar 16 '23 00:03 mgrudzinska

@fire You wrote the bindings, please correct me if I got it wrong. The debugger has troubles stepping in the code (godot changes thorvg's pointers to internal api or multithreading issues).

1 Godot looks at the file extensions, loads the svg data itself and knows nothing else of the contents. 2 Sends it to thorvg's sw-renderer. 3 Gets the image data, width and height. 4 Attempts to change the color in the svg file and sends it to thorvg to create a file icon.

In cases the svg file contais swg's or viewBox's width or height (or both) 0, it gets zero width or height (or no success?) from the thorvg api. At this point we don't know the image size. The question is what to do next.

capnm avatar Mar 16 '23 04:03 capnm

Is zero size a failure case of import. It’s technically valid to zero width height image but I thought a zero area image is invalid.

fire avatar Mar 16 '23 05:03 fire

In web context it's used to currently hide or not render the image.

capnm avatar Mar 16 '23 05:03 capnm

@mgrudzinska quick test for latest godot tip + pr1318 godot_pr1318_diff.zip

Issues: svg without viewport/viewbox , <svg width="0"> (t8) and viewbox without viewport that contains 0s – get now marked as broken. Errors:

ERROR: ImageLoaderSVG: Couldn't set target on ThorVG canvas.
   at: create_image_from_utf8_buffer (modules/svg/image_loader_svg.cpp:103)
ERROR: Error loading image: res://prototype_textures_orig_vec/texture_02.svg
   at: load_image (core/io/image_loader.cpp:101)
ERROR: Error importing 'res://prototype_textures_orig_vec/texture_02.svg'.
   at: _reimport_file (editor/editor_file_system.cpp:2031)
ERROR: Error loading image: res://prototype_textures_orig_vec/texture_01.svg
   at: load_image (core/io/image_loader.cpp:101)
ERROR: Error importing 'res://prototype_textures_orig_vec/texture_01.svg'.
   at: _reimport_file (editor/editor_file_system.cpp:2031)
Screenshots

230316

vp_vb_tests.zip

capnm avatar Mar 16 '23 13:03 capnm

omg it's a huge diff :D but I don't see what did you change in godot in image_loader_svg.cpp. could you share?

mgrudzinska avatar Mar 16 '23 16:03 mgrudzinska

I'll be available in a few hours and i run it myself

mgrudzinska avatar Mar 16 '23 16:03 mgrudzinska

You were very hardworking :D image_loader_svg.cpp hasn't been changed since 2022-12. You can clone the godot tip and run git apply pr1318.diff

capnm avatar Mar 16 '23 17:03 capnm

  1. so, the viewbox error is now solved in #1318
  2. all svgs with the width or height value set to zero - in my opinion you have to handle the result in the image_loader_svg.cpp file. For now you'll get an error msg: ImageLoaderSVG: Couldn't set target on ThorVG canvas. because width and/or height are zero. you can change it to any value you want, like instead of zero use 1. it will be the canvas, but still nothing will be drawn, so maybe this is the sollution

I didn;t manage to install everything to run the code on my computer... butt the above should be helpfull

mgrudzinska avatar Mar 17 '23 00:03 mgrudzinska

Here are the docs what you need for any OS, may help: https://docs.godotengine.org/en/latest/contributing/development/compiling/index.html I can take a look at it over the weekend.

capnm avatar Mar 17 '23 05:03 capnm

@mgrudzinska After https://github.com/godotengine/godot/pull/75034 the svg import is now error free for all images we get with a 0 size!

The only small problem I can see is the case without viewport and viewbox, all images width/height is 1 px larger than it should be. Maybe some float rounding problems...

Details
<svg>
  <linearGradient id="Gradient1" x1="0" x2="30%" y1="0" y2="40" gradientUnits="userSpaceOnUse">
    <stop offset="0%" stop-color="red" />
    <stop offset="50%" stop-color="black" stop-opacity="0" />
    <stop offset="100%" stop-color="green" />
  </linearGradient>

  <path fill="blue" d="M 0 0 h 400 v 400 z" opacity="0.3"/>
  <path fill="green" d="M 0 400  h 400 v -400 z"/>
  <path stroke="none" fill="url(#Gradient1)" d="M0 0 L100 0 100 100 0 100 0 0"/>
  <path fill="none" stroke="#00ff00" stroke-width="1" d="M0 0 L 100 100"/>
</svg>

grafik grafik

https://github.com/capnm/godot4/tree/update_thorvg_pr1318

capnm avatar Mar 17 '23 18:03 capnm

@capnm good catch! I noticed this but I wanted to solve this after we agree with https://github.com/thorvg/thorvg/pull/1318

After https://github.com/godotengine/godot/pull/75034 the svg import is now error free for all images we get with a 0 size!

I hope that I've misunderstood - all of the images have a size equal 0? even if it shouldn;t be?

mgrudzinska avatar Mar 20 '23 23:03 mgrudzinska

@mgrudzinska

I hope that I've misunderstood - all of the images have a size equal 0? even if it shouldn;t be?

Most images show a picture :+1: I didn't examine if they are correct cropped. The 0 size is no longer a bug after this patch. It renders 1 pixel images in this case.

From all test images, I posted:

The 0 size cases are: <svg width="0"> (the Gnome Image Viewer: whole picture) -> t8.svg <svg viewBox="0 0 0 200"> (giv: 1 pixel) <svg viewBox="0 0 200 0"> (giv: 1 pixel) <svg viewBox="0 0 0 0"> (giv: 1 pixel) <svg width="0" height="0" viewBox="0 0 200 200"> (giv: 1 pixel) <svg width="0" height="200" viewBox="0 0 20 20"> (giv: 1 pixel) same: <svg width="0" height="200" viewBox="0 0 200 200"> <svg width="200" height="0" viewBox="0 0 20 20">

This renders a transparent 200x200 sized images (giv: 200x200 cropped picture): <svg width="200" height="200" viewBox="0 0 0 0"> <svg width="200" height="200" viewBox="0 0 0 200"> <svg width="200" height="200" viewBox="0 0 200 0">

capnm avatar Mar 21 '23 03:03 capnm

great, so I'll take care now of this one extra pixel

mgrudzinska avatar Mar 21 '23 18:03 mgrudzinska