Skip to content

SVG support on Windows? #1211

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

Open
nrkn opened this issue Aug 2, 2018 · 13 comments
Open

SVG support on Windows? #1211

nrkn opened this issue Aug 2, 2018 · 13 comments

Comments

@nrkn
Copy link

nrkn commented Aug 2, 2018

Glad to see this PR adding SVG landed, but it doesn't appear to work on Windows when using a standard npm install canvas

So I looked at the binding.gyp and saw options for windows and that librsvg was false by default, so tried node-gyp rebuild --with_rsvg=true but it complains that it's missing headers etc. for librsvg:

fatal error C1083: Cannot open include file: 'librsvg/rsvg.h': No such file or directory

I found the librsvg files built for windows with dlls, src and headers etc on the same ftp server as gtk but not sure where to put them? Tried just copying them into c:\gtk at the appropriate places but rebuild still failing

Also tried putting them in c:\librsvg, I'm not a C++ dev though so really just guessing and flailing in the dark here, any ideas?

@zbjornson
Copy link
Collaborator

#1206 is needed for it to work on Windows, and no release has been made since that was merged. Can you try installing from GitHub? (npm i Automattic/node-canvas#master)

@LinusU
Copy link
Collaborator

LinusU commented Aug 2, 2018

Sorry, I haven't cut a release in quite a while.

Did it now, please try with 2.0.0-alpha.13 🎉

@nrkn
Copy link
Author

nrkn commented Aug 2, 2018

OK - installed latest, still no luck with the standard install of 2.0.0-alpha.13, so tried node-gyp rebuild with rsvg flag again and still gives 'librsvg/rsvg.h': No such file or directory - any ideas? Has someone else tried and confirmed working? I'm using all 64bit, Node 10.7.0, if that makes a difference. The librsvg files appear to be present under gtk.

@nrkn
Copy link
Author

nrkn commented Aug 2, 2018

Also you appear to have published the 2.0.0-alpha.13 to npm as canvas?

I just tried to install it for an unrelated project that uses the old 1.x api using just npm install canvas and got the alpha branch - I changed it to use the specific version so no problem but thought you may like to know, suspect you didn't mean to do that?

@LinusU
Copy link
Collaborator

LinusU commented Aug 3, 2018

Also you appear to have published the 2.0.0-alpha.13 to npm as canvas?

oh no, not again 😅

fixed 👌

@zbjornson
Copy link
Collaborator

@nrkn I got close to getting it to work with only pre-compiled binaries on the GNOME FTP server, but I can't find a ready-made librsvg-2-2.lib to link against. In #1123 it sounds like @timknip maybe built RSVG with mingw, @Khorynthium perhaps as well. That's probably the only viable way forward -- hopefully we can get it in prebuilds though.

@khkassem
Copy link

I'm trying to use canvas with svg support in Electron, I can't use the prebuilt (because of Electron js), so npm install is building the library.
It's working without problems without svg support but when I add

--with_rsvg=true

I get the following error :

canvas\src\Image.h(28): fatal error C1083: Cannot open include file: 'librsvg/rsvg.h'

the GTK bundle i have http://ftp.gnome.org/pub/GNOME/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip didn't contain any librsvg file, I tried to download a librsvg lib but without success

Where can i find a complete GTK binaries for win32 so I can build the node canvas with svg support??

@khkassem
Copy link

I tried to download librsvg for win32, I get node_canvas to compile (I generated the .lib from the .dll) but at run time I am getting an error :
Unhandled rejection Error: The specified procedure could not be found. node_modules\canvas\build\Release\canvas.node

So the librsvg I get is not the one used in the node_canvas library

@Sakari369
Copy link
Contributor

Sakari369 commented Aug 17, 2021

Any update on this ? @khkassem @zbjornson any information on how to build node-canvas on Windows with svg support ? Or is there a prebuilt binary perhaps ?

I am developing an Electron application that exports PDF and SVG files that can have SVG embedded documents inside a canvas renderer. Without SVG support I cannot export the documents that have embedded SVG.

On macOS I can succesfully recompile the library with SVG support, but I have not yet looked at how to do it in Windows, just wondering if there are some easy guides how to do it. Thanks!

@Sakari369
Copy link
Contributor

Sakari369 commented Aug 18, 2021

