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

Future strategy for icon management #2960

Open
abey79 opened this issue Aug 11, 2023 · 9 comments
Open

Future strategy for icon management #2960

abey79 opened this issue Aug 11, 2023 · 9 comments
Labels
enhancement New feature or request ui concerns graphical user interface

Comments

@abey79
Copy link
Member

abey79 commented Aug 11, 2023

(forked from discussion in #2920)

We currently use 24x24px png exported from Figma.

This approach has two shortcomings:

Moving forward, our strategy for icons should enable:

  • Ease of changing out icons (e.g just drop a .png or .svg in folder)
  • Low code bloat (don't increase .wasm size too much)
  • Visual quality (icons shouldn't be blurry, no matter what dpi scaling the user has)

cc @martenbjork @emilk

@abey79 abey79 added enhancement New feature or request ui concerns graphical user interface labels Aug 11, 2023
@abey79
Copy link
Member Author

abey79 commented Aug 11, 2023

Comment from @emilk:

We should create a proper issue about how to do icons. Some quick, random thoughts:

There are at least three things to consider:

  • Ease of changing out icons (e.g just drop a .png or .svg in folder)
  • Low code bloat (don't increase .wasm size too much)
  • Visual quality (icons shouldn't be blurry, no matter what dpi scaling the user has)

There are two major ways to go.

Imagers (e.g. .png)

  • very easy to create and use

  • but one imager will never be optimal for all resolution scalings.

    • we could export one high-res .png and dynamically rescale it to fit the users resolution. Pretty easy to implement, and low code bloat.

Vector graphics

Using epaint vector rendering (like this PR) works great (proper anti-aliasing for all resolutions), but only for convex polygons.

Dor concave polygons we either need to implement something new in epaint, or use some 3rd party rendering tool (more code bloat)

.svg is a horribly complex format. tinyvg is an interesting new alternative, but still requires us to ship code for parsing and rasterizing, increasing .wasm size.

Conclusions?

I'm leaning towards using a single high-res .png for each icon, then resize it using some high-quality algo (e.g. Lanczos filtering) to create a crisp icon for the current resolution scaling.

Easy to use, easy to implement, high-quality, low code bloat.

@abey79
Copy link
Member Author

abey79 commented Aug 11, 2023

My two three cents:

  1. On code bloat: we currently have 29kB worth of PNGs pulled into the binary. Assuming a doubling of resolution (48x48), that would scale to about 120kB. A vector representation would arguably reduce this significantly (10x?). Does that represent a significant budget for some (acceptable) code bloat?

  2. I'd stay away from SVG: too complex and not mature enough. An alternative could be the SVG path format (e.g. L10,10 Q20,20 30,30 Z). kurbo has a parser for that and seems like a very lightweight dependency (by default, no sub-dependency that we dont already have). This would require building a render with support for concave shapes and even-odd fill rules.

  3. Developing said renderer might be simpler if we cache bitmaps at the desired resolution (as opposed to including it in epaint and the egui render loop), even CPU based. That approach could further limit code bloat at the expense of a little memory and CPU time at start-up (or upon first displaying a given icon).

@Wumpf
Copy link
Member

Wumpf commented Aug 11, 2023

did we already consider creating a font at build time from input vector data and use that? Egui already handles font rendering, meaning that a vector graphics library is already dragged in

@abey79
Copy link
Member Author

abey79 commented Aug 11, 2023

did we already consider creating a font at build time from input vector data and use that? Egui already handles font rendering, meaning that a vector graphics library is already dragged in

We'd end up pulling a font-building library I guess, but I like this idea :)

@emilk
Copy link
Member

emilk commented Aug 11, 2023

Example of putting icons in a font for egui: https://github.com/amPerl/egui-phosphor

@abey79
Copy link
Member Author

abey79 commented Aug 11, 2023

It appears to be just using pre-packaged fonts.

Which leads to the idea of storing our icons in a font file, and just editing/adding icon with e.g. FontForge (or some scripts). Then we just need a bunch of constants to map icon names to unicode characters.

@abey79
Copy link
Member Author

abey79 commented Aug 11, 2023

Online tool to build font from SVG: https://www.glyphter.com

It should be relatively straightforward to have a script converting a bunch of SVGs into a TTF font and generate the corresponding re_ui constants.

@emilk
Copy link
Member

emilk commented Aug 12, 2023

One downside of the font approach is that it will only support monochrome icons (epaint doesn't support color emojis)

@emilk
Copy link
Member

emilk commented Sep 1, 2023

Whatever we chose should be compatible with:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request ui concerns graphical user interface
Projects
None yet
Development

No branches or pull requests

3 participants