diff --git a/osx_installer.py b/osx_installer.py index 84e1c6eaf5..ce9ee98f5c 100644 --- a/osx_installer.py +++ b/osx_installer.py @@ -240,6 +240,9 @@ _check_symlinks_prescript() os.link(os.path.expanduser('~/pdftohtml'), os.path.join(frameworks_dir, 'pdftohtml')) 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/*')): + 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)) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 23befd12dd..ccfcdd5113 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -15,15 +15,14 @@ from optparse import OptionParser as _OptionParser from optparse import IndentedHelpFormatter from logging import Formatter -from ttfquery import findsystem, describe from PyQt4.QtCore import QSettings, QVariant, QUrl from PyQt4.QtGui import QDesktopServices from calibre.translations.msgfmt import make from calibre.ebooks.chardet import detect from calibre.terminfo import TerminalController -terminal_controller = TerminalController(sys.stdout) +terminal_controller = TerminalController(sys.stdout) iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower() isosx = 'darwin' in sys.platform.lower() islinux = not(iswindows or isosx) @@ -306,44 +305,6 @@ def set_translator(): set_translator() -font_families = {} -def get_font_families(cached=None): - global font_families - if cached is not None: - font_families = cached - if not font_families: - try: - ffiles = findsystem.findFonts() - except Exception, err: - print 'WARNING: Could not find fonts on your system.' - print err - else: - zlist = [] - for ff in ffiles: - try: - if 'Optane' in str(ff): - font = describe.openFont(ff) - wt, italic = describe.modifiers(font) - except: - pass - try: - font = describe.openFont(ff) - except: # Some font files cause ttfquery to raise an exception, in which case they are ignored - continue - try: - wt, italic = describe.modifiers(font) - except: - wt, italic = 0, 0 - if wt == 400 and italic == 0: - try: - family = describe.shortName(font)[1].strip() - except: # Windows strikes again! - continue - zlist.append((family, ff)) - font_families = dict(zlist) - - return font_families - def sanitize_file_name(name): ''' Remove characters that are illegal in filenames from name. @@ -596,3 +557,12 @@ def entity_to_unicode(match, exceptions=[], encoding='cp1252'): except KeyError: return '&'+ent+';' +if isosx: + fdir = os.path.expanduser('~/.fonts') + if not os.path.exists(fdir): + os.makedirs(fdir) + if not os.path.exists(os.path.join(fdir, 'LiberationSans_Regular.ttf')): + from calibre.ebooks.lrf.fonts.liberation import __all__ as fonts + for font in fonts: + exec 'from calibre.ebooks.lrf.fonts.liberation.'+font+' import font_data' + open(os.path.join(fdir, font+'.ttf'), 'wb').write(font_data) \ No newline at end of file diff --git a/src/calibre/ebooks/lrf/__init__.py b/src/calibre/ebooks/lrf/__init__.py index 990ce6b08d..02882312a8 100644 --- a/src/calibre/ebooks/lrf/__init__.py +++ b/src/calibre/ebooks/lrf/__init__.py @@ -9,7 +9,6 @@ from optparse import OptionValueError from htmlentitydefs import name2codepoint from uuid import uuid4 -from ttfquery import describe, findsystem from fontTools.ttLib import TTLibError from calibre.ebooks.lrf.pylrs.pylrs import Book as _Book @@ -67,20 +66,6 @@ def profile_from_string(option, opt_str, value, parser): except KeyError: raise OptionValueError('Profile: '+value+' is not implemented. Implemented profiles: %s'%(profile_map.keys())) -def font_family(option, opt_str, value, parser): - if value: - value = value.split(',') - if len(value) != 2: - raise OptionValueError('Font family specification must be of the form'+\ - ' "path to font directory, font family"') - path, family = tuple(value) - if not os.path.isdir(path) or not os.access(path, os.R_OK|os.X_OK): - raise OptionValueError('Cannot read from ' + path) - setattr(parser.values, option.dest, (path, family)) - else: - setattr(parser.values, option.dest, tuple()) - - def option_parser(usage, gui_mode=False): parser = OptionParser(usage=usage, gui_mode=gui_mode) metadata = parser.add_option_group('METADATA OPTIONS') @@ -203,18 +188,17 @@ def option_parser(usage, gui_mode=False): fonts = parser.add_option_group('FONT FAMILIES', _('''Specify trutype font families for serif, sans-serif and monospace fonts. ''' '''These fonts will be embedded in the LRF file. Note that custom fonts lead to ''' - '''slower page turns. Each family specification is of the form: ''' - '''"path to fonts directory, family" ''' + '''slower page turns. ''' '''For example: ''' - '''--serif-family "%s, Times New Roman" - ''') % ('C:\Windows\Fonts' if iswindows else '/usr/share/fonts/corefonts')) - fonts.add_option('--serif-family', action='callback', callback=font_family, + '''--serif-family "Times New Roman" + ''')) + fonts.add_option('--serif-family', default=None, dest='serif_family', type='string', help=_('The serif family of fonts to embed')) - fonts.add_option('--sans-family', action='callback', callback=font_family, + fonts.add_option('--sans-family', default=None, dest='sans_family', type='string', help=_('The sans-serif family of fonts to embed')) - fonts.add_option('--mono-family', action='callback', callback=font_family, + fonts.add_option('--mono-family', default=None, dest='mono_family', type='string', help=_('The monospace family of fonts to embed')) @@ -231,45 +215,25 @@ def option_parser(usage, gui_mode=False): return parser def find_custom_fonts(options, logger): + from calibre.utils.fontconfig import files_for_family fonts = {'serif' : None, 'sans' : None, 'mono' : None} - def find_family(option): - path, family = option - paths = findsystem.findFonts([path]) - results = {} - for path in paths: - if len(results.keys()) == 4: - break - f = describe.openFont(path) - name, cfamily = describe.shortName(f) - if cfamily.lower().strip() != family.lower().strip(): - continue - try: - wt, italic = describe.modifiers(f) - except TTLibError: - logger.exception('Could not process fonts in %s', path) - wt, italic = 0, 0 - result = (path, name) - if wt == 400 and italic == 0: - results['normal'] = result - elif wt == 400 and italic > 0: - results['italic'] = result - elif wt >= 700 and italic == 0: - results['bold'] = result - elif wt >= 700 and italic > 0: - results['bi'] = result - return results + def family(cmd): + return cmd.split(',')[-1].strip() if options.serif_family: - fonts['serif'] = find_family(options.serif_family) + f = family(options.serif_family) + fonts['serif'] = files_for_family(f) if not fonts['serif']: - logger.warn('Unable to find serif family %s in %s'%(options.serif_family[1].strip(), options.serif_family[0])) + logger.warn('Unable to find serif family %s'%f) if options.sans_family: - fonts['sans'] = find_family(options.sans_family) + f = family(options.sans_family) + fonts['sans'] = files_for_family(f) if not fonts['sans']: - logger.warn('Unable to find sans family %s in %s'%(options.sans_family[1].strip(), options.sans_family[0])) + logger.warn('Unable to find sans family %s'%f) if options.mono_family: - fonts['mono'] = find_family(options.mono_family) + f = family(options.mono_family) + fonts['mono'] = files_for_family(f) if not fonts['mono']: - logger.warn('Unable to find mono family %s in %s'%(options.mono_family[1].strip(), options.mono_family[0])) + logger.warn('Unable to find mono family %s'%f) return fonts @@ -324,4 +288,4 @@ def Book(options, logger, font_delta=0, header=None, raise ConversionError, 'Could not find the normal version of the ' + family + ' font' return book, fonts -from calibre import entity_to_unicode \ No newline at end of file +from calibre import entity_to_unicode diff --git a/src/calibre/ebooks/lrf/fonts/liberation/__init__.py b/src/calibre/ebooks/lrf/fonts/liberation/__init__.py index e69de29bb2..95148ae3ec 100644 --- a/src/calibre/ebooks/lrf/fonts/liberation/__init__.py +++ b/src/calibre/ebooks/lrf/fonts/liberation/__init__.py @@ -0,0 +1,5 @@ +__all__ = ['LiberationMono_Bold', 'LiberationMono_Regular', 'LiberationSans_Bold', + 'LiberationSans_Regular', 'LiberationSerif_Bold', 'LiberationSerif_Regular', + 'LiberationMono_BoldItalic', 'LiberationMono_Italic', + 'LiberationSans_BoldItalic', 'LiberationSans_Italic', + 'LiberationSerif_BoldItalic', 'LiberationSerif_Italic'] \ No newline at end of file diff --git a/src/calibre/gui2/dialogs/lrf_single.py b/src/calibre/gui2/dialogs/lrf_single.py index 036570902f..543942f4e1 100644 --- a/src/calibre/gui2/dialogs/lrf_single.py +++ b/src/calibre/gui2/dialogs/lrf_single.py @@ -143,7 +143,7 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): for opt in ('--serif-family', '--sans-family', '--mono-family'): if opt in cmdline: print 'in' - family = cmdline[cmdline.index(opt)+1].split(',')[1].strip() + family = cmdline[cmdline.index(opt)+1].split(',')[-1].strip() obj = getattr(self, 'gui_'+opt[2:].replace('-', '_')) try: obj.setCurrentIndex(self.font_family_model.index_of(family)) @@ -332,12 +332,8 @@ class LRFSingleDialog(QDialog, Ui_LRFSingleDialog): for opt in ('--serif-family', '--sans-family', '--mono-family'): obj = getattr(self, 'gui_'+opt[2:].replace('-', '_')) family = qstring_to_unicode(obj.itemText(obj.currentIndex())).strip() - try: - path = self.font_family_model.path_of(family) - except KeyError: - continue - if path: - cmd.extend([opt, os.path.dirname(path)+', '+family]) + if family != 'None': + cmd.extend([opt, family]) return cmd diff --git a/src/calibre/linux.py b/src/calibre/linux.py index aad0fb616c..60d5763f2c 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -48,6 +48,7 @@ entry_points = { 'lrf2html = calibre.ebooks.lrf.html.convert_to:main', 'calibre-debug = calibre.debug:main', 'calibredb = calibre.library.cli:main', + 'calibre-fontconfig = calibre.utils.fontconfig:main', ], 'gui_scripts' : [ __appname__+' = calibre.gui2.main:main', diff --git a/src/calibre/trac/plugins/download.py b/src/calibre/trac/plugins/download.py index ca900837ce..e586a11f50 100644 --- a/src/calibre/trac/plugins/download.py +++ b/src/calibre/trac/plugins/download.py @@ -31,7 +31,6 @@ class Distribution(object): ('libusb', '0.1.12', None, None, None), ('Qt', '4.4.0', 'qt', 'libqt4-core libqt4-gui', 'qt4'), ('PyQt', '4.4.2', 'PyQt4', 'python-qt4', 'PyQt4'), - ('fonttools', '2.0-beta1', 'fonttools', 'fonttools', 'fonttools'), ('mechanize for python', '0.1.7b', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'), ('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'), ('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'), diff --git a/src/calibre/trac/plugins/templates/distro.html b/src/calibre/trac/plugins/templates/distro.html index 237df4bdc5..61944e7747 100644 --- a/src/calibre/trac/plugins/templates/distro.html +++ b/src/calibre/trac/plugins/templates/distro.html @@ -34,7 +34,7 @@
  1. Make sure that your system has python >= 2.5
  2. -
  3. Install the various dependencies listed below: Make sure that any python packages are installed into python2.5 (e.g. setuptools, python-imaging, PyQt4, fonttools, etc)
  4. +
  5. Install the various dependencies listed below: Make sure that any python packages are installed into python2.5 (e.g. setuptools, python-imaging, PyQt4, etc)
  6. As root run the command
    easy_install-2.5 -U TTFQuery calibre && calibre_postinstall

Dependencies

diff --git a/src/calibre/translations/__init__.py b/src/calibre/translations/__init__.py index 46a73639e3..01f546b42e 100644 --- a/src/calibre/translations/__init__.py +++ b/src/calibre/translations/__init__.py @@ -85,7 +85,6 @@ def main(args=sys.argv): if __name__ == '__main__': cwd = os.getcwd() sys.path.insert(0, os.path.dirname(os.path.dirname(cwd))) - print sys.path[0] sys.exit(main()) diff --git a/src/calibre/utils/fontconfig.py b/src/calibre/utils/fontconfig.py new file mode 100644 index 0000000000..d00bfc9692 --- /dev/null +++ b/src/calibre/utils/fontconfig.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +:mod:`fontconfig` -- Query system fonts +============================================= +.. module:: fontconfig + :platform: Unix, Windows, OS X + :synopsis: Query system fonts +.. moduleauthor:: Kovid Goyal + +A ctypes based wrapper around the `fontconfig `_ library. +It can be used to find all fonts available on the system as well as the closest +match to a given font specification. The main functions in this module are: + +.. autofunction:: find_font_families + +.. autofunction:: files_for_family + +.. autofunction:: match +''' + +import sys, os, locale, codecs +from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, \ + pointer, byref, create_string_buffer, Union, c_char_p, c_double + +try: + preferred_encoding = locale.getpreferredencoding() + codecs.lookup(preferred_encoding) +except: + preferred_encoding = 'utf-8' + +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) + return cdll.LoadLibrary(lib) + elif iswindows: + return cdll.LoadLibrary('libfontconfig-1') + else: + return cdll.LoadLibrary('libfontconfig.so') + +class FcPattern(Structure): + _fields_ = [ + ('num', c_int), + ('size', c_int), + ('elts_offset', c_void_p), + ('ref', c_int) + ] +class FcFontSet(Structure): + _fields_ = [ + ('nfont', c_int), + ('sfont', c_int), + ('fonts', POINTER(POINTER(FcPattern))) + ] +( + FcTypeVoid, + FcTypeInteger, + FcTypeDouble, + FcTypeString, + FcTypeBool, + FcTypeMatrix, + FcTypeCharSet, + FcTypeFTFace, + FcTypeLangSet +) = map(c_int, range(9)) +(FcMatchPattern, FcMatchFont, FcMatchScan) = map(c_int, range(3)) +( +FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId, + FcResultOutOfMemory +) = map(c_int, range(5)) +FcFalse, FcTrue = c_int(0), c_int(1) + +class _FcValue(Union): + _fields_ = [ + ('s', c_char_p), + ('i', c_int), + ('b', c_int), + ('d', c_double), + ] + +class FcValue(Structure): + _fields_ = [ + ('type', c_int), + ('u', _FcValue) + ] + +lib = load_library() +lib.FcPatternCreate.restype = c_void_p +lib.FcObjectSetCreate.restype = c_void_p +lib.FcFontSetDestroy.argtypes = [POINTER(FcFontSet)] +lib.FcFontList.restype = POINTER(FcFontSet) +lib.FcNameUnparse.argtypes = [POINTER(FcPattern)] +lib.FcNameUnparse.restype = POINTER(c_ubyte) +lib.FcPatternGetString.argtypes = [POINTER(FcPattern), POINTER(c_char), c_int, c_void_p] +lib.FcPatternGetString.restype = c_int +lib.FcPatternAdd.argtypes = [c_void_p, POINTER(c_char), FcValue, c_int] +lib.FcPatternGetInteger.argtypes = [POINTER(FcPattern), POINTER(c_char), c_int, POINTER(c_int)] +lib.FcPatternGetInteger.restype = c_int +lib.FcNameParse.argtypes = [c_char_p] +lib.FcNameParse.restype = POINTER(FcPattern) +lib.FcDefaultSubstitute.argtypes = [POINTER(FcPattern)] +lib.FcConfigSubstitute.argtypes = [c_void_p, POINTER(FcPattern), c_int] +lib.FcFontSetCreate.restype = POINTER(FcFontSet) +lib.FcFontMatch.argtypes = [c_void_p, POINTER(FcPattern), POINTER(c_int)] +lib.FcFontMatch.restype = POINTER(FcPattern) +lib.FcFontSetAdd.argtypes = [POINTER(FcFontSet), POINTER(FcPattern)] +lib.FcFontSort.argtypes = [c_void_p, POINTER(FcPattern), c_int, c_void_p, POINTER(c_int)] +lib.FcFontSort.restype = POINTER(FcFontSet) +lib.FcFontRenderPrepare.argtypes = [c_void_p, POINTER(FcPattern), POINTER(FcPattern)] +lib.FcFontRenderPrepare.restype = POINTER(FcPattern) + + +if not lib.FcInit(): + raise RuntimeError(_('Could not initialize the fontconfig library')) + + +def find_font_families(allowed_extensions=['ttf']): + ''' + Return an alphabetically sorted list of font families available on the system. + + `allowed_extensions`: A list of allowed extensions for font file types. Defaults to + `['ttf']`. If it is empty, it is ignored. + ''' + allowed_extensions = [i.lower() for i in allowed_extensions] + + empty_pattern = lib.FcPatternCreate() + oset = lib.FcObjectSetCreate() + if not lib.FcObjectSetAdd(oset, 'file'): + raise RuntimeError('Allocation failure') + if not lib.FcObjectSetAdd(oset, 'family'): + raise RuntimeError('Allocation failure') + fs = lib.FcFontList(0, empty_pattern, oset) + font_set = fs.contents + file = pointer(create_string_buffer(chr(0), 5000)) + family = pointer(create_string_buffer(chr(0), 200)) + font_families = [] + for i in range(font_set.nfont): + pat = font_set.fonts[i] + if lib.FcPatternGetString(pat, 'file', 0, byref(file)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + path = str(file.contents.value) + ext = os.path.splitext(path)[1] + if ext: + ext = ext[1:].lower() + if 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) + lib.FcFontSetDestroy(fs) + font_families = list(set(font_families)) + font_families.sort() + return font_families + +def files_for_family(family, normalize=True): + ''' + Find all the variants in the font family `family`. + Returns a dictionary of tuples. Each tuple is of the form (Full font name, path to font file). + The keys of the dictionary depend on `normalize`. If `normalize` is `False`, + they are a tuple (slant, weight) otherwise they are strings from the set + `('normal', 'bold', 'italic', 'bi', 'light', 'li')` + ''' + if isinstance(family, unicode): + family = family.encode(preferred_encoding) + family_pattern = lib.FcPatternBuild(0, 'family', FcTypeString, family, 0) + if not family_pattern: + raise RuntimeError('Allocation failure') + #lib.FcPatternPrint(family_pattern) + oset = lib.FcObjectSetCreate() + if not lib.FcObjectSetAdd(oset, 'file'): + raise RuntimeError('Allocation failure') + if not lib.FcObjectSetAdd(oset, 'weight'): + raise RuntimeError('Allocation failure') + if not lib.FcObjectSetAdd(oset, 'fullname'): + raise RuntimeError('Allocation failure') + if not lib.FcObjectSetAdd(oset, 'slant'): + raise RuntimeError('Allocation failure') + if not lib.FcObjectSetAdd(oset, 'style'): + raise RuntimeError('Allocation failure') + fonts = {} + fs = lib.FcFontList(0, family_pattern, oset) + font_set = fs.contents + file = pointer(create_string_buffer(chr(0), 5000)) + full_name = pointer(create_string_buffer(chr(0), 200)) + weight = c_int(0) + slant = c_int(0) + fname = '' + for i in range(font_set.nfont): + pat = font_set.fonts[i] + #lib.FcPatternPrint(pat) + pat = font_set.fonts[i] + if lib.FcPatternGetString(pat, 'file', 0, byref(file)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + if lib.FcPatternGetInteger(pat, 'weight', 0, byref(weight)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + if lib.FcPatternGetString(pat, 'fullname', 0, byref(full_name)) != FcResultMatch.value: + if lib.FcPatternGetString(pat, 'fullname', 0, byref(full_name)) == FcResultNoMatch.value: + if lib.FcPatternGetString(pat, 'style', 0, byref(full_name)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + fname = family + ' ' + full_name.contents.value + else: + raise RuntimeError('Error processing pattern') + else: + fname = full_name.contents.value + if lib.FcPatternGetInteger(pat, 'slant', 0, byref(slant)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + style = (slant.value, weight.value) + if normalize: + italic = slant.value > 0 + normal = weight.value == 80 + bold = weight.value > 80 + if italic: + style = 'italic' if normal else 'bi' if bold else 'li' + else: + style = 'normal' if normal else 'bold' if bold else 'light' + fonts[style] = (file.contents.value, fname) + lib.FcObjectSetDestroy(oset) + lib.FcPatternDestroy(family_pattern) + if not iswindows: + lib.FcFontSetDestroy(fs) + + return fonts + +def match(name, sort=False, verbose=False): + ''' + Find the system font that most closely matches `name`, where `name` is a specification + of the form:: + familyname-::... + + For example, `verdana:weight=bold:slant=italic` + + Returns a list of dictionaries. Each dictionary has the keys: 'weight', 'slant', 'family', 'file' + + `sort`: If `True` return a sorted list of matching fonts, where the sort id in order of + decreasing closeness of matching. + `verbose`: If `True` print debugging information to stdout + ''' + if isinstance(name, unicode): + name = name.encode(preferred_encoding) + pat = lib.FcNameParse(name) + if not pat: + raise ValueError('Could not parse font name') + if verbose: + print 'Searching for pattern' + lib.FcPatternPrint(pat) + if not lib.FcConfigSubstitute(0, pat, FcMatchPattern): + raise RuntimeError('Allocation failure') + lib.FcDefaultSubstitute(pat) + fs = lib.FcFontSetCreate() + result = c_int(0) + matches = [] + if sort: + font_patterns = lib.FcFontSort(0, pat, FcFalse, 0, byref(result)) + if not font_patterns: + raise RuntimeError('Allocation failed') + fps = font_patterns.contents + for j in range(fps.nfont): + fpat = fps.fonts[j] + fp = lib.FcFontRenderPrepare(0, pat, fpat) + if fp: + lib.FcFontSetAdd(fs, fp) + lib.FcFontSetDestroy(font_patterns) + else: + match_pat = lib.FcFontMatch(0, pat, byref(result)) + if pat: + lib.FcFontSetAdd(fs, match_pat) + if result.value != FcResultMatch.value: + lib.FcPatternDestroy(pat) + return matches + font_set = fs.contents + + file = pointer(create_string_buffer(chr(0), 5000)) + family = pointer(create_string_buffer(chr(0), 200)) + weight = c_int(0) + slant = c_int(0) + for j in range(font_set.nfont): + fpat = font_set.fonts[j] + #lib.FcPatternPrint(fpat) + if lib.FcPatternGetString(fpat, 'file', 0, byref(file)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + if lib.FcPatternGetString(fpat, 'family', 0, byref(family)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + if lib.FcPatternGetInteger(fpat, 'weight', 0, byref(weight)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + if lib.FcPatternGetInteger(fpat, 'slant', 0, byref(slant)) != FcResultMatch.value: + raise RuntimeError('Error processing pattern') + + matches.append({ + 'file' : file.contents.value, + 'family' : family.contents.value, + 'weight' : weight.value, + 'slant' : slant.value, + } + ) + + lib.FcPatternDestroy(pat) + lib.FcFontSetDestroy(fs) + return matches + +def main(args=sys.argv): + print find_font_families() + if len(args) > 1: + print + print files_for_family(args[1]) + print + print match(args[1], verbose=True) + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/windows_installer.py b/windows_installer.py index 0835942909..6608effa16 100644 --- a/windows_installer.py +++ b/windows_installer.py @@ -46,6 +46,7 @@ BrandingText "${PRODUCT_NAME} created by Kovid Goyal" !define CLIT "C:\clit\clit.exe" !define PDFTOHTML "C:\pdftohtml\pdftohtml.exe" !define IMAGEMAGICK "C:\ImageMagick" +!DEFINE FONTCONFIG "C:\fontconfig" ; ---------------PATH manipulation ----------------------------------------------------------------- @@ -283,6 +284,7 @@ Section "Main" "secmain" File /r "${PY2EXE_DIR}\*" File "${CLIT}" File "${PDFTOHTML}" + File /r "${FONTCONFIG}\*" SetOutPath "$INSTDIR\ImageMagick" File /r "${IMAGEMAGICK}\*"