IGN:Fix fontconfig on OSX and other minor fixes

This commit is contained in:
Kovid Goyal 2008-06-22 14:53:20 -07:00
parent 564136084a
commit b54dd3c059
5 changed files with 52 additions and 30 deletions

View File

@ -39,6 +39,7 @@ print >>loader, '%(function)s()'
loader.close() loader.close()
os.chmod(loader_path, 0700) os.chmod(loader_path, 0700)
os.environ['PYTHONHOME'] = resources_dir os.environ['PYTHONHOME'] = resources_dir
os.environ['FC_CONFIG_DIR'] = os.path.join(resources_dir, 'fonts')
os.execv(loader_path, sys.argv) os.execv(loader_path, sys.argv)
''' '''
CHECK_SYMLINKS_PRESCRIPT = \ CHECK_SYMLINKS_PRESCRIPT = \
@ -48,10 +49,9 @@ def _check_symlinks_prescript():
from Authorization import Authorization, kAuthorizationFlagDestroyRights from Authorization import Authorization, kAuthorizationFlagDestroyRights
AUTHTOOL="""#!%(sp)s AUTHTOOL="""#!%(sp)s
import os, shutil import os
scripts = %(sp)s scripts = %(sp)s
links = %(sp)s links = %(sp)s
fonts_conf = %(sp)s
os.setuid(0) os.setuid(0)
for s, l in zip(scripts, links): for s, l in zip(scripts, links):
if os.path.lexists(l): if os.path.lexists(l):
@ -60,12 +60,6 @@ for s, l in zip(scripts, links):
omask = os.umask(022) omask = os.umask(022)
os.symlink(s, l) os.symlink(s, l)
os.umask(omask) 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 dest_path = %(dest_path)s
@ -73,7 +67,6 @@ if not os.path.exists('/etc/fonts/fonts.conf'):
scripts = %(scripts)s scripts = %(scripts)s
links = [os.path.join(dest_path, i) for i in scripts] links = [os.path.join(dest_path, i) for i in scripts]
scripts = [os.path.join(resources_path, 'loaders', 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 bad = False
for s, l in zip(scripts, links): for s, l in zip(scripts, links):
@ -81,11 +74,10 @@ if not os.path.exists('/etc/fonts/fonts.conf'):
continue continue
bad = True bad = True
break break
bad = bad or not os.path.exists('/etc/fonts/fonts.conf')
if bad: if bad:
auth = Authorization(destroyflags=(kAuthorizationFlagDestroyRights,)) auth = Authorization(destroyflags=(kAuthorizationFlagDestroyRights,))
fd, name = tempfile.mkstemp('.py') 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.close(fd)
os.chmod(name, 0700) os.chmod(name, 0700)
try: try:
@ -249,13 +241,18 @@ _check_symlinks_prescript()
print 'Adding plugins' print 'Adding plugins'
module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload') module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload')
print 'Adding fontconfig' 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))) os.link(f, os.path.join(frameworks_dir, os.path.basename(f)))
for src, dest in plugin_files: for src, dest in plugin_files:
if 'dylib' in dest: if 'dylib' in dest:
os.link(src, os.path.join(frameworks_dir, dest)) os.link(src, os.path.join(frameworks_dir, dest))
else: else:
os.link(src, os.path.join(module_dir, dest)) 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
print 'Adding IPython' print 'Adding IPython'
dst = os.path.join(resource_dir, 'lib', 'python2.5', '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.write(script, script.partition('/')[-1])
f.close() f.close()
print 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' print 'Building disk image'
BuildAPP.makedmg(os.path.join(self.dist_dir, APPNAME+'.app'), APPNAME+'-'+VERSION) BuildAPP.makedmg(os.path.join(self.dist_dir, APPNAME+'.app'), APPNAME+'-'+VERSION)
@ -312,7 +305,7 @@ def main():
'mechanize', 'ClientForm', 'usbobserver', 'mechanize', 'ClientForm', 'usbobserver',
'genshi', 'calibre.web.feeds.recipes.*', 'genshi', 'calibre.web.feeds.recipes.*',
'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*', 'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*',
'keyword', 'codeop', 'pydoc'], 'keyword', 'codeop', 'pydoc', 'readline'],
'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'], 'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'],
'excludes' : ['IPython'], 'excludes' : ['IPython'],
'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.''' 'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''
@ -322,7 +315,10 @@ def main():
'CFBundleVersion':APPNAME + ' ' + VERSION, 'CFBundleVersion':APPNAME + ' ' + VERSION,
'LSMinimumSystemVersion':'10.4.3', 'LSMinimumSystemVersion':'10.4.3',
'LSMultipleInstancesProhibited':'true', 'LSMultipleInstancesProhibited':'true',
'NSHumanReadableCopyright':'Copyright 2006, Kovid Goyal', 'NSHumanReadableCopyright':'Copyright 2008, Kovid Goyal',
'LSEnvironment':{
'FC_CONFIG_DIR':'@executable_path/../Resources/fonts',
}
}, },
}, },
}, },

