Skip to content

Commit dfe6e61

Browse files
committed
Update font registry on windows
1 parent ed23e67 commit dfe6e61

3 files changed

Lines changed: 98 additions & 40 deletions

File tree

.github/workflows/ci.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ jobs:
3939
sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config
4040
pip install --upgrade pip setuptools pytest-tldr
4141
pip install -e .
42+
- name: Install fonts
43+
run: |
44+
xvfb-run -a -s '-screen 0 2048x1536x24' python tests/utils.py
4245
- name: Test
4346
run: |
4447
xvfb-run -a -s '-screen 0 2048x1536x24' python setup.py test
@@ -62,6 +65,9 @@ jobs:
6265
sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config
6366
pip install --upgrade pip setuptools
6467
pip install -e .
68+
- name: Install fonts
69+
run: |
70+
xvfb-run -a -s '-screen 0 2048x1536x24' python tests/utils.py
6571
- name: Test
6672
run: |
6773
xvfb-run -a -s '-screen 0 2048x1536x24' python setup.py test
@@ -80,9 +86,11 @@ jobs:
8086
run: |
8187
pip install --upgrade pip setuptools
8288
pip install -e .
83-
- name: Test
89+
- name: Install fonts
8490
run: |
8591
python tests/utils.py
92+
- name: Test
93+
run: |
8694
python setup.py test
8795
8896
macOS:
@@ -99,7 +107,9 @@ jobs:
99107
run: |
100108
pip install --upgrade pip setuptools
101109
pip install -e .
102-
- name: Test
110+
- name: Install fonts
103111
run: |
104112
python tests/utils.py
113+
- name: Test
114+
run: |
105115
python setup.py test

colosseum/fonts.py

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ def validate_font_family(cls, value):
2828

2929
raise ValidationError('Font family "{value}" not found on system!'.format(value=value))
3030

31+
@staticmethod
32+
def fonts_path(system=False):
33+
"""Return the path for cross platform user fonts."""
34+
if os.name == 'nt':
35+
import winreg
36+
if system:
37+
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings(r'%windir%'), 'Fonts')
38+
else:
39+
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings(r'%LocalAppData%'),
40+
'Microsoft', 'Windows', 'Fonts')
41+
elif sys.platform == 'darwin':
42+
if system:
43+
fonts_dir = os.path.expanduser('/Library/Fonts')
44+
else:
45+
fonts_dir = os.path.expanduser('~/Library/Fonts')
46+
elif sys.platform.startswith('linux'):
47+
if system:
48+
fonts_dir = os.path.expanduser('/usr/local/share/fonts')
49+
else:
50+
fonts_dir = os.path.expanduser('~/.local/share/fonts/')
51+
else:
52+
raise NotImplementedError('System not supported!')
53+
54+
return fonts_dir
55+
3156

3257
def _check_font_family_mac(value):
3358
"""List available font family names on mac."""
@@ -58,9 +83,11 @@ class Window(Gtk.Window):
5883
def check_system_font(self, value):
5984
"""Check if font family exists on system."""
6085
context = self.create_pango_context()
61-
for fam in context.list_families():
62-
if fam.get_name() == value:
86+
for font_family in context.list_families():
87+
font_name = font_family.get_name()
88+
if font_name == value:
6389
return True
90+
6491
return False
6592

6693
global _GTK_WINDOW # noqa
@@ -72,16 +99,17 @@ def check_system_font(self, value):
7299

73100
def _check_font_family_win(value):
74101
"""List available font family names on windows."""
75-
import winreg
76-
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
77-
r"Software\Microsoft\Windows NT\CurrentVersion\Fonts",
78-
0,
79-
winreg.KEY_READ)
80-
for idx in range(0, winreg.QueryInfoKey(key)[1]):
81-
font_name = winreg.EnumValue(key, idx)[0]
82-
font_name = font_name.replace(' (TrueType)', '')
83-
if font_name == value:
84-
return True
102+
import winreg # noqa
103+
for base in [winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER]:
104+
key = winreg.OpenKey(base,
105+
r"Software\Microsoft\Windows NT\CurrentVersion\Fonts",
106+
0,
107+
winreg.KEY_READ)
108+
for idx in range(0, winreg.QueryInfoKey(key)[1]):
109+
font_name = winreg.EnumValue(key, idx)[0]
110+
font_name = font_name.replace(' (TrueType)', '')
111+
if font_name == value:
112+
return True
85113

86114
return False
87115

@@ -95,15 +123,15 @@ def check_font_family(value):
95123
elif os.name == 'nt':
96124
return _check_font_family_win(value)
97125
else:
98-
raise NotImplementedError('Cannot request fonts on this system!')
126+
raise NotImplementedError('Cannot check font existence on this system!')
99127