Okay I got the library building.

Steps I had to do:

Download all the dependency libraries from https://download.gnome.org/binaries/win64/

Extract and copy the .dll dependencies to C:\GTK\bin

Cd to the MSVC tools directory

cd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx64\x64"

Generate a .def file from the librsvg-2-2.dll:

dumpbin /EXPORTS C:\GTK\bin\librsvg-2-2.dll > C:\GTK\bin\librsvg-2-2.exports

Edit this exports file manually and save to C:\GTK\bin\librsvg-2-2.def to get this:

LIBRARY librsvg-2-2
EXPORTS
_rsvg_acquire_xlink_href_resource
_rsvg_register_types
_rsvg_size_callback
rsvg_css_parse_color
rsvg_error_get_type
rsvg_error_quark
rsvg_handle_close
rsvg_handle_free
rsvg_handle_get_base_uri
rsvg_handle_get_desc
rsvg_handle_get_dimensions
rsvg_handle_get_dimensions_sub
rsvg_handle_get_metadata
rsvg_handle_get_pixbuf
rsvg_handle_get_pixbuf_sub
rsvg_handle_get_position_sub
rsvg_handle_get_title
rsvg_handle_get_type
rsvg_handle_has_sub
rsvg_handle_new
rsvg_handle_new_from_data
rsvg_handle_new_from_file
rsvg_handle_render_cairo
rsvg_handle_render_cairo_sub
rsvg_handle_set_base_uri
rsvg_handle_set_dpi
rsvg_handle_set_dpi_x_y
rsvg_handle_set_size_callback
rsvg_handle_write
rsvg_init
rsvg_pixbuf_from_data_with_size_data
rsvg_pixbuf_from_file
rsvg_pixbuf_from_file_at_max_size
rsvg_pixbuf_from_file_at_size
rsvg_pixbuf_from_file_at_zoom
rsvg_pixbuf_from_file_at_zoom_with_max
rsvg_set_default_dpi
rsvg_set_default_dpi_x_y
rsvg_term

Generate the librsvg-2-2.lib file from the .def file:

lib.exe /def:C:\GTK\bin\librsvg-2-2.def /machine:x64 /out:C:\GTK\lib\librsvg-2-2.lib

