-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
Subset icon font #1201
Comments
Need the same because the docs advertise 900+ fonts as weighing "in at only 42KB in its smallest woff2 format" but I'm seeing 109KB and no compression on the response in dev tools. My code:
|
@caperaven you might want to change the title to better reflect the ask. Perhaps "Customize the icon font set to reduce size" |
Dup of #564, which is 5 years old 😢 |
I am happy to build the font myself, I am just unsure of what the best tooling is to use for this. |
(took the liberty of amending the title) Figure out the glyph ids for the icons you want to keep (because using text= may retain other icons reachable with the same text, e.g. alarm_on might keep alarm as well) and then subset by glyph id. For example, you could use https://rsheeter.github.io/font101/#hb-shape to get the glyph id and then https://rsheeter.github.io/font101/#pyftsubset to subset the font. This could all be packaged up into a nice cli that takes a list of icon names if you need to do it repeatedly. Edit: if you plan to deliver to the web you will want to compress the resulting font; https://rsheeter.github.io/font101/#web-serving has some suggestions. |
Looks like this was resolved long ago! |
@tphinney Actually not really, because it doesn't work with the new Material Symbols. I tried all the options of pyftsubset for an hour, but the ligatures are getting lost in the process. :( Fontsquirrel and fontello doesn't work either. |
Probably the ligatures are getting lost because you aren’t including the glyphs that are needed to input the ligatures. Besides the desired symbols you would need a-z, space, underscore, and to include the 'rlig' feature. |
@tphinney Ah, I see, that makes sense, thanks. Tried for another hour and whenever I add At this point I decided to go with link to fonts.googleapis.com, which download about 40kB for the same font. No idea how, but it works. Still I would prefer self-hosting, if I could manage to make the subset. |
Note: realized I was forgetting the zero through nine characters, also needed to get at the names of some glyphs. So, it seems like you are now getting EVERY ligature that can be formed with those glyphs. Which would be nearly all of them. (Except those needing characters you don't need. Whatever tool you use to subset needs to both:
I don't know if pyftsubset can do that for you. If not, you need something that can. Unfortunately all this is a bit of a “corner case” as far as font subsetting goes. It is an unusual situation where one wants some but not all of the ligatures that can derive from the available characters. |
@tphinney Thanks for the explanation. I haven't found any other tools that can do that programmatically. |
Yes. This is the place for external feature requests. |
@tphinney Sorry to bother again but I just noticed that the API now returns the large file as well. I'd love to use the variable icon font but the size doesn't seem worth it. <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,100..700,1,0..200" rel="stylesheet" /> Can you please escalate this somehow? Thanks |
@tphinney Can you please reopen this issue, or should I open a new one about the variable symbol subsetting? I feel like it's a huge waste for such an awesome asset to be basically unusable in production. |
Yes, please reopen. Came back here after 2 years sure I would find Google has indeed solved this by now. Darn. No app uses 3,000 icons. The smallest configuration I've been able to get yields a 323kb woff2 file (using Ideal solution: If anyone has ever achieved exactly this, PLEASE reveal your secrets! Like maybe the folks at Google working on Material Symbols who know the tooling/config used to build the full Material Symbols font files. Can ya throw us a bone here?! |
Reopening because it would be a good feature to have. If you want to DIY I think what you want to do is roughly:
I'd have to try it to be sure the ligatures would be retained, it's possible you'd end up with just PUA codepoint access. For context, a Google-style icon font typically lets you get the icon glyph by either a PUA or a ligature. If you end up with just PUAs you'd have to rebuild the ligatures. This could certainly be packaged up into a little tool or exposed by an API endpoint but I believe nobody has sat down and done it so far. |
Thanks @rsheeter, will try to look into all that. It's a totally new space to me. PUA = "Private Use Area" yeah? Tool creators do seem to be struggling to provide a solution, but it is nevertheless a need in the web community dzhuang/subset-iconfont#81 |
Yes. On https://fonts.google.com/icons?selected=Material+Symbols+Outlined:menu:FILL@0;wght@400;GRAD@0;opsz@24 this is displayed as codepoint. That codepoint maps directly to the glyph via cmap as described in https://rsheeter.github.io/font101/#glyph-ids-and-the-cmap-table.
One extra indirection, a ligature maps a series of glyphs to another glyph so "menu" would resolve to glyphs and then those glyphs would be replaced by the glyph for the menu icon.
All the parts are available but I appreciate that doesn't mean it's trivial to assemble them. |
Apparently I said I would reopen but didn't actually do it |
I agree that “good” subsetting of Material Symbols would be lovely and even important functionality for Google to provide. It is… not trivial, and especially not if adding it to Google’s font-serving capabilities. Another thing that any subsetter needs to do to maintain full functionality is, IF the subset includes the 'FILL' axis, maintain alt glyphs that get swapped at >99% fill. This is needed to ensure that fully-filled glyphs render correctly, especially (1) when multiple axes are at non-default positions; and/or (2) Apple’s rasterizer is being used, as is commonly the case on iPhone and macOS. (Note to Googlers: there are additional wrinkles on this, if we are dealing with the internal Google Symbols version of the font.) Note that the way these alts are implemented is not supported in all environments (notably not working in Figma and Adobe desktop apps), though they work in all browsers AFAIK. |
If we lose the alt glyphs when subsetting that's a bug in the subsetter that we would fix so I think for planning purposes one could assume that works. |
https://github.com/rsheeter/subset-gf-icons/blob/main/src/subset_gf_icons/subset_gf_icons.py shows finding the glyph ids which one would then feed to subset, etc. I only had a few minutes to play so that's as far as I got :) |
A nicety for sure, but I think a CLI is where the biggest impact is. Frontend teams would want to be able to update their project's list of used icon names in a PR and then have CI (or local tooling) spit out the new icon font file, which would get hosted along with all their other assets. Pardon my frankness, but don't you guys already have these tools available to you?! |
^ it was an intern who did it all by hand wasn't it? |
@tphinney Interesting, you're correct. It's not multi-word icons, it's all icons containing characters a, b or c. All icons without these letters are working. Thanks for the correction. @rsheeter Any idea why does subset_gf_icons omit these characters? For completeness, this is my command:
|
My quick hackery assumed zero width space would suffice to break ligatures. I never tested that, it doesn't work. The result was if the sorted unique characters from the icon names you asked to subset activated a ligature it would activate and then some of the icons you wanted to use wouldn't be accessible. Your sample command hits this for the sequence abc. Should be fixed by rsheeter/subset-gf-icons#2. |
@rsheeter It works! You're my hero :) Thanks a lot. Example for anyone new here, you can subset the variable Google Symbols font into woff2 like so (replace icon names):
|
Bump |
It was reopened a month ago |
@jfbrennan & @EskelCz Thank you for exploring possible solutions. Using a python script however to convert material symbols from ttf to woff as part of build seems quite impractical in our pipeline. I really can't grasp why the Google engineers overlooked the quite obvious flaws in distributing Material Symbols as one extremely large, unusable webfont. Perhaps they could think of a system like the 'ol Icomoon app, where users can select icons & generate a webfont on the fly? |
@MarcoTroost I was originally looking for a UI solution too, but actually running a script is much more easily automated so I would say it's in fact a better way to go about it. You can also save the list of your icons with the script. @tphinney @rsheeter Sorry to bother again but after some time of using the subset I noticed a slight flaw in the rendering/antialiasing of the filled variant. It creates minor gaps between the shapes and once you notice it you can't unsee it. :) It's not there with the original font from fonts.googleapis.com, I just checked. Any ideas what might be happening with precision in the export process? It looks like this, when zoomed in: Tried TTF and it's the same thing. EDIT: Checked glyph coordinates before and after the subsetting, they look the same. Since they are in integers, it also doesn't look like a precision issue.
|
Whether this problem happens or not depends on the font rendering engine in use; Apple’s is the biggest problem in this regard. (Note: I am not saying Apple is doing anything terribly wrong! This is a highly unusual glyph rendering situation. It isn’t like a dynamic Fill axis is something one sees every day in a font.) The original font avoids this Apple-rendering complication by being coded to substitute a completely filled glyph variant when Fill is >99%. Crazy workaround, but effective. So, the subsetting needs to preserve this, too. Currently this is wired up to the 'rclt' OpenType layout feature. (Not every glyph needs this, but most of them do. That is, all the ones that have an interior fill, similar to the two shown.) |
The subsetter preserves this sort of feature through layout closure. I turned it off to prevent pulling in excess icons so that's a bug in subset-gf-icons. |
@tphinney could I impose on you to review rsheeter/subset-gf-icons#3? - looks to me like now if I subset Material Symbols to "star" it additionally retains "star.fill" |
That sounds like the desired behavior! Rod, can you share an output font with me? You’ve got my email etc. :) |
See https://stackoverflow.com/questions/60049960/fonttools-convert-ttf-to-woff2/77263093#77263093 |
@tphinney Thanks for the explanation!
You're a star :) Thanks a lot! |
Although I am happy to also inspect the font itself, I suspect the proof is in the visual output. If that is fixed, we can reasonably suspect that it is because the fully-filled alternate glyph is being called upon as intended. :) |
About: rsheeter/subset-gf-icons#3 I'm trying to develop a web version and I'm having a little problem. |
I read the Python code for pyftsubset input.ttf --gids='4261,4995,5012,5013,5014' --output-file="ft.ttf" --verbose --glyph-names There will be more 'atr', ' 'rtt', etc. in the output Glyph names than in subset-gf-icons, which will be permuted when pyftsubset is subsetted. pyftsubset output
subset-gf-icons output
@behdad @anthrotype |
There isn't an exact equivalent, you'd have to make a new entrypoint that does what subset-gf-icons does. I'm not sure off-hand if the closure function you need is readily accessible; if not that might require a change to HB. |
@rsheeter I found the right way to go and should have used the
The difference between the current hb-subset and pyftsubset is that |
@tphinney Magic, do you mean that when the variable axis Is it just that Apple's font rendering engine doesn't handle this extreme case very well? My tests have found blanks in Chrome and Firefox on the Mac as well. |
Yes, that is about it, although technically the code sure looks like it says the alt glyph kicks in at GREATER THAN 0.99, so for example at 0.991 or higher fill, you should get a swap to the fully-filled version of the icon. That is exactly the reason, that Apple’s rendering engine does not handle this well. But honestly the whole thing of having two filled glyph areas that are supposedly seamlessly abut each other… this is really NOT a normal font rendering expectation/situation at all. We are doing something pretty darn weird, and I really don’t blame Apple that their rendering does not deal with it well. That’s why I came up with the alternate glyph swap at >99% fill as a workaround. (At least, I think it was my idea. Most of the clever technical ideas on this were Vassil Kateliev’s, though!) |
@tphinney Thanks! I found some |
Sorry I didn’t notice that last comment earlier. We use 'rlig' two different ways —
|
@tphinney Hi, I just want to say thank you, and I'm wondering if this is mentioned anywhere. If it's not, I'm not sure if it's a good idea, but I'm hoping to write it down somewhere in case someone encounters this issue, since most people may not read the whole thread. |
The icon font has all the icons available.
I am looking for a way to customise or create a custom font that only contains the icons I use.
What tooling do you use to create the current icon fonts?
I am kinda new to the font generation thing but would like to get the same behaviour as using the standard font.
That being that the icon name is the identifier of the icon not some ascii code.
The intent of the custom font is for personal use but are there any legal issues I should take note of?
The text was updated successfully, but these errors were encountered: