Skip to content
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

Improving Eclipse Icon Scaling by Supporting Vectorized Icons #1438

Open
Michael5601 opened this issue Sep 2, 2024 · 43 comments · May be fixed by #1638, eclipse-platform/eclipse.platform.ui#2593, #1647 or eclipse-platform/eclipse.platform.ui#2621
Assignees
Labels
enhancement New feature or request

Comments

@Michael5601
Copy link

Michael5601 commented Sep 2, 2024

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:

  1. 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.

  2. 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!

@Michael5601 Michael5601 added the enhancement New feature or request label Sep 2, 2024
@vogella
Copy link
Contributor

vogella commented Sep 2, 2024

Thanks. SVG support for icons would be really great. IIRC @HeikoKlare did also mentioned this in the past

@merks
Copy link
Contributor

merks commented Sep 2, 2024

Yes there were discussions about this at the most-recent community meeting that @HannesWell hosted last week

@HannesWell
Copy link
Member

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.

@laeubi
Copy link
Contributor

laeubi commented Sep 3, 2024

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:

  1. 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
  2. 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
  3. 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
  4. 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!
  5. 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.

@Michael5601
Copy link
Author

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:

  1. 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
  2. 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
  3. 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
  4. 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!
  5. 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.

@HeikoKlare
Copy link
Contributor

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.

@HeikoKlare HeikoKlare transferred this issue from eclipse-platform/eclipse.platform.ui Sep 3, 2024
@BeckerWdf
Copy link
Contributor

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?

@laeubi
Copy link
Contributor

laeubi commented Sep 3, 2024

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

@mickaelistria
Copy link
Contributor

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.

@laeubi
Copy link
Contributor

laeubi commented Sep 3, 2024

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
grafik

Unicode Symbol U+1F512 „🔒“ and I can get it at any scale on any background.

@HeikoKlare
Copy link
Contributor

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).

@laeubi
Copy link
Contributor

laeubi commented Sep 3, 2024

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 ...)

@HeikoKlare
Copy link
Contributor

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.

@sravanlakkimsetti
Copy link
Member

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

  1. Changing scalefactor of the system (currently we require restart of eclipse on windows and linux and recommended on Mac)
  2. Moving eclipse from low res monitor to high res monitor. (here also we require restart)
    Actually in these cases we used to popup a message to restart. Not sure if this popup still there

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

  1. SVG
  2. PNG
  3. GIF
  4. BMP

@HannesWell
Copy link
Member

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.

@mickaelistria
Copy link
Contributor

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.

@Michael5601
Copy link
Author

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:

  1. Apache Batik 1.17
  2. EchoSVG 1.2.2 (a fork of Apache Batik)
  3. JSVG 1.6.1 by weisJ
  4. svgSalamander 1.4.1

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.

Functionality

I tested the libraries' functionality using vdiff, a tool enabling manual testing with various test suites. I tested with the following test suites:

  1. The W3C SVG 1.1 Second Edition Test Suite (418 tests) (result not included in this post but very similar to the second test suite)
  2. The resvg Test-Suite (1680 tests)
  3. All Eclipse icons (1967 icons without org.eclipse.e4.ui.model.workbench.edit icons, as they are duplicates with different colors and may not be in use in Eclipse)

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:

20241020_Funktionalität_resvg 20241020_Funktionalität_Eclipse 20241020_Funktionalität_Eclipse

Additional Findings
While conducting this analysis, I identified some side findings:

  • Duplicate Icons: Eclipse contains numerous duplicate icons, which I documented here.
  • False SVGs: Four false SVGs were discovered, with explanations in this issue and fixes in this PR.
  • SVG Elements Analysis: I parsed the XML for all unique Eclipse icons, counted and grouped the SVG elements to find out which groups are most important for the Eclipse icons. The first place is paint-servers which includes all radient elements. These results can be compared with the grouped resvg test suite results in the diagram below the table.
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%
20241025_Funktionalität_resvg-gruppiert-in-Prozent
  • Blurry 32x32px PNGs: Several 32x32px PNGs in Eclipse appear blurry. The following image compares the rasterization result of JSVG with the original 32x32px Icon.
20241021_Verpixelte_Icons

Performance

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.

20241024_Batik_Standardized_Rasterization_Time 20241024_EchoSVG_Standardized_Rasterization_Time 20241024_JSVG_Standardized_Rasterization_Time 20241024_svgSalamander_Standardized_Rasterization_Time 20241030_All_Libraries_Rasterization_Time_All_Icons

Performance Notes for first 4 diagrams:

  • Certain data points are significantly higher than others, as each library performed slower with the group containing 20 icons. This suggests that some icons may take longer to rasterize than others, even when they are the same size. The icons were selected randomly but I made sure no library would crash or fail on the rasterization.
  • Interestingly, svgSalamander shows improved performance as the icon size increases. I verified the data and found it accurate, but I plan to rerun the benchmarks specifically for svgSalamander to confirm there are no errors.

Compatibility

For compatibility, I assessed each library's dependencies:

  • Apache Batik and EchoSVG: Both have many dependencies. Their transcoder package, that provides rasterization functionality, cannot be integrated standalone due to significant inter-package dependencies, potentially adding unnecessary functionality to Eclipse. (See Batik’s jar dependency graph on Apache Batik’s website).
  • svgSalamander: Depends on org.apache.ant, but marked as optional in Maven. No other runtime dependencies found.
  • JSVG: Has two gradle compile-only dependencies on JetBrains and Google annotations. Compile-only Dependencies are unproblematic. There are no runtime dependencies.

Maintenance State

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:

  • svgSalamander’s development has ceased as stated here
  • Apache Batik, first released in 2001, had frequent updates initially but saw an update pause from 2008 to 2015, with minor updates roughly once a year since. Additionally the state of the test suite is very bad as stated in the EchoSVG repository
  • EchoSVG and JSVG, both new in 2023, are actively maintained, with JSVG’s integration into IntelliJ indicating additional potential for ongoing support.

Licensing

Library licenses are as follows:

  1. Apache Batik: Apache 2.0 License
  2. EchoSVG: Apache 2.0 License
  3. JSVG: MIT License
  4. svgSalamander: BSD-3-Clause License

All licenses are compatible with the Eclipse Public License.

Conclusion

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.

@BeckerWdf
Copy link
Contributor

  • Blurry 32x32px PNGs: Several 32x32px PNGs in Eclipse appear blurry. The following image compares the rasterization result of JSVG with the original 32x32px Icon.
20241021_Verpixelte_Icons

Did you find out what this happens? Is that happening to only this one icon?

@BeckerWdf
Copy link
Contributor

  • False SVGs: Four false SVGs were discovered, with explanations in this issue and fixes in this PR.

So the pass rate of your tests with the Eclipse icons now is 100% ?

@akurtakov
Copy link
Member

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.

@BeckerWdf
Copy link
Contributor

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.

@HeikoKlare
Copy link
Contributor

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?

@mickaelistria
Copy link
Contributor

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.

@BeckerWdf
Copy link
Contributor

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.

@akurtakov
Copy link
Member

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!).

@Michael5601
Copy link
Author

  • Blurry 32x32px PNGs: Several 32x32px PNGs in Eclipse appear blurry. The following image compares the rasterization result of JSVG with the original 32x32px Icon.
20241021_Verpixelte_Icons

Did you find out what this happens? Is that happening to only this one icon?

I'm not sure why this is happening, but I noticed it with certain items while testing with vdiff. Initially, I thought the program was making them blurry, but that wasn’t the case—it simply loaded the PNG at its original size of 32x32 pixels.

@Michael5601
Copy link
Author

  • False SVGs: Four false SVGs were discovered, with explanations in this issue and fixes in this PR.

So the pass rate of your tests with the Eclipse icons now is 100% ?

No these four icons were broken generally, so it had nothing to do with the functionality of the libraries. The percentage of eclipse icons that are not properly rasterized still remains the same. For JSVG this means that 17 SVGs need to be adjusted to be properly rasterized.

@Michael5601
Copy link
Author

yes exactly.

If you provide Issues for that I might have a look at them

That's very kind of you. Unfortunately, I didn’t write them down, but I’ll look for them.

@BeckerWdf
Copy link
Contributor

I will provide issues in which I describe how to fix these icons for JSVG after I implemented it in Eclipse.

Sounds reasonable.

@BeckerWdf
Copy link
Contributor

yes exactly.

If you provide Issues for that I might have a look at them

