lucide-icons / lucide-flutter

Archived package of Lucide Flutter
4 stars 3 forks source link

"Weight" parameter is not supported #6

Open n-bernat opened 4 months ago

n-bernat commented 4 months ago

Icon widgets allows developers to customize a bunch of properties. One of them is weight which currently has no effect. According to the documentation:

Requires the underlying icon font to support the wght [FontVariation] axis, otherwise has no effect.

I will investigate how fonts are generated and see whether I can make it work.

n-bernat commented 4 months ago

It looks like svgtofont lacks support for generating fonts with a custom font axis (wght in this case). It would probably require some custom implementation and more research into the TTF specs if there are no tools for that.

n-bernat commented 4 months ago

After digging a little bit it looks like fontmake from Google supports generating variable font icons, which would allow to control both weight and optical size.

fontmake supports .glyphs, .ufo and .designspace formats.

UFO sounds like the most reasonable candidate for an intermediate format, because it was the easiest to find information about it and it also looks like the most "open" file format. I'm not a font designer though, so if anyone wants to stop me it's the best time for that.

The workflow update that I can imagine for that is:

  1. Replace downloading the compiled TrueType font with raw SVGs from lucide-icons/lucide
  2. Generate outlined SVGs for various weights and sizes
  3. Convert SVGs to *.ufo files (I found something called fonttools that does that, but I will look for something that doesn't require Python)
  4. Feed fontmake with UFOs and let it do its magic
  5. ✨ Have fun with a TrueType variable font ✨

For supported weights, I would go for values supported by Material Symbols and add one additional weight value.

Weight (wght) Source line thickness (px)
100 0.5
200 1
300 1.5
400 2
500 2.5
600 3
700 3.5
800 4 (additional)

For supported optical sizes, I would also start with Material's defaults and maybe add more in the future.

Optical Size (opsz)
20
24
40
48

One consideration is that the library will probably grow quite a bit, but as it's a Flutter-specific implementation and Flutter removes unused icons it shouldn't be much of a problem.

After doing all of that, it should be supported natively in Flutter.

Icon(
  LucideIcons.bot,
  color: Colors.black,
  size: 24,
  // Now supports customizing `weight` and `opticalSize` 🎉
  weight: 400,
  opticalSize: 24,
)

If everything goes smoothly, it may be implemented faster than for the official icon set in Flutter https://www.github.com/flutter/flutter/issues/102560