notes/icon-font.md
Telegram.ttf is now built by Tools/IconFont from SVG sources and a manifest, instead of by
icomoon.io from Telegram.json. The website is no longer in the loop and the repository holds
every outline the font is made of.
663 manifest entries, 638 glyphs, 166 KB - down from 667 glyphs and 184 KB, because 29 codepoints that carried the same drawing now share one glyph.
| 428 | fetched from @fluentui/svg-icons, pinned at 1.1.338 |
| 206 | local artwork in Tools/IconFont/icons/ |
| 29 | aliases: a codepoint that carries another codepoint's glyph |
Two thirds of the font now follows upstream, so it stops going stale on its own.
Microsoft's icons come from npm rather than the GitHub repository on purpose. The repository has over a hundred thousand entries so the git tree API truncates, and an icon's folder name cannot be derived from its own name. The npm package is one request, is versioned, and lays every icon out flat.
iconfont verify compares two fonts by what each codepoint paints - rasterised coverage, not
outline points, because contour order and winding direction are free choices that nonzero filling
cannot see. iconfont changes --reference <ttf> renders the same comparison as a page, each
changed glyph drawn before and after.
Against the IcoMoon font: 530 of 666 codepoints render identically. The 136 that differ are almost all deliberate - icons re-pointed at the live source, taking upstream's current drawing in place of a copy frozen years ago:
| 20 | over 15%: a different drawing, or a name that did not describe the artwork |
| 28 | 5-15%: the same icon visibly redrawn |
| 30 | 1-5%: a corner radius, a stroke weight |
| 58 | under 1%: imperceptible |
Nothing below 0.2% is counted at all; that is smaller than the cubic-to-quadratic conversion moves an edge, and every glyph went through it.
Icons.cs, the app names codepoints directly in ~760
 literals across 211 XAML files, and App.xaml points both TelegramThemeFontFamily
and SymbolThemeFontFamily at this font. A reshuffled codepoint changes icons all over the app;
a missing one renders as nothing rather than falling back to a system icon font.SharedLinkCell.xaml.cs:250 draws "" for the Instant View bolt, but that glyph is at
U+E60E - the two places that render it correctly (TLNavigationService.cs:164,
WebPageContent.xaml.cs:670) use E60E. IcoMoon had named the glyph uniE611 while assigning it
E60E, and someone read the name. It has always rendered blank. One-character fix, not made here.SymbolThemeFontFamily was overridden: U+E052, U+E1CD (Icons.Loading), U+E73C, U+E8B1
(shuffle), U+EE35, U+F13D and U+F13E (the poll ticks). iconfont missing --reference <segoe.ttf> --suggest shows what each used to draw and offers replacements from the MIT package.iconfont drift puts each next to today's upstream version.uniE600, uniE602,
uniE60B, uniE60C, uniE90A, uE6000 (outside the private use area), plus uniE601 and
uniE603, which are the seen and empty message-state badges and keep their IcoMoon names on
purpose - identified.txt marks those legacy rather than tbd. Four of the rest are the same
36x20 message-state family and probably belong with them.iconfont drift
puts each next to today's version; iconfont adopt --only <name> takes one.Icons.cs from the manifest, so a codepoint cannot drift between the font and the
constants.Everything is py -m iconfont <command> from Tools/IconFont, and adopt, identify, import,
rename, tidy and update are dry runs until given --apply. README.md there is the
reference; identified.txt records the by-hand identification of the glyphs IcoMoon left nameless,
and re-running rename over it is a no-op.