That's very kind of you. Unfortunately, I didn’t write them down, but I’ll look for them.

No hurry.

@HannesWell
Copy link
Member

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.

Assuming that the capability to render SVGs should be implemented in SWT directly and given that SWT should work in non OSGI runtimes as well and especially used to be one artifact (or in OSGI runtimes two), have we considered to embedd the jsvg jar or to shade it's content into into the SWT jar?
Usually shading/embedding dependencies is bad so I would only do this if we strongly want SWT to have no dependencies/be one artifact.

But if we are fine to introduce a dependency I'm happy to help OSGI-fying it. Given the project I'd interested in such change it's usually simple and I have done it already a few times.

@HeikoKlare
Copy link
Contributor

Assuming that the capability to render SVGs should be implemented in SWT directly and given that SWT should work in non OSGI runtimes as well and especially used to be one artifact (or in OSGI runtimes two), have we considered to embedd the jsvg jar or to shade it's content into into the SWT jar?
Usually shading/embedding dependencies is bad so I would only do this if we strongly want SWT to have no dependencies/be one artifact.

That's something we discuss discuss since, if I am not mistaken, this would be the first "explicit" dependency of SWT. We should at least discuss whether it wouldn't be better to provide a hook for SVG rendering and provide the rendering capabilities separately, so that consumers can decide on their own whether they want to integrate it in their applications or not. The Eclipse RCP could then hook the functionality in by default.

@peteroupc
Copy link

For your information I refer to an idea employed by the Haiku Vector Icon Format and Haiku's built-in tool Icon-o-Matic, namely the idea of allowing for icons with a different level of detail depending on their display size.

@Michael5601
Copy link
Author

For your information I refer to an idea employed by the Haiku Vector Icon Format and Haiku's built-in tool Icon-o-Matic, namely the idea of allowing for icons with a different level of detail depending on their display size.

Thanks for the info. The Haiku Vector Icon Format looks very interesting but I see two challenges that would be faced in the context of Eclipse:

  • All SVG icons need to be remade in the new Haiku format.
  • The libraries that I evaluated only support the vector format SVG to be rasterized.

Additionally we don't know right know how slow the rasterization is. I will provide performance measurements for starting an Eclipse application with and without SVG rasterization soon.

@peteroupc
Copy link

peteroupc commented Nov 19, 2024

Thanks for the info. The Haiku Vector Icon Format looks very interesting but I see two challenges that would be faced in the context of Eclipse:

* All SVG icons need to be remade in the new Haiku format.

* The libraries that I evaluated only support the vector format SVG to be rasterized.

Additionally we don't know right know how slow the rasterization is. I will provide performance measurements for starting an Eclipse application with and without SVG rasterization soon.

I mention the Haiku Vector Icon Format solely for its level-of-detail feature that allows for multiple icons that are the "same" but have a different level of detail depending on the pixel size in which they are rendered.

In the context of this issue, this feature can be implemented in some icons by somehow providing for multiple SVGs for the "same" icon that differ depending on their "pixel size", not necessarily by converting all vector graphics to the Haiku Vector Icon Format or a similar binary XML format such as EBML. (I don't suggest that SWT use the Haiku Vector Icon Format or any other binary vector graphics format, especially if the usual text SVG format is fast enough for SWT's purposes.)

Having multiple SVGs of this kind can be useful not only for performance reasons; for example, it would be possible to design vector icons such that the smaller versions lack finer details that wouldn't be seen.

@BeckerWdf
Copy link
Contributor

Having multiple SVGs of this kind can be useful not only for performance reasons; for example, it would be possible to design vector icons such that the smaller versions lack finer details that wouldn't be seen.

For the PNGs this today this is technically already possible.
the 32x32 pixel version get a @2x suffix. You could already provide two PNGs where the 16x16px version contains less details as in the 32x32px version. To my knowledge this is not used in the Eclipse IDE currently.

We could keep that freedom by also allow to providing:
x.svg
[email protected]
[email protected]
...

@laeubi
Copy link
Contributor

laeubi commented Nov 19, 2024

We could keep that freedom by also allow to providing

Eclipse also support /icon/NxM/x.png format, but for SVG I think neither of those are suitable but it should be more like something that set an upper/lower bound (what is hard to archive if you need to query an URL you cannot browse)...

One can of course try to do a binary search for find the best fitting SVG...

Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 6, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---

### **Key Features**

- **Example Images**:
  Screenshots showcasing the new functionality can be found below. These screenshots were taken with 125% monitor-zoom and scaling enabled with the flag `-Dswt.autoScale=quarter`.

| PNG      | SVG      |
|---------------|---------------|
| ![PNG](https://github.com/user-attachments/assets/6ecd1eb2-8716-465f-9206-e64ae9e17e7a)  | ![SVG](https://github.com/user-attachments/assets/44d69279-18a0-46de-9972-a529eff5da66)  |
| ![PNG2](https://github.com/user-attachments/assets/0ba6c210-1b0e-4f75-8fc5-f8b40d5c97b4)  | ![SVG2](https://github.com/user-attachments/assets/d8892fd4-c374-4152-9458-b7d50ed54157)  |
| ![PNG3](https://github.com/user-attachments/assets/d3c5668f-a4a3-4b9f-8ad4-73072c258abc)  | ![SVG3](https://github.com/user-attachments/assets/8f20bbf6-30d8-41cb-9775-ddbdad7398a4)  |
| ![PNG4](https://github.com/user-attachments/assets/dbbd7b6c-4e58-415e-8a13-ba3557f2dca6)  | ![SVG4](https://github.com/user-attachments/assets/95270a6b-b550-4652-afe5-43d35444b1df)  |

- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 6, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 10, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 10, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 10, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.

Introduce SVG rasterizer logic
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 11, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 11, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.

Introduce SVG rasterizer logic
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 11, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 12, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
carlosame added a commit to css4j/echosvg that referenced this issue Dec 19, 2024
Sometimes an SVG library is embedded into an executable, and a common concern
for both EchoSVG and Batik users in those cases is to make the size of the
embedded modules as small as possible.

Notably, in the case of the Transcoder a number of unneeded classes may be
included. For an example of such concern see

eclipse-platform/eclipse.platform.swt#1438 (comment)

The current `transcoder` module was designed as a monolithic do-it-all package,
with users always carrying code that they do not intend to run. But it can be
split in several submodules, in a way that backwards compatibility is kept (the
old `transcoder` module still exists and provides all the classes), so users
willing to minimize their dependencies can choose a smaller specific sub-module.

This commit splits the transcoder in 4 modules:

- `transcoder-api` (API)
- `transcoder-svg` (SVG to image)
- `transcoder-svg2svg` (SVG to SVG)
- `transcoder-tosvg` (conversions to SVG, currently only WMF to SVG)

In the typical case of rendering SVG as a PNG, the current 2.0 transcoder with
dependencies fills a jar of 6.26 MB, while the specific SVG-to-image transcoder
becomes a bit smaller (5.98 MB).

The gains are higher for the WMF to SVG case (3.94 MB) or the SVG-to-SVG (3.60
MB). Note that there is plenty of room for improvement in conversions to SVG,
because the current code uses the SVG DOM implementation provided by the `anim`
module (with all its dependencies) but the JDK DOM implementation could be used
instead (like in the EchoSVG Wiki example for `SVGGraphics2D`).
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 20, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Michael5601 added a commit to Michael5601/eclipse.platform.swt that referenced this issue Dec 20, 2024
Feature Proposal: Rasterization of SVGs at Runtime for Eclipse Icons
Fixes eclipse-platform#1438

Eclipse currently loads icons exclusively as raster graphics (e.g., `.png`), without support for vector formats like `.svg`. A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterizing SVGs outside Eclipse, leading to unnecessary effort and many icon files.

This PR introduces support for vector graphics in Eclipse, enabling SVGs to be used for icons. Existing PNG icons will continue to be loaded alongside SVGs, allowing the use of the new functionality without the need to replace all PNG files at once.

---
- **How It Works**:
  - To use SVG icons, simply place the SVG file in the bundle and reference it in the `plugin.xml` and other necessary locations, as is done for PNGs. No additional configuration is required.
  - At runtime, Eclipse uses the library JSVG to rasterize the SVG into a raster image of the desired size, eliminating the need for scaling. My analysis shows that JSVG is the most suitable Java library for this purpose.
  - You need to write the flag `-Dswt.autoScale=quarter` into your `eclipse.ini` file or into the run arguments of a new configuration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment