From b54dd3c0594ca8cbefdf0c56cbef95bcb1eb7bf1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 22 Jun 2008 14:53:20 -0700 Subject: [PATCH] IGN:Fix fontconfig on OSX and other minor fixes --- osx_installer.py | 32 +++++++-------- src/calibre/gui2/lrf_renderer/main.py | 3 +- .../gui2/pictureflow/PyQt/configure.py | 1 + src/calibre/parallel.py | 5 ++- src/calibre/utils/fontconfig.py | 41 ++++++++++++++----- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/osx_installer.py b/osx_installer.py index afe9f6fde0..c092650de6 100644 --- a/osx_installer.py +++ b/osx_installer.py @@ -39,6 +39,7 @@ print >>loader, '%(function)s()' loader.close() os.chmod(loader_path, 0700) os.environ['PYTHONHOME'] = resources_dir +os.environ['FC_CONFIG_DIR'] = os.path.join(resources_dir, 'fonts') os.execv(loader_path, sys.argv) ''' CHECK_SYMLINKS_PRESCRIPT = \ @@ -48,10 +49,9 @@ def _check_symlinks_prescript(): from Authorization import Authorization, kAuthorizationFlagDestroyRights AUTHTOOL="""#!%(sp)s -import os, shutil +import os scripts = %(sp)s links = %(sp)s -fonts_conf = %(sp)s os.setuid(0) for s, l in zip(scripts, links): if os.path.lexists(l): @@ -60,12 +60,6 @@ for s, l in zip(scripts, links): omask = os.umask(022) os.symlink(s, l) os.umask(omask) -if not os.path.exists('/etc/fonts/fonts.conf'): - print 'Creating default fonts.conf' - if not os.path.exists('/etc/fonts'): - os.makedirs('/etc/fonts') - shutil.copyfile(fonts_conf, '/etc/fonts/fonts.conf') - shutil.copyfile(fonts_conf.replace('conf', 'dtd'), '/etc/fonts/fonts.dtd') """ dest_path = %(dest_path)s @@ -73,7 +67,6 @@ if not os.path.exists('/etc/fonts/fonts.conf'): scripts = %(scripts)s links = [os.path.join(dest_path, i) for i in scripts] scripts = [os.path.join(resources_path, 'loaders', i) for i in scripts] - fonts_conf = os.path.join(resources_path, 'fonts.conf') bad = False for s, l in zip(scripts, links): @@ -81,11 +74,10 @@ if not os.path.exists('/etc/fonts/fonts.conf'): continue bad = True break - bad = bad or not os.path.exists('/etc/fonts/fonts.conf') if bad: auth = Authorization(destroyflags=(kAuthorizationFlagDestroyRights,)) fd, name = tempfile.mkstemp('.py') - os.write(fd, AUTHTOOL %(pp)s (sys.executable, repr(scripts), repr(links), repr(fonts_conf))) + os.write(fd, AUTHTOOL %(pp)s (sys.executable, repr(scripts), repr(links))) os.close(fd) os.chmod(name, 0700) try: @@ -249,13 +241,18 @@ _check_symlinks_prescript() print 'Adding plugins' module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload') print 'Adding fontconfig' - for f in glob.glob(os.path.expanduser('~/fontconfig/*')): + for f in glob.glob(os.path.expanduser('~/fontconfig2/*')): os.link(f, os.path.join(frameworks_dir, os.path.basename(f))) for src, dest in plugin_files: if 'dylib' in dest: os.link(src, os.path.join(frameworks_dir, dest)) else: os.link(src, os.path.join(module_dir, dest)) + dst = os.path.join(resource_dir, 'fonts') + if os.path.exists(dst): + shutil.rmtree(dst) + shutil.copytree('/usr/local/etc/fonts', dst, symlinks=False) + print print 'Adding IPython' dst = os.path.join(resource_dir, 'lib', 'python2.5', 'IPython') @@ -286,10 +283,6 @@ sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), ' f.write(script, script.partition('/')[-1]) f.close() print - print 'Adding default fonts.conf' - open(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'fonts.conf'), 'wb').write(open('/etc/fonts/fonts.conf').read()) - open(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'fonts.dtd'), 'wb').write(open('/etc/fonts/fonts.dtd').read()) - print print 'Building disk image' BuildAPP.makedmg(os.path.join(self.dist_dir, APPNAME+'.app'), APPNAME+'-'+VERSION) @@ -312,7 +305,7 @@ def main(): 'mechanize', 'ClientForm', 'usbobserver', 'genshi', 'calibre.web.feeds.recipes.*', 'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*', - 'keyword', 'codeop', 'pydoc'], + 'keyword', 'codeop', 'pydoc', 'readline'], 'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'], 'excludes' : ['IPython'], 'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.''' @@ -322,7 +315,10 @@ def main(): 'CFBundleVersion':APPNAME + ' ' + VERSION, 'LSMinimumSystemVersion':'10.4.3', 'LSMultipleInstancesProhibited':'true', - 'NSHumanReadableCopyright':'Copyright 2006, Kovid Goyal', + 'NSHumanReadableCopyright':'Copyright 2008, Kovid Goyal', + 'LSEnvironment':{ + 'FC_CONFIG_DIR':'@executable_path/../Resources/fonts', + } }, }, }, diff --git a/src/calibre/gui2/lrf_renderer/main.py b/src/calibre/gui2/lrf_renderer/main.py index 35c32e9226..6dd5722bd9 100644 --- a/src/calibre/gui2/lrf_renderer/main.py +++ b/src/calibre/gui2/lrf_renderer/main.py @@ -3,7 +3,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' import sys, logging, os, traceback, time -from PyQt4.QtGui import QKeySequence, QPainter, QDialog, QSpinBox, QSlider +from PyQt4.QtGui import QKeySequence, QPainter, QDialog, QSpinBox, QSlider, QIcon from PyQt4.QtCore import Qt, QObject, SIGNAL, QCoreApplication, QThread from calibre import __appname__, setup_cli_handlers, islinux, Settings @@ -300,6 +300,7 @@ def main(args=sys.argv, logger=None): pid = os.fork() if islinux else -1 if pid <= 0: app = Application(args) + app.setWindowIcon(QIcon(':/images/viewer.svg')) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) opts = normalize_settings(parser, opts) diff --git a/src/calibre/gui2/pictureflow/PyQt/configure.py b/src/calibre/gui2/pictureflow/PyQt/configure.py index e24e9a8405..8b6295d817 100644 --- a/src/calibre/gui2/pictureflow/PyQt/configure.py +++ b/src/calibre/gui2/pictureflow/PyQt/configure.py @@ -43,6 +43,7 @@ else: makefile.extra_lib_dirs = ['..\\..\\.build\\release', '../../.build', '.'] makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"] makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] +makefile.extra_lflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] makefile.extra_cxxflags = makefile.extra_cflags # Generate the Makefile itself. diff --git a/src/calibre/parallel.py b/src/calibre/parallel.py index 51a9cf97b8..e174f37c7c 100644 --- a/src/calibre/parallel.py +++ b/src/calibre/parallel.py @@ -539,7 +539,10 @@ class Server(Thread): with self.pool_lock: self.pool.append(o) - time.sleep(1) + try: + time.sleep(1) + except: + return def killall(self): diff --git a/src/calibre/utils/fontconfig.py b/src/calibre/utils/fontconfig.py index 9d96de0a76..fe2261d853 100644 --- a/src/calibre/utils/fontconfig.py +++ b/src/calibre/utils/fontconfig.py @@ -23,7 +23,7 @@ match to a given font specification. The main functions in this module are: ''' import sys, os, locale, codecs -from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, \ +from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, util, \ pointer, byref, create_string_buffer, Union, c_char_p, c_double try: @@ -36,18 +36,20 @@ iswindows = 'win32' in sys.platform or 'win64' in sys.platform isosx = 'darwin' in sys.platform def load_library(): - if isosx: - lib = 'libfontconfig.1.dylib' - if hasattr(sys, 'frameworks_dir'): - lib = os.path.join(getattr(sys, 'frameworks_dir'), lib) + if isosx: + lib = os.path.join(getattr(sys, 'frameworks_dir'), 'libfontconfig.1.dylib') \ + if hasattr(sys, 'frameworks_dir') else util.find_library('fontconfig') return cdll.LoadLibrary(lib) elif iswindows: return cdll.LoadLibrary('libfontconfig-1') else: try: - return cdll.LoadLibrary('libfontconfig.so') + return cdll.LoadLibrary(util.find_library('fontconfig')) except: - return cdll.LoadLibrary('libfontconfig.so.1') + try: + return cdll.LoadLibrary('libfontconfig.so') + except: + return cdll.LoadLibrary('libfontconfig.so.1') class FcPattern(Structure): _fields_ = [ @@ -118,9 +120,29 @@ lib.FcFontSort.argtypes = [c_void_p, POINTER(FcPattern), c_int, c_void_p, POINTE lib.FcFontSort.restype = POINTER(FcFontSet) lib.FcFontRenderPrepare.argtypes = [c_void_p, POINTER(FcPattern), POINTER(FcPattern)] lib.FcFontRenderPrepare.restype = POINTER(FcPattern) +lib.FcConfigCreate.restype = c_void_p +lib.FcConfigSetCurrent.argtypes = [c_void_p] +lib.FcConfigSetCurrent.restype = c_int +lib.FcConfigParseAndLoad.argtypes = [c_void_p, POINTER(c_char), c_int] +lib.FcConfigParseAndLoad.restype = c_int +lib.FcConfigBuildFonts.argtypes = [c_void_p] +lib.FcConfigBuildFonts.restype = c_int -if not lib.FcInit(): +# Initialize the fontconfig library. This has to be done manually +# for the OS X bundle as it has its own private fontconfig. +if hasattr(sys, 'frameworks_dir'): + config_dir = os.path.join(os.path.dirname(getattr(sys, 'frameworks_dir')), 'Resources', 'fonts') + if isinstance(config_dir, unicode): + 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') + if not lib.FcConfigBuildFonts(config): + raise RuntimeError('Could not build fonts') + if not lib.FcConfigSetCurrent(config): + raise RuntimeError('Could not set font config') +elif not lib.FcInit(): raise RuntimeError(_('Could not initialize the fontconfig library')) def find_font_families(allowed_extensions=['ttf']): @@ -151,11 +173,10 @@ def find_font_families(allowed_extensions=['ttf']): ext = os.path.splitext(path)[1] if ext: ext = ext[1:].lower() - if allowed_extensions and ext in allowed_extensions: + if (not allowed_extensions) or (allowed_extensions and ext in allowed_extensions): if lib.FcPatternGetString(pat, 'family', 0, byref(family)) != FcResultMatch.value: raise RuntimeError('Error processing pattern') font_families.append(str(family.contents.value)) - lib.FcObjectSetDestroy(oset) lib.FcPatternDestroy(empty_pattern)