diff --git a/setup/build_environment.py b/setup/build_environment.py
index 6601578345..492eca0697 100644
--- a/setup/build_environment.py
+++ b/setup/build_environment.py
@@ -87,8 +87,6 @@ ft_libs = []
ft_inc_dirs = []
jpg_libs = []
jpg_lib_dirs = []
-fc_inc = '/usr/include/fontconfig'
-fc_lib = '/usr/lib'
podofo_inc = '/usr/include/podofo'
podofo_lib = '/usr/lib'
chmlib_inc_dirs = chmlib_lib_dirs = []
@@ -107,8 +105,6 @@ if iswindows:
'source', 'i18n')]
icu_lib_dirs = [os.path.join(ICU, 'source', 'lib')]
sqlite_inc_dirs = [sw_inc_dir]
- fc_inc = os.path.join(sw_inc_dir, 'fontconfig')
- fc_lib = sw_lib_dir
chmlib_inc_dirs = consolidate('CHMLIB_INC_DIR', os.path.join(prefix,
'build', 'chmlib-0.40', 'src'))
chmlib_lib_dirs = consolidate('CHMLIB_LIB_DIR', os.path.join(prefix,
@@ -131,8 +127,6 @@ if iswindows:
podofo_inc = os.path.join(sw_inc_dir, 'podofo')
podofo_lib = sw_lib_dir
elif isosx:
- fc_inc = '/sw/include/fontconfig'
- fc_lib = '/sw/lib'
podofo_inc = '/sw/podofo'
podofo_lib = '/sw/lib'
magick_inc_dirs = consolidate('MAGICK_INC',
@@ -166,13 +160,6 @@ else:
ft_libs = pkgconfig_libs('freetype2', '', '')
-fc_inc = os.environ.get('FC_INC_DIR', fc_inc)
-fc_lib = os.environ.get('FC_LIB_DIR', fc_lib)
-fc_error = None if os.path.exists(os.path.join(fc_inc, 'fontconfig.h')) else \
- ('fontconfig header files not found on your system. '
- 'Try setting the FC_INC_DIR and FC_LIB_DIR environment '
- 'variables.')
-
magick_error = None
if not magick_inc_dirs or not os.path.exists(os.path.join(magick_inc_dirs[0],
'wand')):
diff --git a/setup/extensions.py b/setup/extensions.py
index 989a9ddbe9..cfbb148873 100644
--- a/setup/extensions.py
+++ b/setup/extensions.py
@@ -13,7 +13,7 @@ from multiprocessing import cpu_count
from PyQt4.pyqtconfig import QtGuiModuleMakefile
from setup import Command, islinux, isbsd, isosx, SRC, iswindows
-from setup.build_environment import (fc_inc, fc_lib, chmlib_inc_dirs, fc_error,
+from setup.build_environment import (chmlib_inc_dirs,
podofo_inc, podofo_lib, podofo_error, pyqt, OSX_SDK, NMAKE, QMAKE,
msvc, MT, win_inc, win_lib, win_ddk, magick_inc_dirs, magick_lib_dirs,
magick_libs, chmlib_lib_dirs, sqlite_inc_dirs, icu_inc_dirs,
@@ -122,13 +122,6 @@ extensions = [
libraries=ft_libs,
lib_dirs=ft_lib_dirs),
- Extension('fontconfig',
- ['calibre/utils/fonts/fontconfig.c'],
- inc_dirs = [fc_inc],
- libraries=['fontconfig'],
- lib_dirs=[fc_lib],
- error=fc_error),
-
Extension('woff',
['calibre/utils/fonts/woff/main.c',
'calibre/utils/fonts/woff/woff.c'],
@@ -305,9 +298,6 @@ class Build(Command):
CFLAGS - Extra compiler flags
LDFLAGS - Extra linker flags
- FC_INC_DIR - fontconfig header files
- FC_LIB_DIR - fontconfig library
-
POPPLER_INC_DIR - poppler header files
POPPLER_LIB_DIR - poppler-qt4 library
diff --git a/setup/installer/osx/app/main.py b/setup/installer/osx/app/main.py
index 14df94f4ba..a101c574b7 100644
--- a/setup/installer/osx/app/main.py
+++ b/setup/installer/osx/app/main.py
@@ -15,8 +15,6 @@ from setup import __version__ as VERSION, __appname__ as APPNAME, basenames, \
LICENSE = open('LICENSE', 'rb').read()
MAGICK_HOME='@executable_path/../Frameworks/ImageMagick'
ENV = dict(
- FC_CONFIG_DIR='@executable_path/../Resources/fonts',
- FC_CONFIG_FILE='@executable_path/../Resources/fonts/fonts.conf',
MAGICK_CONFIGURE_PATH=MAGICK_HOME+'/config',
MAGICK_CODER_MODULE_PATH=MAGICK_HOME+'/modules-Q16/coders',
MAGICK_CODER_FILTER_PATH=MAGICK_HOME+'/modules-Q16/filter',
@@ -180,7 +178,7 @@ class Py2App(object):
self.add_poppler()
self.add_libjpeg()
self.add_libpng()
- self.add_fontconfig()
+ self.add_freetype()
self.add_imagemagick()
self.add_misc_libraries()
@@ -397,28 +395,11 @@ class Py2App(object):
@flush
- def add_fontconfig(self):
- info('\nAdding fontconfig')
- for x in ('fontconfig.1', 'freetype.6', 'expat.1'):
+ def add_freetype(self):
+ info('\nAdding freetype')
+ for x in ('freetype.6', 'expat.1'):
src = os.path.join(SW, 'lib', 'lib'+x+'.dylib')
self.install_dylib(src)
- dst = os.path.join(self.resources_dir, 'fonts')
- if os.path.exists(dst):
- shutil.rmtree(dst)
- src = os.path.join(SW, 'etc', 'fonts')
- shutil.copytree(src, dst, symlinks=False)
- fc = os.path.join(dst, 'fonts.conf')
- raw = open(fc, 'rb').read()
- raw = raw.replace('
/usr/share/fonts', '''\
- /Library/Fonts
- /Network/Library/Fonts
- /System/Library/Fonts
- /usr/X11R6/lib/X11/fonts
- /usr/share/fonts
- /var/root/Library/Fonts
- /usr/share/fonts
- ''')
- open(fc, 'wb').write(raw)
@flush
def add_imagemagick(self):
diff --git a/setup/installer/windows/freeze.py b/setup/installer/windows/freeze.py
index 12443b4898..e578d64607 100644
--- a/setup/installer/windows/freeze.py
+++ b/setup/installer/windows/freeze.py
@@ -281,8 +281,6 @@ class Win32Freeze(Command, WixMixIn):
for x in ('zlib1.dll', 'libxml2.dll'):
shutil.copy2(self.j(bindir, x+'.manifest'), self.dll_dir)
- shutil.copytree(os.path.join(SW, 'etc', 'fonts'),
- os.path.join(self.base, 'fontconfig'))
# Copy ImageMagick
for pat in ('*.dll', '*.xml'):
for f in glob.glob(self.j(IMAGEMAGICK, pat)):
diff --git a/setup/installer/windows/notes.rst b/setup/installer/windows/notes.rst
index 9502135f6e..fe0d8380e0 100644
--- a/setup/installer/windows/notes.rst
+++ b/setup/installer/windows/notes.rst
@@ -276,27 +276,6 @@ cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.exp lib/
cp -r build/kdewin32-msvc-0.3.9/include/msvc/ include/
cp build/kdewin32-msvc-0.3.9/include/*.h include/
-fontconfig
----------------
-
-Get it from http://www.winkde.org/pub/kde/ports/win32/repository/win32libs/
-mkdir build
-Remove subdirectory test from the bottom of CMakeLists.txt
-run cmake
-
-Set build type to release and project config to dll
-Right click on the fontconfig project and select properties. Add sw/include/msvc to the include paths
-Build only fontconfig
-
-cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.dll bin
-cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.lib lib
-cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.exp lib
-cp -r build/fontconfig-msvc-2.4.2-3/fontconfig/ include/
-
-Also install the etc files from the font-config-bin archive from kde win32libs
-It contains correct fonts.conf etc.
-
-
poppler
-------------
diff --git a/src/calibre/constants.py b/src/calibre/constants.py
index f098b77f9a..3c89db2d1a 100644
--- a/src/calibre/constants.py
+++ b/src/calibre/constants.py
@@ -83,7 +83,6 @@ class Plugins(collections.Mapping):
'magick',
'podofo',
'cPalmdoc',
- 'fontconfig',
'progress_indicator',
'chmlib',
'chm_extra',
diff --git a/src/calibre/utils/fonts/fc.py b/src/calibre/utils/fonts/fc.py
deleted file mode 100644
index 3e6ae844bc..0000000000
--- a/src/calibre/utils/fonts/fc.py
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/usr/bin/env python
-# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
-from __future__ import with_statement
-
-__license__ = 'GPL v3'
-__copyright__ = '2009, Kovid Goyal '
-__docformat__ = 'restructuredtext en'
-
-import os, sys
-
-from calibre.constants import plugins, islinux, isbsd, isosx, preferred_encoding
-
-_fc, _fc_err = plugins['fontconfig']
-
-if _fc is None:
- raise RuntimeError('Failed to load fontconfig with error:'+_fc_err)
-
-if islinux or isbsd:
- Thread = object
-else:
- from threading import Thread
-
-class FontConfig(Thread):
-
- def __init__(self):
- Thread.__init__(self)
- self.daemon = True
- self.failed = False
- self.css_weight_map = {
- _fc.FC_WEIGHT_THIN : u'100',
- _fc.FC_WEIGHT_EXTRALIGHT : u'200', _fc.FC_WEIGHT_ULTRALIGHT : u'200',
- _fc.FC_WEIGHT_LIGHT : u'300',
- _fc.FC_WEIGHT_BOOK : u'normal', _fc.FC_WEIGHT_BOOK : u'normal', _fc.FC_WEIGHT_REGULAR : u'normal',
- _fc.FC_WEIGHT_MEDIUM : u'500',
- _fc.FC_WEIGHT_DEMIBOLD : u'600', _fc.FC_WEIGHT_SEMIBOLD : u'600',
- _fc.FC_WEIGHT_BOLD : u'bold',
- _fc.FC_WEIGHT_EXTRABOLD : u'800', _fc.FC_WEIGHT_ULTRABOLD : u'800',
- _fc.FC_WEIGHT_HEAVY : u'900', _fc.FC_WEIGHT_BLACK : u'900', _fc.FC_WEIGHT_EXTRABLACK : u'900', _fc.FC_WEIGHT_ULTRABLACK : u'900'
- }
- self.css_slant_map = {
- _fc.FC_SLANT_ROMAN : u'normal',
- _fc.FC_SLANT_ITALIC : u'italic',
- _fc.FC_SLANT_OBLIQUE : u'oblique'
- }
- self.css_stretch_map = {
- _fc.FC_WIDTH_ULTRACONDENSED: u'ultra-condensed',
- _fc.FC_WIDTH_EXTRACONDENSED : u'extra-condensed',
- _fc.FC_WIDTH_CONDENSED: u'condensed',
- _fc.FC_WIDTH_SEMICONDENSED: u'semi-condensed',
- _fc.FC_WIDTH_NORMAL: u'normal',
- _fc.FC_WIDTH_SEMIEXPANDED: u'semi-expanded',
- _fc.FC_WIDTH_EXPANDED: u'expanded',
- _fc.FC_WIDTH_EXTRAEXPANDED: u'extra-expanded',
- _fc.FC_WIDTH_ULTRAEXPANDED: u'ultra-expanded',
- }
-
- def run(self):
- config = None
- if getattr(sys, 'frameworks_dir', False):
- 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 = 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 is_scanning(self):
- if isosx:
- return self.is_alive()
- return False
-
- def wait(self):
- if not (islinux or isbsd):
- self.join()
- if self.failed:
- raise RuntimeError('Failed to initialize fontconfig')
-
- def find_font_families(self, allowed_extensions={'ttf', 'otf'}):
- '''
- 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', 'otf']`. If it is empty, it is ignored.
- '''
- self.wait()
- ans = _fc.find_font_families([bytes('.'+x) for x in allowed_extensions])
- ans = sorted(set(ans), cmp=lambda x,y:cmp(x.lower(), y.lower()))
- ans2 = []
- for x in ans:
- try:
- ans2.append(x.decode('utf-8'))
- except UnicodeDecodeError:
- continue
- return ans2
-
- def files_for_family(self, family, normalize=True):
- '''
- Find all the variants in the font family `family`.
- Returns a dictionary of tuples. Each tuple is of the form (path to font
- file, Full font name).
- 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')`
- '''
- self.wait()
- if not isinstance(family, unicode):
- family = family.decode(preferred_encoding)
- fonts = {}
- for entry in _fc.files_for_family(family):
- slant, weight = entry['slant'], entry['weight']
- fullname, path = entry['fullname'], entry['path']
- nfamily = entry['family']
- style = (slant, weight)
- if normalize:
- italic = slant > 0
- normal = weight == 80
- bold = weight > 80
- if italic:
- style = 'italic' if normal else 'bi' if bold else 'li'
- else:
- style = 'normal' if normal else 'bold' if bold else 'light'
- try:
- fullname, path = fullname.decode('utf-8'), path.decode('utf-8')
- nfamily = nfamily.decode('utf-8')
- except UnicodeDecodeError:
- continue
- if style in fonts:
- if nfamily.lower().strip() == family.lower().strip() \
- and 'Condensed' not in fullname and 'ExtraLight' not in fullname:
- fonts[style] = (path, fullname)
- else:
- fonts[style] = (path, fullname)
-
- return fonts
-
- def faces_for_family(self, family):
- '''
- Return all the faces in a font family in a manner suitable for CSS 3.
- '''
- self.wait()
- if not isinstance(family, unicode):
- family = family.decode(preferred_encoding)
- seen = set()
- for entry in _fc.files_for_family(family):
- slant, weight = entry['slant'], entry['weight']
- fullname, path = entry['fullname'], entry['path']
- nfamily, width = entry['family'], entry['width']
- fingerprint = (slant, weight, width, nfamily)
- if fingerprint in seen:
- # Fontconfig returns the same font multiple times if it is
- # present in multiple locations
- continue
- seen.add(fingerprint)
-
- try:
- nfamily = nfamily.decode('UTF-8')
- fullname = fullname.decode('utf-8')
- path = path.decode('utf-8')
- except UnicodeDecodeError:
- continue
-
- face = {
- 'font-weight': self.css_weight_map[weight],
- 'font-style': self.css_slant_map[slant],
- 'font-stretch': self.css_stretch_map[width],
- 'font-family': nfamily,
- 'fullname': fullname, 'path':path
- }
- yield face
-
- def match(self, name, all=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, or a single dictionary.
- Each dictionary has the keys:
- 'weight', 'slant', 'family', 'file', 'fullname', 'style'
-
- `all`: If `True` return a sorted list of matching fonts, where the sort
- is in order of decreasing closeness of matching. If `False` only the
- best match is returned. '''
- self.wait()
- if isinstance(name, unicode):
- name = name.encode('utf-8')
- fonts = []
- for fullname, path, style, family, weight, slant in \
- _fc.match(str(name), bool(all), bool(verbose)):
- try:
- fullname = fullname.decode('utf-8')
- path = path.decode('utf-8')
- style = style.decode('utf-8')
- family = family.decode('utf-8')
- fonts.append({
- 'fullname' : fullname,
- 'path' : path,
- 'style' : style,
- 'family' : family,
- 'weight' : weight,
- 'slant' : slant
- })
- except UnicodeDecodeError:
- continue
- return fonts if all else (fonts[0] if fonts else None)
-
-fontconfig = FontConfig()
-if islinux or isbsd:
- # On X11 Qt also uses fontconfig, so initialization must happen in the
- # main thread. In any case on X11 initializing fontconfig should be very
- # fast
- fontconfig.run()
-else:
- fontconfig.start()
-
-def test():
- from pprint import pprint;
- pprint(fontconfig.find_font_families())
- pprint(tuple(fontconfig.faces_for_family('liberation serif')))
- m = 'liberation serif'
- pprint(fontconfig.match(m+':slant=italic:weight=bold', verbose=True))
-
-if __name__ == '__main__':
- test()
diff --git a/src/calibre/utils/fonts/fontconfig.c b/src/calibre/utils/fonts/fontconfig.c
deleted file mode 100644
index b66aba4b08..0000000000
--- a/src/calibre/utils/fonts/fontconfig.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
-:mod:`fontconfig` -- Pythonic interface to fontconfig
-=====================================================
-
-.. module:: fontconfig
- :platform: All
- :synopsis: Pythonic interface to the fontconfig library
-
-.. moduleauthor:: Kovid Goyal Copyright 2009
-
-*/
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-#include
-
-static PyObject *
-fontconfig_initialize(PyObject *self, PyObject *args) {
- FcChar8 *path;
- FcBool ok;
- FcConfig *config;
- PyThreadState *_save;
-
- if (!PyArg_ParseTuple(args, "z", &path))
- return NULL;
- if (path == NULL) {
- _save = PyEval_SaveThread();
- ok = FcInit();
- PyEval_RestoreThread(_save);
- } else {
- config = FcConfigCreate();
- if (config == NULL) return PyErr_NoMemory();
- _save = PyEval_SaveThread();
- ok = FcConfigParseAndLoad(config, path, FcTrue);
- if (ok) ok = FcConfigBuildFonts(config);
- if (ok) ok = FcConfigSetCurrent(config);
- PyEval_RestoreThread(_save);
- if (!ok) return PyErr_NoMemory();
- ok = 1;
- }
- if (ok) Py_RETURN_TRUE;
- 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);
- if (oset != NULL) FcObjectSetDestroy(oset);
- if (fs != NULL) FcFontSetDestroy(fs);
-}
-
-
-static PyObject *
-fontconfig_find_font_families(PyObject *self, PyObject *args) {
- int i;
- size_t flen;
- char *ext;
- Py_ssize_t l, j, extlen;
- FcBool ok;
- FcPattern *pat, *temp;
- FcObjectSet *oset;
- FcFontSet *fs;
- FcValue v, w;
- PyObject *ans, *exts, *t;
-
- ans = PyList_New(0);
- fs = NULL; oset = NULL; pat = NULL;
-
- if (ans == NULL) return PyErr_NoMemory();
-
- if (!PyArg_ParseTuple(args, "O", &exts))
- return NULL;
-
- if (!PySequence_Check(exts)) {
- PyErr_SetString(PyExc_ValueError, "Must pass sequence of extensions");
- return NULL;
- }
- l = PySequence_Size(exts);
-
-
- pat = FcPatternCreate();
- if (pat == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- oset = FcObjectSetCreate();
- if (oset == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_FILE)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_FAMILY)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- fs = FcFontList(FcConfigGetCurrent(), pat, oset);
- if (fs == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- for (i = 0; i < fs->nfont; i++) {
- temp = fs->fonts[i];
-
- if (temp == NULL) continue;
- if (FcPatternGet(temp, FC_FILE, 0, &v) != FcResultMatch) continue;
-
- if (v.type == FcTypeString) {
- flen = strlen((char *)v.u.s);
- ok = FcFalse;
- if (l == 0) ok = FcTrue;
- for ( j = 0; j < l && !ok; j++) {
- ext = PyBytes_AS_STRING(PySequence_ITEM(exts, j));
- extlen = PyBytes_GET_SIZE(PySequence_ITEM(exts, j));
- ok = flen > extlen && extlen > 0 &&
- PyOS_strnicmp(ext, ((char *)v.u.s) + (flen - extlen), extlen) == 0;
- }
-
- if (ok) {
- if (FcPatternGet(temp, FC_FAMILY, 0, &w) != FcResultMatch) continue;
- if (w.type != FcTypeString) continue;
- t = PyString_FromString((char *)w.u.s);
- if (t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (PyList_Append(ans, t) != 0)
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- }
- }
-
- }
- fontconfig_cleanup_find(pat, oset, fs);
- Py_INCREF(ans);
- return ans;
-}
-
-static PyObject *
-fontconfig_files_for_family(PyObject *self, PyObject *args) {
- char *family; int i;
- FcPattern *pat, *tp;
- FcObjectSet *oset;
- FcFontSet *fs;
- FcValue file, weight, fullname, style, slant, family2, width;
- PyObject *ans, *temp;
-
- if (!PyArg_ParseTuple(args, "es", "UTF-8", &family))
- return NULL;
-
- ans = PyList_New(0);
- if (ans == NULL) return PyErr_NoMemory();
-
- fs = NULL; oset = NULL; pat = NULL;
-
- pat = FcPatternBuild(0, FC_FAMILY, FcTypeString, family, (char *) 0);
- if (pat == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyMem_Free(family); family = NULL;
-
- oset = FcObjectSetCreate();
- if (oset == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_FILE)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_STYLE)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_SLANT)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_WEIGHT)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_WIDTH)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_FAMILY)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcObjectSetAdd(oset, FC_FULLNAME)) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- fs = FcFontList(FcConfigGetCurrent(), pat, oset);
- if (fs == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- for (i = 0; i < fs->nfont; i++) {
- tp = fs->fonts[i];
-
- if (tp == NULL) continue;
- if (FcPatternGet(tp, FC_FILE, 0, &file) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_STYLE, 0, &style) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_WEIGHT, 0, &weight) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_WIDTH, 0, &width) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_SLANT, 0, &slant) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_FAMILY, 0, &family2) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_FULLNAME, 0, &fullname) != FcResultMatch) continue;
-
- temp = Py_BuildValue("{s:s, s:s, s:s, s:s, s:l, s:l, s:l}",
- "fullname", (char*)fullname.u.s,
- "path", (char*)file.u.s,
- "style", (char*)style.u.s,
- "family", (char*)family2.u.s,
- "weight", (long)weight.u.i,
- "slant", (long)slant.u.i,
- "width", (long)width.u.i
- );
- if (temp == NULL) { fontconfig_cleanup_find(pat, oset, fs); return NULL; }
- if (PyList_Append(ans, temp) != 0)
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- }
- fontconfig_cleanup_find(pat, oset, fs);
- Py_INCREF(ans);
- return ans;
-}
-
-static PyObject *
-fontconfig_match(PyObject *self, PyObject *args) {
- FcChar8 *namespec; int i;
- FcPattern *pat, *tp;
- FcObjectSet *oset;
- FcFontSet *fs, *fs2;
- FcValue file, weight, fullname, style, slant, family;
- FcResult res;
- PyObject *ans, *temp, *t, *all, *verbose;
-
- if (!PyArg_ParseTuple(args, "sOO", &namespec, &all, &verbose))
- return NULL;
-
- ans = PyList_New(0);
- if (ans == NULL) return PyErr_NoMemory();
-
- fs = NULL; oset = NULL; pat = NULL; fs2 = NULL;
-
- pat = FcNameParse(namespec);
- if (pat == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (PyObject_IsTrue(verbose)) FcPatternPrint(pat);
-
- if (!FcConfigSubstitute(FcConfigGetCurrent(), pat, FcMatchPattern))
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- FcDefaultSubstitute(pat);
-
- fs = FcFontSetCreate();
- if (fs == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (PyObject_IsTrue(all)) {
- fs2 = FcFontSort(FcConfigGetCurrent(), pat, FcTrue, NULL, &res);
- if (fs2 == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- for (i = 0; i < fs2->nfont; i++) {
- tp = fs2->fonts[i];
- if (tp == NULL) continue;
- tp = FcFontRenderPrepare(FcConfigGetCurrent(), pat, tp);
- if (tp == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcFontSetAdd(fs, tp))
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- }
- if (fs2 != NULL) FcFontSetDestroy(fs2);
- } else {
- tp = FcFontMatch(FcConfigGetCurrent(), pat, &res);
- if (tp == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- if (!FcFontSetAdd(fs, tp))
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- }
-
- for (i = 0; i < fs->nfont; i++) {
- tp = fs->fonts[i];
- if (tp == NULL) continue;
- if (FcPatternGet(tp, FC_FILE, 0, &file) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_STYLE, 0, &style) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_WEIGHT, 0, &weight) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_SLANT, 0, &slant) != FcResultMatch) continue;
- if (FcPatternGet(tp, FC_FAMILY, 0, &family) != FcResultMatch) continue;
- if (FcPatternGet(tp, "fullname", 0, &fullname) != FcResultMatch) continue;
-
- temp = PyTuple_New(6);
- if(temp == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- t = PyBytes_FromString((char *)fullname.u.s);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 0, t);
- t = PyBytes_FromString((char *)file.u.s);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 1, t);
- t = PyBytes_FromString((char *)style.u.s);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 2, t);
- t = PyBytes_FromString((char *)family.u.s);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 3, t);
- t = PyInt_FromLong((long)weight.u.i);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 4, t);
- t = PyInt_FromLong((long)slant.u.i);
- if(t == NULL) { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
- PyTuple_SET_ITEM(temp, 5, t);
- if (PyList_Append(ans, temp) != 0)
- { fontconfig_cleanup_find(pat, oset, fs); return PyErr_NoMemory(); }
-
- }
- fontconfig_cleanup_find(pat, oset, fs);
- Py_INCREF(ans);
- return ans;
-}
-
-
-
-static
-PyMethodDef fontconfig_methods[] = {
- {"initialize", fontconfig_initialize, METH_VARARGS,
- "initialize(path_to_config_file)\n\n"
- "Initialize the library. If path to config file is specified it is used instead of the "
- "default configuration. Returns True iff the initialization succeeded."
- },
-
- {"find_font_families", fontconfig_find_font_families, METH_VARARGS,
- "find_font_families(allowed_extensions)\n\n"
- "Find all font families on the system for fonts of the specified types. If no "
- "types are specified all font families are returned."
- },
-
- {"files_for_family", fontconfig_files_for_family, METH_VARARGS,
- "files_for_family(family, normalize)\n\n"
- "Find all the variants in the font family `family`. "
- "Returns a list of tuples. Each tuple is of the form "
- "(fullname, path, style, family, weight, slant). "
- },
-
- {"match", fontconfig_match, METH_VARARGS,
- "match(namespec,all,verbose)\n\n"
- "Find all system fonts that match namespec, in decreasing order "
- "of closeness. "
- "Returns a list of tuples. Each tuple is of the form "
- "(fullname, path, style, family, weight, slant). "
-
- },
-
- {"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}
-};
-
-
-
-PyMODINIT_FUNC
-initfontconfig(void) {
- PyObject *m;
- m = Py_InitModule3(
- "fontconfig", fontconfig_methods,
- "Find fonts."
- );
- if (m == NULL) return;
-
- PyModule_AddIntMacro(m, FC_WEIGHT_THIN);
- PyModule_AddIntMacro(m, FC_WEIGHT_EXTRALIGHT);
- PyModule_AddIntMacro(m, FC_WEIGHT_ULTRALIGHT);
- PyModule_AddIntMacro(m, FC_WEIGHT_LIGHT);
- PyModule_AddIntMacro(m, FC_WEIGHT_BOOK);
- PyModule_AddIntMacro(m, FC_WEIGHT_REGULAR);
- PyModule_AddIntMacro(m, FC_WEIGHT_NORMAL);
- PyModule_AddIntMacro(m, FC_WEIGHT_MEDIUM);
- PyModule_AddIntMacro(m, FC_WEIGHT_DEMIBOLD);
- PyModule_AddIntMacro(m, FC_WEIGHT_SEMIBOLD);
- PyModule_AddIntMacro(m, FC_WEIGHT_BOLD);
- PyModule_AddIntMacro(m, FC_WEIGHT_EXTRABOLD);
- PyModule_AddIntMacro(m, FC_WEIGHT_ULTRABOLD);
- PyModule_AddIntMacro(m, FC_WEIGHT_BLACK);
- PyModule_AddIntMacro(m, FC_WEIGHT_HEAVY);
- PyModule_AddIntMacro(m, FC_WEIGHT_EXTRABLACK);
- PyModule_AddIntMacro(m, FC_WEIGHT_ULTRABLACK);
-
- PyModule_AddIntMacro(m, FC_SLANT_ROMAN);
- PyModule_AddIntMacro(m, FC_SLANT_ITALIC);
- PyModule_AddIntMacro(m, FC_SLANT_OBLIQUE);
-
- PyModule_AddIntMacro(m, FC_WIDTH_ULTRACONDENSED);
- PyModule_AddIntMacro(m, FC_WIDTH_EXTRACONDENSED);
- PyModule_AddIntMacro(m, FC_WIDTH_CONDENSED);
- PyModule_AddIntMacro(m, FC_WIDTH_SEMICONDENSED);
- PyModule_AddIntMacro(m, FC_WIDTH_NORMAL);
- PyModule_AddIntMacro(m, FC_WIDTH_SEMIEXPANDED);
- PyModule_AddIntMacro(m, FC_WIDTH_EXPANDED);
- PyModule_AddIntMacro(m, FC_WIDTH_EXTRAEXPANDED);
- PyModule_AddIntMacro(m, FC_WIDTH_ULTRAEXPANDED);
-
-#
-}
-