Skip to content

Commit

Permalink
Update font registry on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca committed Jan 10, 2020
1 parent ed23e67 commit dfe6e61
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 40 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config
pip install --upgrade pip setuptools pytest-tldr
pip install -e .
- name: Install fonts
run: |
xvfb-run -a -s '-screen 0 2048x1536x24' python tests/utils.py
- name: Test
run: |
xvfb-run -a -s '-screen 0 2048x1536x24' python setup.py test
Expand All @@ -62,6 +65,9 @@ jobs:
sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-dev libgirepository1.0-dev libcairo2-dev pkg-config
pip install --upgrade pip setuptools
pip install -e .
- name: Install fonts
run: |
xvfb-run -a -s '-screen 0 2048x1536x24' python tests/utils.py
- name: Test
run: |
xvfb-run -a -s '-screen 0 2048x1536x24' python setup.py test
Expand All @@ -80,9 +86,11 @@ jobs:
run: |
pip install --upgrade pip setuptools
pip install -e .
- name: Test
- name: Install fonts
run: |
python tests/utils.py
- name: Test
run: |
python setup.py test
macOS:
Expand All @@ -99,7 +107,9 @@ jobs:
run: |
pip install --upgrade pip setuptools
pip install -e .
- name: Test
- name: Install fonts
run: |
python tests/utils.py
- name: Test
run: |
python setup.py test
56 changes: 42 additions & 14 deletions colosseum/fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,31 @@ def validate_font_family(cls, value):

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

@staticmethod
def fonts_path(system=False):
"""Return the path for cross platform user fonts."""
if os.name == 'nt':
import winreg
if system:
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings(r'%windir%'), 'Fonts')
else:
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings(r'%LocalAppData%'),
'Microsoft', 'Windows', 'Fonts')
elif sys.platform == 'darwin':
if system:
fonts_dir = os.path.expanduser('/Library/Fonts')
else:
fonts_dir = os.path.expanduser('~/Library/Fonts')
elif sys.platform.startswith('linux'):
if system:
fonts_dir = os.path.expanduser('/usr/local/share/fonts')
else:
fonts_dir = os.path.expanduser('~/.local/share/fonts/')
else:
raise NotImplementedError('System not supported!')

return fonts_dir


def _check_font_family_mac(value):
"""List available font family names on mac."""
Expand Down Expand Up @@ -58,9 +83,11 @@ class Window(Gtk.Window):
def check_system_font(self, value):
"""Check if font family exists on system."""
context = self.create_pango_context()
for fam in context.list_families():
if fam.get_name() == value:
for font_family in context.list_families():
font_name = font_family.get_name()
if font_name == value:
return True

return False

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

def _check_font_family_win(value):
"""List available font family names on windows."""
import winreg
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
r"Software\Microsoft\Windows NT\CurrentVersion\Fonts",
0,
winreg.KEY_READ)
for idx in range(0, winreg.QueryInfoKey(key)[1]):
font_name = winreg.EnumValue(key, idx)[0]
font_name = font_name.replace(' (TrueType)', '')
if font_name == value:
return True
import winreg # noqa
for base in [winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER]:
key = winreg.OpenKey(base,
r"Software\Microsoft\Windows NT\CurrentVersion\Fonts",
0,
winreg.KEY_READ)
for idx in range(0, winreg.QueryInfoKey(key)[1]):
font_name = winreg.EnumValue(key, idx)[0]
font_name = font_name.replace(' (TrueType)', '')
if font_name == value:
return True

return False

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


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

if keyword in SYSTEM_FONT_KEYWORDS:
# Get the system font
# TODO: Get the system font that corresponds
return 'Ahem'

return None
68 changes: 44 additions & 24 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,44 +156,60 @@ def output_layout(layout, depth=1):
return (' ' * depth + "* '{text}'\n".format(text=layout['text'].strip()))


def fonts_path(system=False):
"""Return the path for cross platform user fonts."""
if os.name == 'nt':
import winreg
fonts_dir = os.path.join(winreg.ExpandEnvironmentStrings('%windir%'), 'fonts')
elif sys.platform == 'darwin':
if system:
fonts_dir = os.path.expanduser('/Library/Fonts')
else:
fonts_dir = os.path.expanduser('~/Library/Fonts')
elif sys.platform.startswith('linux'):
fonts_dir = os.path.expanduser('~/.local/share/fonts/')
else:
raise NotImplementedError('System not supported!')

return fonts_dir


def copy_fonts(system=False):
"""Copy needed files for running tests."""
fonts_folder = fonts_path(system=system)
fonts_folder = FontDatabase.fonts_path(system=system)

if not os.path.isdir(fonts_folder):
os.makedirs(fonts_folder)

fonts_data_path = os.path.join(HERE, 'data', 'fonts')
font_files = sorted([item for item in os.listdir(fonts_data_path) if item.endswith('.ttf')])
for font_file in font_files:
font_file_data_path = os.path.join(fonts_data_path, font_file)
font_file_path = os.path.join(fonts_folder, font_file)

if not os.path.isfile(font_file_path):
shutil.copyfile(font_file_data_path, font_file_path)
# Register font

if os.name == 'nt':
import winreg # noqa
base_key = winreg.HKEY_LOCAL_MACHINE if system else winreg.HKEY_CURRENT_USER
key_path = r"Software\Microsoft\Windows NT\CurrentVersion\Fonts"

if '_' in font_file:
font_name = font_file.split('_')[-1].split('.')[0]
else:
font_name = font_file.split('.')[0]

# This font has a space in its system name
if font_name == 'WhiteSpace':
font_name = 'White Space'

font_name = font_name + ' (TrueType)'

with winreg.OpenKey(base_key, key_path, 0, winreg.KEY_ALL_ACCESS) as reg_key:
value = None
try:
# Query if it exists
value = winreg.QueryValueEx(reg_key, font_name)
except FileNotFoundError:
pass

# If it does not exists, add value
if value != font_file_path:
winreg.SetValueEx(reg_key, font_name, 0, winreg.REG_SZ, font_file_path)


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

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.copy_fonts()
if self._FONTS_ACTIVE is False:
self.copy_fonts()

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

ColosseumTestCase._FONTS_ACTIVE = True


class LayoutTestCase(ColosseumTestCase):
def setUp(self):
Expand Down Expand Up @@ -451,7 +469,9 @@ def test_method(self):


if __name__ == '__main__':
print('Copying test fonts...')
print(fonts_path(system=True))
copy_fonts(system=True)
print(list(sorted(os.listdir(fonts_path()))))
# On CI we use system font locations except for linux containers
system = bool(os.environ.get('GITHUB_WORKSPACE', None))
if sys.platform.startswith('linux'):
system = False
print('Copying test fonts to "{path}"...'.format(path=FontDatabase.fonts_path(system=system)))
copy_fonts(system=system)

0 comments on commit dfe6e61

Please sign in to comment.