Description
When using Collection::load_fonts_from_paths to register fonts from a directory, the resulting Collection contains duplicate entries for the same font file.
❯ cargo run --release -- a --no-system -I Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB -vv
Finished `release` profile [optimized] target(s) in 0.22s
Running `target\release\fontfor.exe a --no-system -I Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB -vv`
Font(s) support the character "a"(U+0061, 97, 0x61):
LXGW WenKai GB
LXGW WenKai GB Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Regular.ttf:0
LXGW WenKai GB Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Regular.ttf:0
LXGW WenKai GB Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Regular.ttf:0
LXGW WenKai GB Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Regular.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Light.ttf:0
LXGW WenKai GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Medium.ttf:0
LXGW WenKai GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Medium.ttf:0
LXGW WenKai GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Medium.ttf:0
LXGW WenKai GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Medium.ttf:0
LXGW WenKai GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiGB-Medium.ttf:0
LXGW WenKai Mono GB
LXGW WenKai Mono GB Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Regular.ttf:0
LXGW WenKai Mono GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Light.ttf:0
LXGW WenKai Mono GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Light.ttf:0
LXGW WenKai Mono GB Light Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Light.ttf:0
LXGW WenKai Mono GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Medium.ttf:0
LXGW WenKai Mono GB Medium Y:\Cloud\Data\Fonts\Free\Lxgw\WenkaiGB\LXGWWenKaiMonoGB-Medium.ttf:0
Cause
Currently, the load_fonts_from_path function contains a families map inside it, and each time the scan_path callback is triggered, the register_font_impl it calls adds all fonts in this families map to self.families. Throughout the entire process, families is never cleared.
At the same time, it is quite strange that while the scan_path callback already returns ScannedFont, register_font_impl still uses scan_memory to re-process all fonts in the data. This not only causes performance issues but also leads to further font duplication when processing TTC files...
For example, when I was testing on Linux, I encountered this spectacle:
❯ cargo run --release -- a --no-system -I /usr/share/fonts
Finished `release` profile [optimized] target(s) in 0.87s
Running `target/release/fontfor a --no-system -I /usr/share/fonts`
Font(s) support the character "a"(U+0061, 97, 0x61):
Adwaita Mono with 690 styles
Adwaita Sans with 339 styles
C059 with 138 styles
Cantarell with 1065 styles
D050000L with 32 styles
Droid Sans with 323 styles
Droid Sans Devanagari with 159 styles
Droid Sans Thai with 149 styles
Font Awesome 6 Brands with 168 styles
Font Awesome 6 Free with 333 styles
Jomolhari with 79 styles
Liberation Mono with 306 styles
Liberation Sans with 290 styles
Liberation Serif with 274 styles
Madan2 with 66 styles
Nimbus Mono PS with 118 styles
Nimbus Roman with 102 styles
Nimbus Sans with 86 styles
Nimbus Sans Narrow with 70 styles
Noto Sans with 224 styles
Noto Sans CJK HK with 695 styles
Noto Sans CJK JP with 695 styles
Noto Sans CJK KR with 695 styles
Noto Sans CJK SC with 695 styles
Noto Sans CJK TC with 695 styles
Noto Sans Math with 147 styles
Noto Sans Mono with 109 styles
Noto Sans Mono CJK HK with 670 styles
Noto Sans Mono CJK JP with 670 styles
Noto Sans Mono CJK KR with 670 styles
Noto Sans Mono CJK SC with 670 styles
Noto Sans Mono CJK TC with 670 styles
Noto Sans Sinhala with 106 styles
Noto Sans Symbols with 105 styles
Noto Serif with 178 styles
Noto Serif CJK HK with 645 styles
Noto Serif CJK JP with 645 styles
Noto Serif CJK KR with 645 styles
Noto Serif CJK SC with 645 styles
Noto Serif CJK TC with 645 styles
Open Sans with 605 styles
P052 with 54 styles
Padauk with 93 styles
PakType Naskh Basic with 55 styles
PakType Naskh Basic Semi Wide with 54 styles
PakType Naskh Basic Wide with 53 styles
RIT Meera New with 52 styles
RIT Rachana with 198 styles
STIX Two Math with 45 styles
STIX Two Text with 324 styles
Standard Symbols PS with 11 styles
Symbola with 165 styles
URW Bookman with 34 styles
URW Gothic with 18 styles
Vazirmatn with 1 style
Z003 with 2 styles
I had intended to submit a PR (implementing ScannedFont registration directly within the scan_path callback) to fix this issue. However, given that the current implementation is quite messy, I am not confident that I understand the rationale behind the current design, so I have opted to submit an issue instead.
Additionally, these two lines of code also seem very strange and redundant. This is just an extra found and is unrelated to the issue mentioned above.
Description
When using
Collection::load_fonts_from_pathsto register fonts from a directory, the resulting Collection contains duplicate entries for the same font file.Cause
Currently, the
load_fonts_from_pathfunction contains afamiliesmap inside it, and each time thescan_pathcallback is triggered, theregister_font_implit calls adds all fonts in thisfamiliesmap toself.families. Throughout the entire process,familiesis never cleared.At the same time, it is quite strange that while the
scan_pathcallback already returnsScannedFont,register_font_implstill usesscan_memoryto re-process all fonts in the data. This not only causes performance issues but also leads to further font duplication when processing TTC files...For example, when I was testing on Linux, I encountered this spectacle:
❯ cargo run --release -- a --no-system -I /usr/share/fonts Finished `release` profile [optimized] target(s) in 0.87s Running `target/release/fontfor a --no-system -I /usr/share/fonts` Font(s) support the character "a"(U+0061, 97, 0x61): Adwaita Mono with 690 styles Adwaita Sans with 339 styles C059 with 138 styles Cantarell with 1065 styles D050000L with 32 styles Droid Sans with 323 styles Droid Sans Devanagari with 159 styles Droid Sans Thai with 149 styles Font Awesome 6 Brands with 168 styles Font Awesome 6 Free with 333 styles Jomolhari with 79 styles Liberation Mono with 306 styles Liberation Sans with 290 styles Liberation Serif with 274 styles Madan2 with 66 styles Nimbus Mono PS with 118 styles Nimbus Roman with 102 styles Nimbus Sans with 86 styles Nimbus Sans Narrow with 70 styles Noto Sans with 224 styles Noto Sans CJK HK with 695 styles Noto Sans CJK JP with 695 styles Noto Sans CJK KR with 695 styles Noto Sans CJK SC with 695 styles Noto Sans CJK TC with 695 styles Noto Sans Math with 147 styles Noto Sans Mono with 109 styles Noto Sans Mono CJK HK with 670 styles Noto Sans Mono CJK JP with 670 styles Noto Sans Mono CJK KR with 670 styles Noto Sans Mono CJK SC with 670 styles Noto Sans Mono CJK TC with 670 styles Noto Sans Sinhala with 106 styles Noto Sans Symbols with 105 styles Noto Serif with 178 styles Noto Serif CJK HK with 645 styles Noto Serif CJK JP with 645 styles Noto Serif CJK KR with 645 styles Noto Serif CJK SC with 645 styles Noto Serif CJK TC with 645 styles Open Sans with 605 styles P052 with 54 styles Padauk with 93 styles PakType Naskh Basic with 55 styles PakType Naskh Basic Semi Wide with 54 styles PakType Naskh Basic Wide with 53 styles RIT Meera New with 52 styles RIT Rachana with 198 styles STIX Two Math with 45 styles STIX Two Text with 324 styles Standard Symbols PS with 11 styles Symbola with 165 styles URW Bookman with 34 styles URW Gothic with 18 styles Vazirmatn with 1 style Z003 with 2 stylesI had intended to submit a PR (implementing
ScannedFontregistration directly within thescan_pathcallback) to fix this issue. However, given that the current implementation is quite messy, I am not confident that I understand the rationale behind the current design, so I have opted to submit an issue instead.Additionally, these two lines of code also seem very strange and redundant. This is just an extra found and is unrelated to the issue mentioned above.