100128

101129
def get_system_font(keyword):
102130
"""Return a font object from given system font keyword."""
103131
from .constants import SYSTEM_FONT_KEYWORDS # noqa
104132

105133
if keyword in SYSTEM_FONT_KEYWORDS:
106-
# Get the system font
134+
# TODO: Get the system font that corresponds
107135
return 'Ahem'
108136

109137
return None

tests/utils.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,44 +156,60 @@ def output_layout(layout, depth=1):
156156
return (' ' * depth + "* '{text}'\n".format(text=layout['text'].strip()))
157157

158158

159-
def fonts_path(system=False):
160-
"""Return the path for cross platform user fonts."""
161-
if os.name == 'nt':
162-
import winreg
163-
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings('%windir%'), 'fonts')
164-
elif sys.platform == 'darwin':
165-
if system:
166-
fonts_dir = os.path.expanduser('/Library/Fonts')
167-
else:
168-
fonts_dir = os.path.expanduser('~/Library/Fonts')
169-
elif sys.platform.startswith('linux'):
170-
fonts_dir = os.path.expanduser('~/.local/share/fonts/')
171-
else:
172-
raise NotImplementedError('System not supported!')
173-
174-
return fonts_dir
175-
176-
177159
def copy_fonts(system=False):
178160
"""Copy needed files for running tests."""
179-
fonts_folder = fonts_path(system=system)
161+
fonts_folder = FontDatabase.fonts_path(system=system)
162+
180163
if not os.path.isdir(fonts_folder):
181164
os.makedirs(fonts_folder)
165+
182166
fonts_data_path = os.path.join(HERE, 'data', 'fonts')
183167
font_files = sorted([item for item in os.listdir(fonts_data_path) if item.endswith('.ttf')])
184168
for font_file in font_files:
185169
font_file_data_path = os.path.join(fonts_data_path, font_file)
186170
font_file_path = os.path.join(fonts_folder, font_file)
171+
187172
if not os.path.isfile(font_file_path):
188173
shutil.copyfile(font_file_data_path, font_file_path)
174+
# Register font
175+
176+
if os.name == 'nt':
177+
import winreg # noqa
178+
base_key = winreg.HKEY_LOCAL_MACHINE if system else winreg.HKEY_CURRENT_USER
179+
key_path = r"Software\Microsoft\Windows NT\CurrentVersion\Fonts"
180+
181+
if '_' in font_file:
182+
font_name = font_file.split('_')[-1].split('.')[0]
183+
else:
184+
font_name = font_file.split('.')[0]
185+
186+
# This font has a space in its system name
187+
if font_name == 'WhiteSpace':
188+
font_name = 'White Space'
189+
190+
font_name = font_name + ' (TrueType)'
191+
192+
with winreg.OpenKey(base_key, key_path, 0, winreg.KEY_ALL_ACCESS) as reg_key:
193+
value = None
194+
try:
195+
# Query if it exists
196+
value = winreg.QueryValueEx(reg_key, font_name)
197+
except FileNotFoundError:
198+
pass
199+
200+
# If it does not exists, add value
201+
if value != font_file_path:
202+
winreg.SetValueEx(reg_key, font_name, 0, winreg.REG_SZ, font_file_path)
189203

190204

191205
class ColosseumTestCase(TestCase):
192206
"""Install test fonts before running tests that use them."""
207+
_FONTS_ACTIVE = False
193208

194209
def __init__(self, *args, **kwargs):
195210
super().__init__(*args, **kwargs)
196-
self.copy_fonts()
211+
if self._FONTS_ACTIVE is False:
212+
self.copy_fonts()
197213

198214
def copy_fonts(self):
199215
copy_fonts()
@@ -204,6 +220,8 @@ def copy_fonts(self):
204220
raise Exception('\n\nTesting fonts (Ahem & Ahem Extra) are not active.\n'
205221
'\nPlease run the test suite one more time.\n')
206222

223+
ColosseumTestCase._FONTS_ACTIVE = True
224+
207225

208226
class LayoutTestCase(ColosseumTestCase):
209227
def setUp(self):
@@ -451,7 +469,9 @@ def test_method(self):
451469

452470

453471
if __name__ == '__main__':
454-
print('Copying test fonts...')
455-
print(fonts_path(system=True))
456-
copy_fonts(system=True)
457-
print(list(sorted(os.listdir(fonts_path()))))
472+
# On CI we use system font locations except for linux containers
473+
system = bool(os.environ.get('GITHUB_WORKSPACE', None))
474+
if sys.platform.startswith('linux'):
475+
system = False
476+
print('Copying test fonts to "{path}"...'.format(path=FontDatabase.fonts_path(system=system)))
477+
copy_fonts(system=system)

0 commit comments

Comments
 (0)