View File

@ -3,7 +3,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import sys, logging, os, traceback, time 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 PyQt4.QtCore import Qt, QObject, SIGNAL, QCoreApplication, QThread
from calibre import __appname__, setup_cli_handlers, islinux, Settings 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 pid = os.fork() if islinux else -1
if pid <= 0: if pid <= 0:
app = Application(args) app = Application(args)
app.setWindowIcon(QIcon(':/images/viewer.svg'))
QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setOrganizationName(ORG_NAME)
QCoreApplication.setApplicationName(APP_UID) QCoreApplication.setApplicationName(APP_UID)
opts = normalize_settings(parser, opts) opts = normalize_settings(parser, opts)

View File

@ -43,6 +43,7 @@ else:
makefile.extra_lib_dirs = ['..\\..\\.build\\release', '../../.build', '.'] 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_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_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 makefile.extra_cxxflags = makefile.extra_cflags
# Generate the Makefile itself. # Generate the Makefile itself.

View File

@ -539,7 +539,10 @@ class Server(Thread):
with self.pool_lock: with self.pool_lock:
self.pool.append(o) self.pool.append(o)
time.sleep(1) try:
time.sleep(1)
except:
return
def killall(self): def killall(self):

View File

@ -23,7 +23,7 @@ match to a given font specification. The main functions in this module are:
''' '''
import sys, os, locale, codecs 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 pointer, byref, create_string_buffer, Union, c_char_p, c_double
try: try:
@ -37,17 +37,19 @@ isosx = 'darwin' in sys.platform
def load_library(): def load_library():
if isosx: if isosx:
lib = 'libfontconfig.1.dylib' lib = os.path.join(getattr(sys, 'frameworks_dir'), 'libfontconfig.1.dylib') \
if hasattr(sys, 'frameworks_dir'): if hasattr(sys, 'frameworks_dir') else util.find_library('fontconfig')
lib = os.path.join(getattr(sys, 'frameworks_dir'), lib)
return cdll.LoadLibrary(lib) return cdll.LoadLibrary(lib)
elif iswindows: elif iswindows:
return cdll.LoadLibrary('libfontconfig-1') return cdll.LoadLibrary('libfontconfig-1')
else: else:
try: try:
return cdll.LoadLibrary('libfontconfig.so') return cdll.LoadLibrary(util.find_library('fontconfig'))
except: except:
return cdll.LoadLibrary('libfontconfig.so.1') try:
return cdll.LoadLibrary('libfontconfig.so')
except:
return cdll.LoadLibrary('libfontconfig.so.1')
class FcPattern(Structure): class FcPattern(Structure):
_fields_ = [ _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.FcFontSort.restype = POINTER(FcFontSet)
lib.FcFontRenderPrepare.argtypes = [c_void_p, POINTER(FcPattern), POINTER(FcPattern)] lib.FcFontRenderPrepare.argtypes = [c_void_p, POINTER(FcPattern), POINTER(FcPattern)]
lib.FcFontRenderPrepare.restype = 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')) raise RuntimeError(_('Could not initialize the fontconfig library'))
def find_font_families(allowed_extensions=['ttf']): def find_font_families(allowed_extensions=['ttf']):
@ -151,12 +173,11 @@ def find_font_families(allowed_extensions=['ttf']):
ext = os.path.splitext(path)[1] ext = os.path.splitext(path)[1]
if ext: if ext:
ext = ext[1:].lower() 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: if lib.FcPatternGetString(pat, 'family', 0, byref(family)) != FcResultMatch.value:
raise RuntimeError('Error processing pattern') raise RuntimeError('Error processing pattern')
font_families.append(str(family.contents.value)) font_families.append(str(family.contents.value))
lib.FcObjectSetDestroy(oset) lib.FcObjectSetDestroy(oset)
lib.FcPatternDestroy(empty_pattern) lib.FcPatternDestroy(empty_pattern)
lib.FcFontSetDestroy(fs) lib.FcFontSetDestroy(fs)