Okay now all the dependencies should be met. Then I edited the binding.gyp file (set with_rsvg to true):

  'conditions': [
    ['OS=="win"', {
      'variables': {
        'GTK_Root%': 'C:/GTK',  # Set the location of GTK all-in-one bundle
        'with_jpeg%': 'false',
        'with_gif%': 'false',
        'with_rsvg%': 'true',
        'variables': { # Nest jpeg_root to evaluate it before with_jpeg
          'jpeg_root%': '<!(node ./util/win_jpeg_lookup)'
        },
        'jpeg_root%': '<(jpeg_root)', # Take value of nested variable
        'conditions': [
          ['jpeg_root==""', {
            'with_jpeg%': 'false'
          }, {
            'with_jpeg%': 'false'
          }]
        ]
      }
    }, {  # 'OS!="win"'

And added the include_dirs to the windows section:

        ['with_rsvg=="true"', {
          'defines': [
            'HAVE_RSVG'
          ],
          'conditions': [
            ['OS=="win"', {
              'copies': [{
                'destination': '<(PRODUCT_DIR)',
                'files': [
                  '<(GTK_Root)/bin/librsvg-2-2.dll',
                  '<(GTK_Root)/bin/libgdk_pixbuf-2.0-0.dll',
                  '<(GTK_Root)/bin/libgio-2.0-0.dll',
                  '<(GTK_Root)/bin/libcroco-0.6-3.dll',
                  '<(GTK_Root)/bin/libgsf-1-114.dll',
                  '<(GTK_Root)/bin/libxml2-2.dll'
                ]
              }],
              'include_dirs': [
                  '<(GTK_Root)/include/',
                  '<(GTK_Root)/include/gdk-pixbuf-2.0',
                  '<(GTK_Root)/include/gtk-2.0',
                  '<(GTK_Root)/include/glib-2.0',
              ],
              'libraries': [
                '-l<(GTK_Root)/lib/librsvg-2-2.lib'
              ]
            }, {

Had to remove the LIBRSVG_VERSION definition from the init.cc also:

...
#ifdef HAVE_GIF
#ifndef GIF_LIB_VERSION
  char gif_version[10];
  snprintf(gif_version, 10, "%d.%d.%d", GIFLIB_MAJOR, GIFLIB_MINOR, GIFLIB_RELEASE);
  Nan::Set(target, Nan::New<String>("gifVersion").ToLocalChecked(), Nan::New<String>(gif_version).ToLocalChecked()).Check();
#else
  Nan::Set(target, Nan::New<String>("gifVersion").ToLocalChecked(), Nan::New<String>(GIF_LIB_VERSION).ToLocalChecked()).Check();
#endif
#endif

#ifdef HAVE_RSVG
  Nan::Set(target, Nan::New<String>("rsvgVersion").ToLocalChecked(), Nan::New<String>("2.2").ToLocalChecked()).Check();
#endif

  char freetype_version[10];
  snprintf(freetype_version, 10, "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
  Nan::Set(target, Nan::New<String>("freetypeVersion").ToLocalChecked(), Nan::New<String>(freetype_version).ToLocalChecked()).Check();
}

NODE_MODULE(canvas, init);

I just replaced it with "2.2" as you can see. Probably this would have to be set by package-config and the build has not been tested on Windows ? Don't know, just guessing.

After this I could build the canvas succesfully with

npx electron-rebuild -f canvas

From my Electron project root directory.
The resulted canvas.node is being loaded succesfully by my Electron project, but alas, when I try to export a document with embedded SVG in it, I get the error:

"error while reading from input stream"

And also I see these messages in my electron debug log:


(electron.exe:3260): GLib-GObject-CRITICAL **: gtype.c:2710: You forgot to call g_type_init()

(electron.exe:3260): GLib-GObject-CRITICAL **: gtype.c:2710: You forgot to call g_type_init()

(electron.exe:3260): GLib-GObject-CRITICAL **: g_object_new: assertion `G_TYPE_IS_OBJECT (object_type)' failed

Now, if I export a document without embedded SVG elements in it through node-canvas to a PDF or SVG file, and after this succeeds, running the export again with embedded SVG, will not give the "error while reading from input stream" error and will not show the GLib errors.

But the resulting PDF from my app will be rendered without the SVG elements in it, where they should be in the exported PDF they will be just empty. So my guess is if I try to export directly with elements with SVG in them, the node-canvas library fails to initialize properly at all, but when I do a initial run without the SVG elements, the library is initialized properly and after that I can export the SVG elements, but for some reason it fails to read the SVG elements.

On mac the elements are correctly rasterized as images in the resulting PDF or SVG. Just to clarify, I have an application where you can load SVG images to be rendered in a canvas, and then I have support for exporting that canvas to a PDF/SVG via node-canvas.

Any idea what might cause this ? Works perfectly fine on macOS like I said .. not sure I want to go digging any deeper in this :P But let's see, I will at least take a look at the sources if I can figure it out ..

EDIT: Ok looking at some reports found online, my best guess currently is that some of the dependency libraries or glib or something has been built against different version, at least the g_type_init() call seemed to be deprecated in some newer versions of glib or something.

@Sakari369
Copy link
Contributor

It seems the librsvg win64 .dll file that can be downloaded from gnome.org is the old version, not the newer one built with Rust. Probably this is causing the library not to work and causing the g_type_init() calls also being missing.

No idea where to find a build of the Rust -version for win64 .dll build. Only builds I can see are in msys2, but those are built as .a and .dll.a files, not as dll .. damn. Any info on where to find newer builds for librsvg2 (the rust version, after 2017 developed ? ) would be dandy.

@Sakari369
Copy link
Contributor

Okay just another update, I got it building using the MSYS2 build instructions and hacking away. I wish the instructions on the WIndows build would just point to this page by default, now I wasted couple of days trying to get the normal build process working, but I can see that for most cases this could be sufficient, but if you want to enable SVG support then the MSYS2 build process is the only way to go, and it requires manual hacking to get there.

I will document later on what I did get it compiling and working.

@yisibl
Copy link

yisibl commented Oct 28, 2021

Consider using skr-canvas, no additional dependencies to install, no node-gyp, and native support for SVG.
https://github.com/Brooooooklyn/canvas#example

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants