rerun-io / rerun

Visualize streams of multimodal data. Fast, easy to use, and simple to integrate. Built in Rust using egui.
https://rerun.io/
Apache License 2.0
5.61k stars 254 forks source link

Future strategy for icon management #2960

Open abey79 opened 10 months ago

abey79 commented 10 months ago

(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:

cc @martenbjork @emilk

abey79 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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

abey79 commented 10 months ago

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 commented 10 months ago

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 commented 10 months ago

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

emilk commented 10 months ago

Whatever we chose should be compatible with: