diff --git a/session.vim b/session.vim index c60bcbdf4f..079975f8d4 100644 --- a/session.vim +++ b/session.vim @@ -9,6 +9,7 @@ let g:syntastic_cpp_include_dirs = [ \'/usr/include/qt4/QtGui', \'/usr/include/qt4', \'/usr/include/freetype2', + \'/usr/include/fontconfig', \'src/qtcurve/common', 'src/qtcurve', \'/usr/include/ImageMagick', \] diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 31ce61328a..1fce4a9da6 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -329,6 +329,7 @@ def get_parsed_proxy(typ='http', debug=True): ans['port'] = int(ans['port']) except: if debug: + import traceback traceback.print_exc() else: if debug: @@ -689,26 +690,18 @@ def remove_bracketed_text(src, buf.append(char) return u''.join(buf) -if isosx: - import glob, shutil - fdir = os.path.expanduser('~/.fonts') - try: - if not os.path.exists(fdir): - os.makedirs(fdir) - if not os.path.exists(os.path.join(fdir, 'LiberationSans_Regular.ttf')): - base = P('fonts/liberation/*.ttf') - for f in glob.glob(base): - shutil.copy2(f, fdir) - except: - import traceback - traceback.print_exc() - def load_builtin_fonts(): - import glob - from PyQt4.Qt import QFontDatabase - base = P('fonts/liberation/*.ttf') - for f in glob.glob(base): - QFontDatabase.addApplicationFont(f) + if iswindows or isosx: + import glob + from PyQt4.Qt import QFontDatabase + for f in glob.glob(P('fonts/liberation/*.ttf')): + QFontDatabase.addApplicationFont(f) + else: + # On linux these are loaded by fontconfig which means that + # they are available to Qt as well, since Qt uses fontconfig + from calibre.utils.fonts import fontconfig + fontconfig + return 'Liberation Serif', 'Liberation Sans', 'Liberation Mono' diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 0ac0783bd5..688b134f0e 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -12,7 +12,7 @@ from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, ORG_NAME = 'KovidsBrain' APP_UID = 'libprs500' -from calibre import prints +from calibre import prints, load_builtin_fonts from calibre.constants import (islinux, iswindows, isbsd, isfrozen, isosx, plugins, config_dir, filesystem_encoding, DEBUG) from calibre.utils.config import Config, ConfigProxy, dynamic, JSONConfig @@ -779,6 +779,7 @@ class Application(QApplication): qt_app = self self._file_open_paths = [] self._file_open_lock = RLock() + load_builtin_fonts() self.setup_styles(force_calibre_style) if DEBUG: diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 8ea9c26d00..33b36cf6ec 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -16,7 +16,7 @@ from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings from calibre.gui2.viewer.flip import SlideFlip from calibre.gui2.shortcuts import Shortcuts -from calibre import prints, load_builtin_fonts +from calibre import prints from calibre.customize.ui import all_viewer_plugins from calibre.gui2.viewer.keys import SHORTCUTS from calibre.gui2.viewer.javascript import JavaScriptLoader @@ -86,7 +86,6 @@ class Document(QWebPage): # {{{ settings = self.settings() # Fonts - load_builtin_fonts() self.all_viewer_plugins = tuple(all_viewer_plugins()) for pl in self.all_viewer_plugins: pl.load_fonts() diff --git a/src/calibre/utils/fonts/__init__.py b/src/calibre/utils/fonts/__init__.py index e245b1536c..85bcd8eb39 100644 --- a/src/calibre/utils/fonts/__init__.py +++ b/src/calibre/utils/fonts/__init__.py @@ -111,9 +111,9 @@ fontconfig = Fonts() def test(): import os print(fontconfig.find_font_families()) - m = 'times new roman' if iswindows else 'liberation serif' + m = 'Liberation Serif' for ft, val in fontconfig.files_for_family(m).iteritems(): - print val[0], ft, val[1], os.path.getsize(val[1]) + print val[0], ft, val[1], os.path.getsize(val[0]) if __name__ == '__main__': test() diff --git a/src/calibre/utils/fonts/fc.py b/src/calibre/utils/fonts/fc.py index b6a4b1f906..793ee9b6b1 100644 --- a/src/calibre/utils/fonts/fc.py +++ b/src/calibre/utils/fonts/fc.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import os, sys -from calibre.constants import plugins, iswindows, islinux, isbsd +from calibre.constants import plugins, islinux, isbsd _fc, _fc_err = plugins['fontconfig'] @@ -35,18 +35,14 @@ class FontConfig(Thread): if isinstance(config_dir, unicode): config_dir = config_dir.encode(sys.getfilesystemencoding()) config = os.path.join(config_dir, 'fonts.conf') - if iswindows and getattr(sys, 'frozen', False): - config_dir = os.path.join(os.path.dirname(sys.executable), - 'fontconfig') - if isinstance(config_dir, unicode): - config_dir = config_dir.encode(sys.getfilesystemencoding()) - config = os.path.join(config_dir, 'fonts.conf') try: _fc.initialize(config) except: import traceback traceback.print_exc() self.failed = True + if not self.failed and hasattr(_fc, 'add_font_dir'): + _fc.add_font_dir(P('fonts/liberation')) def wait(self): if not (islinux or isbsd): @@ -162,7 +158,7 @@ def test(): from pprint import pprint; pprint(fontconfig.find_font_families()) pprint(fontconfig.files_for_family('liberation serif')) - m = 'times new roman' if iswindows else 'liberation serif' + m = 'liberation serif' pprint(fontconfig.match(m+':slant=italic:weight=bold', verbose=True)) if __name__ == '__main__': diff --git a/src/calibre/utils/fonts/fontconfig.c b/src/calibre/utils/fonts/fontconfig.c index d8f7190798..be1cbdce13 100644 --- a/src/calibre/utils/fonts/fontconfig.c +++ b/src/calibre/utils/fonts/fontconfig.c @@ -44,6 +44,17 @@ fontconfig_initialize(PyObject *self, PyObject *args) { Py_RETURN_FALSE; } +static PyObject* +fontconfig_add_font_dir(PyObject *self, PyObject *args) { + FcChar8 *path; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (FcConfigAppFontAddDir(NULL, path)) + Py_RETURN_TRUE; + Py_RETURN_FALSE; +} + static void fontconfig_cleanup_find(FcPattern *p, FcObjectSet *oset, FcFontSet *fs) { if (p != NULL) FcPatternDestroy(p); @@ -314,6 +325,11 @@ PyMethodDef fontconfig_methods[] = { }, + {"add_font_dir", fontconfig_add_font_dir, METH_VARARGS, + "add_font_dir(path_to_dir)\n\n" + "Add the fonts in the specified directory to the list of application specific fonts." + }, + {NULL, NULL, 0, NULL} }; diff --git a/src/calibre/utils/fonts/win_fonts.py b/src/calibre/utils/fonts/win_fonts.py index 747580d45e..9fcf5df226 100644 --- a/src/calibre/utils/fonts/win_fonts.py +++ b/src/calibre/utils/fonts/win_fonts.py @@ -19,6 +19,23 @@ class WinFonts(object): def __init__(self, winfonts): self.w = winfonts + # Windows thinks the Liberation font files are not valid, so we use + # this hack to make them available + self.app_font_families = {} + + for f in ('Serif', 'Sans', 'Mono'): + base = 'fonts/liberation/Liberation%s-%s.ttf' + self.app_font_families['Liberation %s'%f] = m = {} + for weight, is_italic in product( (self.w.FW_NORMAL, self.w.FW_BOLD), (False, True) ): + name = {(self.w.FW_NORMAL, False):'Regular', + (self.w.FW_NORMAL, True):'Italic', + (self.w.FW_BOLD, False):'Bold', + (self.w.FW_BOLD, True):'BoldItalic'}[(weight, + is_italic)] + m[(weight, is_italic)] = base%(f, name) + + # import pprint + # pprint.pprint(self.app_font_families) def font_families(self): names = set() @@ -30,7 +47,7 @@ class WinFonts(object): not font['name'].startswith('@') ): names.add(font['name']) - return sorted(names) + return sorted(names.union(frozenset(self.app_font_families))) def get_normalized_name(self, is_italic, weight): if is_italic: @@ -43,12 +60,18 @@ class WinFonts(object): family = type(u'')(family) ans = {} for weight, is_italic in product( (self.w.FW_NORMAL, self.w.FW_BOLD), (False, True) ): - try: - data = self.w.font_data(family, is_italic, weight) - except Exception as e: - prints('Failed to get font data for font: %s [%s] with error: %s'% - (family, self.get_normalized_name(is_italic, weight), e)) - continue + if family in self.app_font_families: + m = self.app_font_families[family] + path = m.get((weight, is_italic), None) + if path is None: continue + data = P(path, data=True) + else: + try: + data = self.w.font_data(family, is_italic, weight) + except Exception as e: + prints('Failed to get font data for font: %s [%s] with error: %s'% + (family, self.get_normalized_name(is_italic, weight), e)) + continue ok, sig = is_truetype_font(data) if not ok: @@ -122,7 +145,7 @@ def test_ttf_reading(): get_font_characteristics(raw) print() -if __name__ == '__main__': +def test(): base = os.path.abspath(__file__) d = os.path.dirname pluginsd = os.path.join(d(d(d(base))), 'plugins') @@ -143,3 +166,5 @@ if __name__ == '__main__': prints(' ', font, data[0], data[1], len(data[2])) print () +if __name__ == '__main__': + test()