|
#1 | AlbrechtS 16:25 Oct 19, 2016 |
| Inspired by the discussion on STR #3341 I could not resist to test if and how FLTK might get support for SVG images, thanks to Chris (OP of STR #3341). http://www.fltk.org/str.php?L3341 See comment #9.
I wrote a short test program to display an SVG image in FLTK with the mentioned nanosvg library. https://github.com/memononen/nanosvg
The usage is simple: include two header files (together ~115 KB) in a C file to get the entire library implementation like this:
$ cat nanosvg.c #include <stdio.h> #include <string.h> #include <math.h>
#define NANOSVG_ALL_COLOR_KEYWORDS // Include full list of color keywords. #define NANOSVG_IMPLEMENTATION // Expands implementation #include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION // Expands implementation #include "nanosvgrast.h"
That's all for the nanosvg library.
The demo program uses "nanosvg.h" to read the svg image file and "nanosvgrast.h" to rasterize the svg data into a memory buffer suitable for Fl_RGB_Image. It's really that simple.
Full source code attached, see svg.cxx. | |
|
#2 | AlbrechtS 16:31 Oct 19, 2016 |
| Attached screenshot fltk_svg_image.png shows the program in action. Image file tiger.svg will also be uploaded shortly.
Note: reading the "docs" and writing the demo program took less than 90 minutes, but I did just the minimum to _use_ the nanosvg library. Image scaling and error handling was done to fit the task to create a demo.
I also didn't thoroughly check the license (of the library as well as the attached "Ghostscript tiger" svg image), so we'd need to check if the nanosvg library could be used and bundled with FLTK.
Have fun! | |
|
#3 | AlbrechtS 17:00 Oct 19, 2016 |
| Here is the link to the original image on Wikimedia: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg
Direct link to image: https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg | |
|
#4 | greg.ercolano 14:55 Oct 20, 2016 |
| Sounds good, though I wonder if we can assume the svg files in /usr/share/icons stay within the subset of commands nanosvg supports.
I was unable to get nanosvg on my Sci Linux system because:
1) There's no yum for it 2) I 'git cloned' it, but it needs premake4 (never heard of it) 3) There's no yum for premake or premake4 4) Gave up for now (it's a work day)
Would be interesting to bring it into fltk if we can.. or at least provide it as an external option.
The other SVG libraries I've seen need cairo (or similar) to render correctly, as vector art only really draws well with the presence of antialiased lines, which I don't think FLTK supports unless one links with cairo.
If nanosvg has its own renderer, I'm curious Albrecht: do you have a screenshot of what it looks like rendered in FLTK? I'm curious if it uses antialiased lines.. if so, might be a cheap way to get antialiased line drawing into FLTK..! ;) | |
|
#5 | greg.ercolano 14:57 Oct 20, 2016 |
| Oh, I see you included fltk_svg_image.png
Yeah, that looks pretty good..! The lines look kinda antialiased. | |
|
#6 | AlbrechtS 07:36 Oct 21, 2016 |
| Hi Greg and others,
if you can clone the github repo you're done. Just grab the two header files from the src folder:
- src/nanosvg.h - src/nanosvgrast.h
and put them into the same folder as the test program.
I'm now uploading svg_v2.cxx which has direct download links included and is a standalone FLTK program that just needs the two headers mentioned above in the same folder. Rename to 'svg.cxx' and build with:
$ fltk-config --compile svg.cxx
Enjoy! | |
|
#7 | AlbrechtS 08:03 Oct 21, 2016 |
| Regarding examples and subset the "svg language" nanosvg supports:
I downloaded several test files and also tried lots (maybe 200-300) of the icons included with Ubuntu (there are thousands of them!). I found that very few of the icons didn't render well, but OTOH 'eog' (image display tool) didn't render some of them as well. Most simple icon-type images worked pretty well and fast, but color gradients seemed to be slow when zoomed to 900x900 (default in the demo program).
I also found that some really "complicated" images were displayed well, i.e. w/o visible artefacts/bugs, but I also found an example that didn't render completely correct. Here are the links:
https://en.wikipedia.org/wiki/Great_Seal_of_the_United_States https://upload.wikimedia.org/wikipedia/commons/5/5c/Great_Seal_of_the_United_States_( obverse).svg
However, the (much smaller) reverse side renders well: https://upload.wikimedia.org/wikipedia/commons/4/45/Great_Seal_of_the_United_States_( reverse).svg
Note: the missing part on the right side of the first image (the eagle's wing and foot) seems to be something that is mirrored from the left side which could be the cause. But there is at least one more missing part (below the red and white stripes).
Uploading screenshot: Great_Seal_with_nanosvg.png | |
|
#8 | AlbrechtS 08:14 Oct 21, 2016 |
| Regarding potential inclusion in FLTK:
I used both the image parsing (nsvgParseFromFile() in nanosvg.h) and the image rasterization (nsvgRasterize() in nanosvgrast.h) that converts the parsed svg image data to RGBA image data. The latter is used to build an Fl_RGB_Image.
Since FLTK is a graphics (GUI) library I could imagine to do the second part directly in FLTK, i.e. direct rendering of the parsed svg image data in FLTK (in Fl_SVG_Image::draw()). But for my demo program it seemed much easier to use the rasterizer supplied by nanosvg.
BTW: sizes of other bundled libs compared to nanosvg:
$ du -h fltk/jpeg/ fltk/png fltk/zlib nanosvg/src 1.7M fltk/jpeg/ 2.1M fltk/png 664K fltk/zlib 120K nanosvg/src | |
|
#10 | AlbrechtS 09:07 Oct 21, 2016 |
| Fix broken links in comment #7:
<https://upload.wikimedia.org/wikipedia/commons/4/45/Great_Seal_of_the_United_States_%28reverse%29.svg> <https://upload.wikimedia.org/wikipedia/commons/5/5c/Great_Seal_of_the_United_States_%28obverse%29.svg> | |
|
#11 | manolo 06:33 Oct 24, 2016 |
| Nanosvg is really impressive. But it seems to ignore any text content in svg files. | |
|
#12 | AlbrechtS 08:24 Oct 24, 2016 |
| @Manolo: thanks for taking a look at it.
I think I didn't experience missing text yet. What I saw was white text on a transparent background in some icons, and since the background in svg_v2.cxx was white nothing seemed to be visible, like an empty image.
svg_v3.cxx (uploaded with this post) changes the background to light gray and displays the image file name and dimensions in the title bar. Tested on Linux and Windows so far.
If you still experience missing text, can you please post a simple/small example svg file that exhibits the issue? And - if it's not in the image file's meta data - can you tell us how it was created (if you know it)? | |
|
#13 | AlbrechtS 09:21 Oct 24, 2016 |
| Indeed, I constructed a simple svg file with a 'text' element, and the text is not rendered by nanosvg. :-( See | |
|
#14 | AlbrechtS 09:27 Oct 24, 2016 |
| [continued...] See uploaded file text_00.svg.
Anyway, nanosvg is open source, and the author writes on his Github page:
"NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!" | |
|
#15 | manolo 00:41 Oct 30, 2016 |
| See attached svg_v4.cxx for an essentially complete implementation of a new class : Fl_SVG_Image : public Fl_RGB_Image
This allows full integration of SVG images in fltk with no platform-specific code anywhere and no SVG-specific code at user level. | |
|
#16 | AlbrechtS 04:27 Oct 30, 2016 |
| Manolo, thanks for this great contribution. My goal was to have an Fl_SVG_Image class and to be able to use SVG images as Fl_Shared_Image's once we decide to have SVG image support (with nanosvg or another library) in FLTK. This is a great step forward to this goal. | |
|
#17 | AlbrechtS 04:40 Oct 30, 2016 |
| Regarding text rendering (comments #11-14):
I took a deeper look at the nanosvg code, and it is clear now that 'text' elements are completely ignored by the svg parser. Even if the parser would not ignore the 'text' elements I wouldn't know how to rasterize the text w/o implementing a full text (font) rendering engine in the rasterizer.
The rasterizer implementation appears to be sophisticated (maybe derived from a font rasterizer engine?) and seems to do a good job at anti-aliasing lines, curves, filled areas, and color gradients (linear as well as radial). We can't simply use FLTK's font rendering on top of that, AFAICT, because 'text' elements would need to be fully integrated (they could be occluded by later, maybe partially transparent elements etc.).
OTOH it seems that icons and other svg images may have pre-rendered text included in many (most?) cases anyway. If that was true (comments, anybody?), then we could try w/o 'text' rendering and include nanosvg anyway as an (incomplete) improvement.
That's just a thought so far... | |
|
#18 | AlbrechtS 04:54 Oct 30, 2016 |
| Regarding missing graphics elements in complex images (comment #7 et al.):
FWIW, so far I found out that some of the issues are really caused by the "mirrored" image elements. They are implemented by a 'use' element that refers to a very large image element (the left wing and leg of the eagle).
The original element (left side, id="g6288") starts at line #735 and ends at line #949.
The "used" element (right side) is at line #950:
<use transform="matrix(-1,0,0,1,608.4247,0)" id="use6503" x="0" y="0" width="467.94525" height="573.34161" xlink:href="#g6288"/>
I don't know yet why this doesn't work, but I succeeded to render the right wing and leg by _copying_ the code instead of 'use'ing it (with an additional transformation).
Needs more investigation and maybe a correction in nanosvg... | |
|
#19 | manolo 05:24 Nov 01, 2016 |
| Attached file svg_v5.cxx improves the Fl_SVG_Image class by using less memory for each image. It also allows to tile svg images. | |
|
#20 | ianmacarthur 09:53 Mar 22, 2017 |
| For what it's worth, I've been using an old version of nanosvg (circa 2014 or so I think) to render button faces for a particular task, and it certainly works well for simple things like that.
Regarding comment #17, I have never missed the text support, I just use the svg to render the "face" then draw the button label on top anyway. Works for me, but I accept it's not ideal...
It is small enough a library, and the licensing seems OK, so maybe we can bundle it in?
Initially I thought not, since it is easy enough to use anyway as an external lib, but having a specific FLTK svg capability, I can see that being useful.
We probably would want to include a warning in the docs saying it is not a full svg renderer I think, just to cover the trickier edge cases!
One specific change though: I hacked the rasterizer to allow me to set different scales for x and y. This was to allow me to draw the faces on a range of differently sized buttons from a single svg. Probably not ideal, but very handy in this case. That *might* be a facility we'd like to keep in, even though it is somewhat odd. And the way I did it is less than ideal (though looks fine in practice!) | |
|
#21 | djcj 07:04 Aug 27, 2017 |
| What about optionally enabling support for librsvg2 as an external library? Or maybe trying to dlopen() it and fall back to nanosvg otherwise. | |
|
#22 | ianmacarthur 11:39 Aug 28, 2017 |
| Adding librsvg2 support is possibly feasible, though it is an additional dependency we (ideally) would not want.
If folks really need better SVG support, then it's not that hard to use it as an external lib themselves, much like nay other support lib.
As for dlopening it as a fallback option, that might be trickier to actually hook together; nanosvg is a compile time option only (there is no lib, it's all in the header files) so making that "congruent" with dlopening a "real" external lib might take a bit of fiddling... and nanosvg would always have to be built into fltk in that case anyway, just in case librsvg2 wasn't found, I guess.
Hmm, don't know. | |
|
#23 | manolo 09:25 Aug 30, 2017 |
| Attached file #10 svg.patch is a complete implementation of SVG image reading and drawing as a new Fl_SVG_Image class derived from Fl_RGB_Image. It could be part of libfltk_images. | |
|
#24 | manolo 04:18 Aug 31, 2017 |
| Attached file svg2.patch adds: - a missing FL_EXPORT - more complete documentation of the new Fl_SVG_Image class - configure/CMake options to build without nanosvg | |
|
#25 | AlbrechtS 07:46 Aug 31, 2017 |
| Uploaded files altsvgrast.h (full version) and altsvgrast.diff contain Ian's patch as posted to fltk.general, upgraded to the current nanosvg version (as of Aug 31, 2017). Manolo's proposal is already based on the current nanosvg version, so I just merged Ian's patch.
WRT line width and unproportional scaling: the uploaded files include one modification WRT Ian's patch: I calculated the average scaling factor sw = (sx + sy) / 2; and applied this to the scaling of line widths (instead of sx, as in Ian's code) and to the *new* dash length. This may be changed in the future.
Note: the average scaling factor can be 0 if one of the scaling factors is negative. This needs to be reflected, but I don't think that negative scaling factors are sensible values.
I tested Ian's buttons code and it worked well this his patch. | |
|
#26 | AlbrechtS 08:00 Aug 31, 2017 |
| Should read: "... worked well with his patch." And to be precise: with the upgraded patch version.
I don't know if unproportional x- and y-scaling is of any use in the current proposal of Fl_SVG_Image, but since I changed and tested Ian's proposal I thought it's worth posting it here. | |
|
#27 | AlbrechtS 08:04 Aug 31, 2017 |
| WRT nanosvg files: I suggest to put nanosvg.h and nanosvgrast.h in a separate directory (nanosvg) as we did with the bundled zlib, png, and jpeg libs. Although this is not strictly necessary it would make maintenance (upgrade of image libraries) more explicit.
If we used Ian's patch I would also propose to add a diff file in the nanosvg folder so we can later upgrade the bundled files easier (unless we find a way to push the patch upstream). | |
|
#28 | manolo 07:24 Sep 01, 2017 |
| Attached svg3.patch completes the class documentation about the fact that text is not rendered. | |
|
#29 | manolo 06:42 Sep 03, 2017 |
| The new class Fl_SVG_Image added with commit r.12413 adds SVG image support to FLTK. | |
|
#30 | djcj 03:55 Sep 07, 2017 |
| I made my own little implementation of Fl_SVG_Image: https://git.io/v5wKH
It may not be as good as yours, but it supports gzip compressed SVG files: https://git.io/v5w62 | |
|
#31 | manolo 09:36 Oct 04, 2017 |
| @djcj: please see the current state of class Fl_SVG_Image (after r.12477) which should support .svgz compressed SVG files, and report if something does not run well. | |
|
#32 | AlbrechtS 07:34 Jan 01, 2019 |
| Fixed in Git repository.
This STR has been fixed a long time ago. Time to close it. | |