Move scanning of system fonts into a separate thread. This will greatly reduce first run startup times.

This commit is contained in:
Kovid Goyal 2008-07-16 23:42:41 -07:00
parent 28a93ca9c7
commit e6bfebed5a
2 changed files with 39 additions and 15 deletions

View File

@ -59,6 +59,9 @@ class Main(MainWindow, Ui_MainWindow):
def __init__(self, single_instance, opts, parent=None):
MainWindow.__init__(self, opts, parent)
# Initialize fontconfig in a separate thread as this can be a lengthy
# process if run for the first time on this machine
self.fc = __import__('calibre.utils.fontconfig', fromlist=1)
self.single_instance = single_instance
if self.single_instance is not None:
self.connect(self.single_instance, SIGNAL('message_received(PyQt_PyObject)'),

View File

@ -128,7 +128,10 @@ lib.FcConfigParseAndLoad.restype = c_int
lib.FcConfigBuildFonts.argtypes = [c_void_p]
lib.FcConfigBuildFonts.restype = c_int
_init_error = None
_initialized = False
from threading import Timer
def _do_init():
# Initialize the fontconfig library. This has to be done manually
# for the OS X bundle as it may have its own private fontconfig.
if hasattr(sys, 'frameworks_dir'):
@ -137,13 +140,28 @@ if hasattr(sys, 'frameworks_dir'):
config_dir = config_dir.encode(sys.getfilesystemencoding())
config = lib.FcConfigCreate()
if not lib.FcConfigParseAndLoad(config, os.path.join(config_dir, 'fonts.conf'), 1):
raise RuntimeError('Could not parse the fontconfig configuration')
_init_error = 'Could not parse the fontconfig configuration'
return
if not lib.FcConfigBuildFonts(config):
raise RuntimeError('Could not build fonts')
_init_error = 'Could not build fonts'
return
if not lib.FcConfigSetCurrent(config):
raise RuntimeError('Could not set font config')
_init_error = 'Could not set font config'
return
elif not lib.FcInit():
raise RuntimeError(_('Could not initialize the fontconfig library'))
_init_error = _('Could not initialize the fontconfig library')
return
global _initialized
_initialized = True
_init_timer = Timer(0.1, _do_init)
_init_timer.start()
def join():
_init_timer.join()
if _init_error is not None:
raise RuntimeError(_init_error)
def find_font_families(allowed_extensions=['ttf', 'otf']):
'''
@ -152,6 +170,7 @@ def find_font_families(allowed_extensions=['ttf', 'otf']):
`allowed_extensions`: A list of allowed extensions for font file types. Defaults to
`['ttf', 'otf']`. If it is empty, it is ignored.
'''
join()
allowed_extensions = [i.lower() for i in allowed_extensions]
empty_pattern = lib.FcPatternCreate()
@ -193,6 +212,7 @@ def files_for_family(family, normalize=True):
they are a tuple (slant, weight) otherwise they are strings from the set
`('normal', 'bold', 'italic', 'bi', 'light', 'li')`
'''
join()
if isinstance(family, unicode):
family = family.encode(preferred_encoding)
family_pattern = lib.FcPatternBuild(0, 'family', FcTypeString, family, 0)
@ -268,6 +288,7 @@ def match(name, sort=False, verbose=False):
decreasing closeness of matching.
`verbose`: If `True` print debugging information to stdout
'''
join()
if isinstance(name, unicode):
name = name.encode(preferred_encoding)
pat = lib.FcNameParse(name)