To be able to quickly find the font I want (windows only for now) I want to create a list I can query to find the font name, family and styles available for the font.
Using fontTools and ttlib , I am able to create the list but, when the font styles are not a part of the file name, I am not able to get them.
Example, I get the styles for the Arial font if they have a different file for them:

But for Cascadia Code, one ttf, contains multiple styles:

I can see the styles on the windows app:

I found a code that does work for some fonts, but not all:
from fontTools import ttLib
path = "C:\\Windows\\Fonts\\CascadiaCode.ttf"
font = ttLib.TTFont(path)
for instance in font["fvar"].instances:
style = font["name"].getName(instance.subfamilyNameID, 3, 1, 0x409)
print(f"{family} {style}")
Which returns the right styles:
Cascadia Code ExtraLight
Cascadia Code Light
Cascadia Code SemiLight
Cascadia Code Regular
Cascadia Code SemiBold
Cascadia Code Bold
But if I use it with other fonts, ex. arial, it returns an error. Not sure why.
Here is my current code:
import os
import pandas as pd
from fontTools import ttLib
paths = []
for file in os.listdir(r'C:\Windows\fonts'):
if file.endswith('.ttf'):
font_path = os.path.join("C:\\Windows\\Fonts\\", file)
paths.append(font_path)
table = []
for p in paths:
font = ttLib.TTFont(str(p))
fontFamilyName = font['name'].getDebugName(1)
style = font['name'].getDebugName(2)
fullName= font['name'].getDebugName(3)
table.append({'family':fontFamilyName, 'name':fullName, 'style':style, 'path': p})
df=pd.DataFrame(table, columns = ['family', 'name', 'style', 'path'])
df['name'] = df['name'].str.split(':').str[-1]
df = df.drop_duplicates()
df.head()
Any ideas?Thanks.
You have a problem with "fvar" because the fvar table is only used in variable font (Cascadia is a variable font).
I recommand you to use DirectWrite instead of parsing the font manually.
This answer is based on List all system fonts as dictionary. | python