mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
On linux when searching the system for fonts, search all directories returned by fontconfig, if available, instead of a default list of directories
This commit is contained in:
parent
ec86392666
commit
e33ac985b4
@ -13,13 +13,82 @@ from threading import Thread
|
|||||||
|
|
||||||
from calibre import walk, prints, as_unicode
|
from calibre import walk, prints, as_unicode
|
||||||
from calibre.constants import (config_dir, iswindows, isosx, plugins, DEBUG,
|
from calibre.constants import (config_dir, iswindows, isosx, plugins, DEBUG,
|
||||||
isworker)
|
isworker, filesystem_encoding)
|
||||||
from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont
|
from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
|
|
||||||
class NoFonts(ValueError):
|
class NoFonts(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def default_font_dirs():
|
||||||
|
return [
|
||||||
|
'/opt/share/fonts',
|
||||||
|
'/usr/share/fonts',
|
||||||
|
'/usr/local/share/fonts',
|
||||||
|
os.path.expanduser('~/.local/share/fonts'),
|
||||||
|
os.path.expanduser('~/.fonts')
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fc_list():
|
||||||
|
import ctypes
|
||||||
|
from ctypes.util import find_library
|
||||||
|
|
||||||
|
lib = find_library('fontconfig')
|
||||||
|
if lib is None:
|
||||||
|
return default_font_dirs()
|
||||||
|
try:
|
||||||
|
lib = ctypes.CDLL(lib)
|
||||||
|
except:
|
||||||
|
return default_font_dirs()
|
||||||
|
|
||||||
|
prototype = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)
|
||||||
|
try:
|
||||||
|
get_font_dirs = prototype(('FcConfigGetFontDirs', lib))
|
||||||
|
except (AttributeError):
|
||||||
|
return default_font_dirs()
|
||||||
|
prototype = ctypes.CFUNCTYPE(ctypes.c_char_p, ctypes.c_void_p)
|
||||||
|
try:
|
||||||
|
next_dir = prototype(('FcStrListNext', lib))
|
||||||
|
except (AttributeError):
|
||||||
|
return default_font_dirs()
|
||||||
|
|
||||||
|
prototype = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
|
||||||
|
try:
|
||||||
|
end = prototype(('FcStrListDone', lib))
|
||||||
|
except (AttributeError):
|
||||||
|
return default_font_dirs()
|
||||||
|
|
||||||
|
str_list = get_font_dirs(ctypes.c_void_p())
|
||||||
|
if not str_list:
|
||||||
|
return default_font_dirs()
|
||||||
|
|
||||||
|
ans = []
|
||||||
|
while True:
|
||||||
|
d = next_dir(str_list)
|
||||||
|
if not d:
|
||||||
|
break
|
||||||
|
if d:
|
||||||
|
try:
|
||||||
|
ans.append(d.decode(filesystem_encoding))
|
||||||
|
except ValueError:
|
||||||
|
return default_font_dirs
|
||||||
|
end(str_list)
|
||||||
|
if len(ans) < 3:
|
||||||
|
return default_font_dirs()
|
||||||
|
parents = []
|
||||||
|
for f in ans:
|
||||||
|
found = False
|
||||||
|
for p in parents:
|
||||||
|
if f.startswith(p):
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
parents.append(f)
|
||||||
|
return parents
|
||||||
|
|
||||||
|
|
||||||
def font_dirs():
|
def font_dirs():
|
||||||
if iswindows:
|
if iswindows:
|
||||||
winutil, err = plugins['winutil']
|
winutil, err = plugins['winutil']
|
||||||
@ -35,12 +104,7 @@ def font_dirs():
|
|||||||
os.path.expanduser('~/.fonts'),
|
os.path.expanduser('~/.fonts'),
|
||||||
os.path.expanduser('~/Library/Fonts'),
|
os.path.expanduser('~/Library/Fonts'),
|
||||||
]
|
]
|
||||||
return [
|
return fc_list()
|
||||||
'/opt/share/fonts',
|
|
||||||
'/usr/share/fonts',
|
|
||||||
'/usr/local/share/fonts',
|
|
||||||
os.path.expanduser('~/.fonts')
|
|
||||||
]
|
|
||||||
|
|
||||||
class Scanner(Thread):
|
class Scanner(Thread):
|
||||||
|
|
||||||
@ -133,7 +197,8 @@ class Scanner(Thread):
|
|||||||
|
|
||||||
for family in self.find_font_families():
|
for family in self.find_font_families():
|
||||||
faces = filter(filter_faces, self.fonts_for_family(family))
|
faces = filter(filter_faces, self.fonts_for_family(family))
|
||||||
if not faces: continue
|
if not faces:
|
||||||
|
continue
|
||||||
generic_family = panose_to_css_generic_family(faces[0]['panose'])
|
generic_family = panose_to_css_generic_family(faces[0]['panose'])
|
||||||
if generic_family in allowed_families or generic_family == preferred_families[0]:
|
if generic_family in allowed_families or generic_family == preferred_families[0]:
|
||||||
return (family, faces)
|
return (family, faces)
|
||||||
@ -233,7 +298,8 @@ class Scanner(Thread):
|
|||||||
def build_families(self):
|
def build_families(self):
|
||||||
families = defaultdict(list)
|
families = defaultdict(list)
|
||||||
for f in self.cached_fonts.itervalues():
|
for f in self.cached_fonts.itervalues():
|
||||||
if not f: continue
|
if not f:
|
||||||
|
continue
|
||||||
lf = icu_lower(f['font-family'] or '')
|
lf = icu_lower(f['font-family'] or '')
|
||||||
if lf:
|
if lf:
|
||||||
families[lf].append(f)
|
families[lf].append(f)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user