Open Michael5601 opened 2 months ago
Thanks. SVG support for icons would be really great. IIRC @HeikoKlare did also mentioned this in the past
Yes there were discussions about this at the most-recent community meeting that @HannesWell hosted last week
Thank you @Michael5601 for working on this. But isn't this mainly a SWT issue and we should move this discussion to https://github.com/eclipse-platform/eclipse.platform.swt, even though some higher level adjustment might be possible then, e.g. in jface?
Yes there were discussions about this at the most-recent community meeting that @HannesWell hosted last week
Yes. I captured the meeting-minutes at https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/wiki/Eclipse-IDE-%E2%80%90-Developers-Community-Call#29th-august-2024
At the very top of this page is also a link to the calendar that contains the dates of the upcoming meetings including the details how to join.
I have already investigated (and implemented) SVG support a while back for SWT so here are some hints if some wants to go in that direction further:
So for my usecase I finally ended up in having a script that automatically generates the icons from a SVG using Inkscape (what is the only descend SVG render I know about) and place them in the bundle, this increases the size a bit but gives the best, reproducible and portable result.
I have already investigated (and implemented) SVG support a while back for SWT so here are some hints if some wants to go in that direction further:
- As @HannesWell pointed out, the best would be if SWT would support SVG out of the box, and the Linux GTK already supports reading SVGs (but has some issues when it comes to scaling such image up but that should be solvable), for Windows there is also native SVG support starting with Windows 10 and as this is effectively the minimum Windows version this would be the most logical choice to bring the topic forward
- I also started implementing a SVG renderer natively using SWT but this failed because the SWT-GC is to limited to support more advanced features than drawing a line (and even that can become cumbersome as its not possible to clone a GC like AWT supports), so using softwarendering usually requires AWT what might introduce problems (@akurtakov mentioned this a while back) and also introduce another overhead to transform the data into an SWT image (especially transparency is really annoying to get correct), also the only quite complete library for that (batik) has quite a heavy dependency footprint and often some incompatibilities an new versions
- Another issue for icons is, that even though it is quite fast for a single image, there is a noticeable overhead as the XML needs to be parsed, then rendered to produce the final pixel data
- A much more problematic thing is, that the support of SVG features (or their individual interpretation) between libraries can greatly vary even the "simple" SVGs used in Eclipse can give surprising results using different renderers, so one has to check that they render equally correct, look good and probably adjust the SVGs before they can be used for each individual icon!
- On the other hand it is no longer true that Eclipse only supports 2 sizes (actually it has before supported 1.5 as well) it is just what is the most common today, Eclipse also supports a scheme where one can specify a URL that uses MxN as part of its name and the one can support any zoom level.
So for my usecase I finally ended up in having a script that automatically generates the icons from a SVG using Inkscape (what is the only descend SVG render I know about) and place them in the bundle, this increases the size a bit but gives the best, reproducible and portable result.
Thank you so much for your feedback - it’s very helpful :) I'll look into the issues you pointed out and see if I can find a suitable solution.
Thanks. SVG support for icons would be really great. IIRC @HeikoKlare did also mentioned this in the past
You remember correctly. I have the pleasure of supervising Michael's work 🙂
I agree with Hannes that this issue should be placed in the SWT repo, as, in a first place, it will have to be addressed in SWT. And it might also be of interest for other SWT users than the Eclipse platform. Actually, the issue itself is not that interesting (as the "limitation" is commonly known), it is rather about informing that someone is working on that (to avoid duplicate work, be able to give feedback etc.). And if someone really wanted to start working on this, they will know or identify soon that this has to be addressed in SWT and (hopefully) have a look in the issue list of that repo. Thus, I will move that over to SWT.
On the other hand it is no longer true that Eclipse only supports 2 sizes (actually it has before supported 1.5 as well) it is just what is the most common today, Eclipse also supports a scheme where one can specify a URL that uses MxN as part of its name and the one can support any zoom level. Interesting. I didn't know this. Where is that documented?
So for my usecase I finally ended up in having a script that automatically generates the icons from a SVG using Inkscape (what is the only descend SVG render I know about) and place them in the bundle, this increases the size a bit but gives the best, reproducible and portable result.
It that script publicly available. And if now would you mind sharing it?
It that script publicly available. And if now would you mind sharing it?
It is not public and rather roughly put together, something similar is already available here:
https://github.com/eclipse-platform/eclipse.platform.images/tree/master/org.eclipse.images.renderer
in my case it just a bit more automated, it first calculates all NxM variants for desired zoomfactors, then check if the source SVG has > modification time than target (or target do not exits) and then creates the PNG in a corresponding folder structure recognized by Eclipse.
So in this case instead of calling org.eclipse.images:org.eclipse.images.renderer:render-icons
manually via CLI invocation and then copy to the bundles, one could run it as part of the maven build and simply do similar to (re) generate images. One even maybe want to not copy the images at all to the bundles see
FWIW, given the current state of the discussion, I would challenge those 2 initial assumptions (the bold parts):
Maintaining multiple PNG versions in different sizes is not a sustainable solution, especially as higher DPI displays may require even more icon variations. Currently, new icons are manually created by converting SVGs to PNGs, a process that is both time-consuming and inefficient. By fully utilizing SVGs, which support resolution-independent scaling, these problems can be effectively addressed.
PNG are sustainable enough, as they have been doing a good work for a decade. The issue is indeed that there are higher DPI nowadays and we miss support for those. But higher resolution PNGs would be sustainable for those higher resolution. Process being time-consuming and inefficient is an issue of the particular implementation of the process. It's not a particular issue of the SVG->PNG rendering. We can relatively easily improve the process to make it less time-consuming and efficient (basically a single click on CI to run a build). It's "just" a matter of doing it.
As highlighted in previous comments, directly rendering SVG with SWT is far from being trivial, is an expensive task to develop and then maintain, that contain a big part of "risk".
So IMO, the most promising step forward (currently), it to improve the process.
In the current process described above by @laeubi , I think the "then copy to the bundles" is the most painful point for adoption of such new icon sizes.
We can maybe start by evolving our process to more easily (almost trivially) allow generation of icons of another size at build/install/configuration time: An interesting iteration IMO would be to allow to have a script in eclipse.platform.images repo such as java generateZoomedIcons.java 182
that would generate for each x.y.z bundle some fragment x.y.z.zoomedIcon182 containing the desired sized png, and ideally a even a p2 repo allowing to install those fragments easily in the IDE (similarly to babel language packs). Once those get installed in the IDE, then the newly sized icons should be used.
Such tool, if properly specified and documented, could also be used directly by other projects and RCP providers to generate their own icon fragments when a new zoon level appears to be prominent on the market.
With that, RCP adopter and users could generate and use the icons of their favorite size much more easily.
That wouldn't be perfect, but this had the advantage of being possibly much easier to setup (as it's not part of SWT, it doesn't even need to deal with release process and so on) and to provide a big chunk of the desired value. This has IMO a much higher ROI and is less risky than trying to render SVG with SWT.
I just wanted to add, that in general Icon-Fonts (even colorful) are actually a better fit for icons and state-of-the-art in web UIs, I though I added support for such kind of images to SWT a while back (but seems not finished / merged this due to low interest and/or contribution barriers at that time).
Here is an example where I use the "locked" icon drawn as a font
Unicode Symbol U+1F512 „🔒“ and I can get it at any scale on any background.
PNG are sustainable enough, as they have been doing a good work for a decade.
Stating that something is good enough because it was good enough for some time is a risky argument. This may be true in case the requirements are still the same, but in this case, the requirements have changed. Of course, generating more PNGs and doing that in a more automated way would be a step forward. But in my opinion, it hides the actual problem. And while all the technical insights are very, very valuable, they should not be taken as arguments for making conceptual considerations and decisions.
Let's phrase the problem a bit differently: there is a (current and even increasing) demand for the ability to retrieve an image (usually an icon) in an arbitrary size. The current way to deal with this is to provide more pre-generated icons for more sizes. For a long time, the assumption that you know at generation time of these images which sizes of the images will be required held true. For that reason, it was sufficient to provide 16x16 and later 32x32 icon images (and maybe even more today). But requirements have changed and will change even more in the future. We see more demand for customizability, such as better HiDPI support, also for the Windows 25% steps or even the experimental 1% steps, and maybe even for further customization of sizes in the UI on its own. This requirement can, conceptually, not be properly addressed with pre-generated images of fixed sizes. You may come to solutions like providing proper answers for every possible request in a specific range (e.g, for icons between 100% and 400%), thus storing 49 PNGs to deliver every size between 16x16 and 64x64. But that's probably not a good solution.
This new requirement (being able to retrieve an icon image for an arbitrary size) demands for icons being generated out of an size-independent representation (such as a vector graphics) at request (and not before application delivery). This does, of course, not prevent you from considering different technical and more fine-grained design options to address specific problems, e.g., doing some caching of already generated images to improve performance.
I just wanted to add, that in general Icon-Fonts (even colorful) are actually a better fit for icons and state-of-the-art in web UIs,
Icon fonts are of course an even better way to provide icons and go beyond the usage of vector graphics. From the perspective of the overall goal, it should definitely be the preferred solution. But changing icons to icon fonts is a more invasive approach that will probably also require more adaptations at the client side than simplify replacing a .png
path with a .svg
path. And you have to agree on some icon font to be used or have to provide multiple fonts for different usage scenarios.
We tried to use icon fonts for the find/replace overlay, but we simply used the default font and not every OS's default font provided/rendered that icon properly (it was not working on Linux, if I remeber correctly).
That's why I said PNG (even with it shortcommings) is the most portable way. Rendering images on demand again opens a another can-of-worms, e.g different (os specific) anti-alising, roundings and so on, so everything has it shortcomminds.
That's also the reason I believe SVG support can only be archived on the native level, because that's what SWT claims to use and we can always argue it is like it is implemented in the OS if it looks different.
thus storing 49 PNGs to deliver every size between 16x16 and 64x64. But that's probably not a good solution.
Technically one can use image-maps that store different sizes in one file if its just the number of files that scares :-)
We tried to use icon fonts for the find/replace overlay, but we simply used the default font and not every OS's default font provided/rendered that icon properly (it was not working on Linux, if I remeber correctly).
I once suggested that SWT ships with some well known fonts like AWT, Jface already maintains a list of "cross platform names" I just wanted to mention this as an alternatives if we talk about icons (e.g. Eclipse platform can deliver its own font for sure... also plugins like JDT/PDE ...)
That's why I said PNG (even with it shortcommings) is the most portable way. Rendering images on demand again opens a another can-of-worms, e.g different (os specific) anti-alising, roundings and so on, so everything has it shortcomminds.
That's also the reason I believe SVG support can only be archived on the native level, because that's what SWT claims to use and we can always argue it is like it is implemented in the OS if it looks different.
I have to admit that I don't get these points and they somehow also sound contradictory to me. The PNGs that we ship right now are rendered out of SVGs with some library. Why should it make any difference if I render the images with that library on-the-fly compared to doing that before application deployment and then simply reloading the persisted result (i.e., the PNGs)? And on the other hand: why should I want to have OS-specific anti-aliasing or the like? This is currently also not the case, as images are pre-generated in a uniform, OS-independent way.
Regarding the second statement: I do not see why SWT should claim that it uses native SVG rendering support. I think you mean that SWT claims to adapt native widgets, but why should that cover using native SVG support given that is no existing SVG support at all? And finally: why should anyone care? If our customers would not like how our applications looks like, we can tell them that our products look like they look because it they are based on Eclipse (and that in turn on SWT, and that in turn on the OS). They would still not like how the application looks like, as they don't care which decision, i.e.g, which dependency is responsible for that.
Here are some points
Please do not focus on changing the Image dynamically. The use case is pretty limited. Only couple of use cases I can think of
Please target ability to create raster images by loading SVG files with target size(this should be calculated based on the size in points multiplied by scalefactor). Need to enhance ImageData class. This will go a long way in rendering sharp images in Eclipse.
Loading of Image should follow this preference
That wouldn't be perfect, but this had the advantage of being possibly much easier to setup (as it's not part of SWT, it doesn't even need to deal with release process and so on) and to provide a big chunk of the desired value. This has IMO a much higher ROI and is less risky than trying to render SVG with SWT.
Please consider that the intended work is part of a bachelor thesis as noted initially. In that context aiming for the technologically and thus academically more interesting goal is IMO totally fine, even if the invest and risk is higher (ROI is usually only a secondary goal in academia). And if the goal is reached we all benefit from a closer to ideal solution, even if an optimized process could be "good enough" as well. And in case the goal isn't reached, we hopefully know in detail what's missing or why it is impossible.
Please consider that the intended work is part of a bachelor thesis as noted initially. In that context aiming for the technologically and thus academically more interesting goal is IMO totally fine, even if the invest and risk is higher (ROI is usually only a secondary goal in academia).
OK, I had missed that point. In such case, I agree that directly aiming for runtime SVG support in SWT is better topic for a bachelor thesis.
As I work on this issue, I’d like to provide an update on my analysis progress.
To date, I’ve completed an in-depth review of suitable Java libraries for vector graphics rasterization at runtime. The research is limited to java libraries because they would be easier to integrate into eclipse later on.
Four libraries were analyzed:
Each library was evaluated using 11 metrics across five categories: functionality, performance, compatibility, maintenance state, and licensing. In this post, I’m presenting key findings from the six most important metrics, organized by section.
I tested the libraries' functionality using vdiff, a tool enabling manual testing with various test suites. I tested with the following test suites:
The first two diagrams below show the pass rate for each test suite. The third diagram compares the results that I gathered to an analysis that was conducted by the author of resvg with the resvg test suite:
Additional Findings
While conducting this analysis, I identified some side findings:
Group name | Element count | Percentage |
---|---|---|
paint-servers | 68703 | 58.2560% |
shapes | 21928 | 18.5936% |
filters | 12450 | 10.5568% |
structure | 12243 | 10.3813% |
masking | 2499 | 2.1190% |
text | 108 | 0.0916% |
painting | 2 | 0.0017% |
Sum | 117933 | 100% |
Using Java Microbenchmark Harness (JMH), I conducted performance benchmarks. Each benchmark tested the rasterization of 20, 50, or 100 Eclipse icons across target sizes (16x16px, 32x32px, 64x64px), resulting in nine benchmarks per library. Each benchmark was run 100 times, with results normalized to reflect the rasterization time per icon (e.g., dividing the results of the first benchmark (20 icons, 16x16px) by 20). This allowed me to combine the results for every size, which results in 300 iterations per size.
The following four diagrams with boxplots summarize each library’s performance by icon size, with 300 data points per plot. A fifth diagram compares all four libraries on rasterizing all unique Eclipse icons (1,825) at 32x32px with 20 data points per plot. The dotted line in the boxplots is the mean and the solid line is the median.
Performance Notes for first 4 diagrams:
For compatibility, I assessed each library's dependencies:
org.apache.ant
, but marked as optional in Maven. No other runtime dependencies found.I measured maintenance frequency by the average time between releases, starting from version 1.0. For svgSalamander, I calculated only from GitHub releases starting 2016 due to the lack of SVN history.
Library | Release Frequency (Days) |
---|---|
Apache Batik | 284.467 |
EchoSVG | 62 |
JSVG | 63.286 |
svgSalamander | 456.8 |
Summary of Maintenance Findings:
Library licenses are as follows:
All licenses are compatible with the Eclipse Public License.
Although JSVG does not achieve the highest functionality scores, it excels in performance, lacks dependency issues, and shows robust maintenance support. EchoSVG, while functionally strong, is slower and has dependency issues. Apache Batik shares dependency concerns and is also slower, with less frequent updates. svgSalamander scores lowest overall, with limited functionality and discontinued development.
Based on these findings, JSVG is the most promising option for Eclipse integration. Additional non-Java libraries are not necessary at this stage.
I welcome any feedback or ideas on this topic. My next step is to begin integrating JSVG into Eclipse. If you’d like to see the complete analysis chapter from my thesis (in German), please reach out, and I’ll be happy to share it.
- Blurry 32x32px PNGs: Several 32x32px PNGs in Eclipse appear blurry. The following image compares the rasterization result of JSVG with the original 32x32px Icon.
Did you find out what this happens? Is that happening to only this one icon?
One point that has been missed from product POV: Batik is used by the theming engine for CSS support so it's already there and needed and unless CSS support is redone (outside of scope for svg support but relevant from releng POV) the dependency concerns for Batik should be lowered in the analysis.
Just as a side remark: AFAIK Batik is also used in the images repo's renderer. If we really go for SVG support in Eclipse via one of these libraries we should also think about using the same library in this renderer.
Just as a side remark: AFAIK Batik is also used in the images repo's renderer. If we really go for SVG support in Eclipse via one of these libraries we should also think about using the same library in this renderer.
If the images repo will still exist in its current state, I agree. But wouldn't SVG support in Eclipse render the repository obsolete, or at least make the PNG images inside the repository obsolete?
Batik is used by the theming engine for CSS support so it's already there and needed and unless CSS support is redone
It seems like the renderer is not used nor included by Platform. Only the CSS subcomponent (which is used by the renderer) and its basic dependencies seems to be there. The SVG bundles of batik are not even part of the p2 repo produced by Platform.
If the images repo will still exist in its current state, I agree. But wouldn't SVG support in Eclipse render the repository obsolete, or at least make the PNG images inside the repository obsolete?
Yes that's true. We could think of removing the PNGs from the images repo.
It seems like the renderer is not used nor included by Platform. Only the CSS subcomponent (which is used by the renderer) and its basic dependencies seems to be there. The SVG bundles of batik are not even part of the p2 repo produced by Platform.
That's exactly why I said "dependency concerns should be lowered" and not "removed". Now I looked more into it more and JSvg (https://mvnrepository.com/artifact/com.github.weisj/jsvg/1.6.1 ) is not osgi library nor in Orbit while batik-transcoder is available at https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/milestone/latest/index.html . So from releng POV JSvg will be more work as it will either have to be OSGified upstream (preferably!) and once such release is done to use it in Eclipse or it will have to be added to Orbit while batik transcoder can be "simply" reused from Orbit as it's already there. Don't get me wrong here - I have no hidden love for Batik but I want to be sure that integrating things proper from releng POV is always considered early in the process so this work doesn't come up as a surprise in the last minute (like it happens quite often!).
Eclipse currently relies on PNG files for displaying icons, requiring two different sizes to handle various zoom levels. For zoom factors between 100% and 174%, the original-size icon is used, while for zoom levels between 175% and 200%, a double-sized icon is displayed. This approach has several drawbacks:
Quality Loss with Autoscaling: Enabling autoscaling for icons using the flags
-Dswt.autoScale=quarter
or-Dswt.autoScale=exact
can cause quality degradation, particularly on high-DPI displays or at high zoom levels, since PNGs do not scale well.Maintenance Challenges: Maintaining multiple PNG versions in different sizes is not a sustainable solution, especially as higher DPI displays may require even more icon variations.
Currently, new icons are manually created by converting SVGs to PNGs, a process that is both time-consuming and inefficient. By fully utilizing SVGs, which support resolution-independent scaling, these problems can be effectively addressed.
Previous discussions have highlighted these issues, such as those documented in this Eclipse bug report.
My bachelor’s thesis explores how SVGs can be better integrated into Eclipse to improve icon scalability and reduce maintenance overhead. If you have any insights or suggestions, please feel free to reach out or leave a comment!