Make the bundled fonts available on all platforms

This commit is contained in:
Kovid Goyal 2012-10-22 10:56:42 +05:30
parent a69112b3e4
commit 7c18f4f0d2
8 changed files with 71 additions and 40 deletions

View File

@ -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',
\]

View File

@ -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'

View File

@ -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:

View File

@ -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()

View File

@ -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()

View File

@ -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__':

View File

@ -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}
};

View File

@ -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()