The headless plugin can now locate all system fonts via fontconfig

This commit is contained in:
Kovid Goyal 2014-05-04 18:28:42 +05:30
parent fa81bfe4c8
commit 261041eaf9
6 changed files with 18 additions and 43 deletions

View File

@ -106,7 +106,8 @@ def get_sip_dir(q):
pyqt['pyqt_sip_dir'] = get_sip_dir(c.default_sip_dir) pyqt['pyqt_sip_dir'] = get_sip_dir(c.default_sip_dir)
pyqt['sip_inc_dir'] = c.sip_inc_dir pyqt['sip_inc_dir'] = c.sip_inc_dir
glib_flags = subprocess.check_output([PKGCONFIG, '--libs', 'glib-2.0']) if islinux else '' glib_flags = subprocess.check_output([PKGCONFIG, '--libs', 'glib-2.0']).strip() if islinux else ''
fontconfig_flags = subprocess.check_output([PKGCONFIG, '--libs', 'fontconfig']).strip() if islinux else ''
qt_inc = pyqt['inc'] qt_inc = pyqt['inc']
qt_lib = pyqt['lib'] qt_lib = pyqt['lib']
ft_lib_dirs = [] ft_lib_dirs = []

View File

@ -16,7 +16,7 @@ from setup.build_environment import (chmlib_inc_dirs,
msvc, MT, win_inc, win_lib, win_ddk, magick_inc_dirs, magick_lib_dirs, 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, magick_libs, chmlib_lib_dirs, sqlite_inc_dirs, icu_inc_dirs,
icu_lib_dirs, win_ddk_lib_dirs, ft_libs, ft_lib_dirs, ft_inc_dirs, icu_lib_dirs, win_ddk_lib_dirs, ft_libs, ft_lib_dirs, ft_inc_dirs,
zlib_libs, zlib_lib_dirs, zlib_inc_dirs, is64bit, glib_flags) zlib_libs, zlib_lib_dirs, zlib_inc_dirs, is64bit, glib_flags, fontconfig_flags)
MT MT
isunix = islinux or isosx or isbsd isunix = islinux or isosx or isbsd
@ -515,7 +515,7 @@ class Build(Command):
if not self.newer(target, headers + sources + others): if not self.newer(target, headers + sources + others):
return return
# Arch monkey patches qmake as a result of which it fails to add # Arch monkey patches qmake as a result of which it fails to add
# glib-2.0 to the list of library dependencies. Compiling QPA # glib-2.0 and freetype2 to the list of library dependencies. Compiling QPA
# plugins uses the static libQt5PlatformSupport.a which needs glib # plugins uses the static libQt5PlatformSupport.a which needs glib
# to be specified after it for linking to succeed, so we add it to # to be specified after it for linking to succeed, so we add it to
# QMAKE_LIBS_PRIVATE (we cannot use LIBS as that would put -lglib-2.0 # QMAKE_LIBS_PRIVATE (we cannot use LIBS as that would put -lglib-2.0
@ -533,9 +533,10 @@ class Build(Command):
OTHER_FILES = {others} OTHER_FILES = {others}
DESTDIR = {destdir} DESTDIR = {destdir}
CONFIG -= create_cmake # Prevent qmake from generating a cmake build file which it puts in the calibre src directory CONFIG -= create_cmake # Prevent qmake from generating a cmake build file which it puts in the calibre src directory
QMAKE_LIBS_PRIVATE += {glib} QMAKE_LIBS_PRIVATE += {glib} {fontconfig}
''').format( ''').format(
headers=' '.join(headers), sources=' '.join(sources), others=' '.join(others), destdir=self.d(target), glib=glib_flags) headers=' '.join(headers), sources=' '.join(sources), others=' '.join(others), destdir=self.d(
target), glib=glib_flags, fontconfig=fontconfig_flags)
bdir = self.j(self.d(self.SRC), 'build', 'headless') bdir = self.j(self.d(self.SRC), 'build', 'headless')
if not os.path.exists(bdir): if not os.path.exists(bdir):
os.makedirs(bdir) os.makedirs(bdir)

View File

@ -9,7 +9,7 @@ QT_BEGIN_NAMESPACE
HeadlessBackingStore::HeadlessBackingStore(QWindow *window) HeadlessBackingStore::HeadlessBackingStore(QWindow *window)
: QPlatformBackingStore(window) : QPlatformBackingStore(window)
, mDebug(HeadlessIntegration::instance()->options() & HeadlessIntegration::DebugBackingStore) , mDebug(0)
{ {
if (mDebug) if (mDebug)
qDebug() << "HeadlessBackingStore::HeadlessBackingStore:" << (quintptr)this; qDebug() << "HeadlessBackingStore::HeadlessBackingStore:" << (quintptr)this;

View File

@ -10,30 +10,13 @@
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
#include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformfontdatabase.h>
#include <QtPlatformSupport/private/qfontconfigdatabase_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static const char debugBackingStoreEnvironmentVariable[] = "QT_DEBUG_BACKINGSTORE";
static inline unsigned parseOptions(const QStringList &paramList)
{
unsigned options = 0;
foreach (const QString &param, paramList) {
if (param == QLatin1String("enable_fonts"))
options |= HeadlessIntegration::EnableFonts;
}
return options;
}
HeadlessIntegration::HeadlessIntegration(const QStringList &parameters) HeadlessIntegration::HeadlessIntegration(const QStringList &parameters)
: m_dummyFontDatabase(0)
, m_options(parseOptions(parameters))
{ {
if (qEnvironmentVariableIsSet(debugBackingStoreEnvironmentVariable) Q_UNUSED(parameters);
&& qgetenv(debugBackingStoreEnvironmentVariable).toInt() > 0) {
m_options |= DebugBackingStore | EnableFonts;
}
HeadlessScreen *mPrimaryScreen = new HeadlessScreen(); HeadlessScreen *mPrimaryScreen = new HeadlessScreen();
mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320); mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320);
@ -41,11 +24,11 @@ HeadlessIntegration::HeadlessIntegration(const QStringList &parameters)
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied; mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
screenAdded(mPrimaryScreen); screenAdded(mPrimaryScreen);
m_fontDatabase.reset(new QFontconfigDatabase());
} }
HeadlessIntegration::~HeadlessIntegration() HeadlessIntegration::~HeadlessIntegration()
{ {
delete m_dummyFontDatabase;
} }
bool HeadlessIntegration::hasCapability(QPlatformIntegration::Capability cap) const bool HeadlessIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@ -68,11 +51,7 @@ public:
QPlatformFontDatabase *HeadlessIntegration::fontDatabase() const QPlatformFontDatabase *HeadlessIntegration::fontDatabase() const
{ {
if (m_options & EnableFonts) return m_fontDatabase.data();
return QPlatformIntegration::fontDatabase();
if (!m_dummyFontDatabase)
m_dummyFontDatabase = new DummyFontDatabase;
return m_dummyFontDatabase;
} }
QPlatformWindow *HeadlessIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *HeadlessIntegration::createPlatformWindow(QWindow *window) const
@ -90,11 +69,7 @@ QPlatformBackingStore *HeadlessIntegration::createPlatformBackingStore(QWindow *
QAbstractEventDispatcher *HeadlessIntegration::createEventDispatcher() const QAbstractEventDispatcher *HeadlessIntegration::createEventDispatcher() const
{ {
#ifdef Q_OS_WIN
return new QEventDispatcherWin32;
#else
return createUnixEventDispatcher(); return createUnixEventDispatcher();
#endif
} }
HeadlessIntegration *HeadlessIntegration::instance() HeadlessIntegration *HeadlessIntegration::instance()

View File

@ -2,6 +2,7 @@
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
#include <QScopedPointer>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -25,10 +26,6 @@ public:
class HeadlessIntegration : public QPlatformIntegration class HeadlessIntegration : public QPlatformIntegration
{ {
public: public:
enum Options { // Options to be passed on command line or determined from environment
DebugBackingStore = 0x1,
EnableFonts = 0x2
};
explicit HeadlessIntegration(const QStringList &parameters); explicit HeadlessIntegration(const QStringList &parameters);
~HeadlessIntegration(); ~HeadlessIntegration();
@ -40,13 +37,12 @@ public:
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QAbstractEventDispatcher *createEventDispatcher() const; QAbstractEventDispatcher *createEventDispatcher() const;
unsigned options() const { return m_options; } unsigned options() const { return 0; }
static HeadlessIntegration *instance(); static HeadlessIntegration *instance();
private: private:
mutable QPlatformFontDatabase *m_dummyFontDatabase; QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
unsigned m_options;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -77,10 +77,12 @@ def test_apsw():
def test_qt(): def test_qt():
from calibre.gui2 import Application from calibre.gui2 import Application
from PyQt5.Qt import (QImageReader, QNetworkAccessManager) from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase)
from PyQt5.QtWebKitWidgets import QWebView from PyQt5.QtWebKitWidgets import QWebView
os.environ.pop('DISPLAY', None) os.environ.pop('DISPLAY', None)
app = Application([], headless=islinux) app = Application([], headless=islinux)
if len(QFontDatabase().families()) < 5:
raise RuntimeError('The QPA headless plugin is not able to locate enough system fonts via fontconfig')
fmts = set(map(unicode, QImageReader.supportedImageFormats())) fmts = set(map(unicode, QImageReader.supportedImageFormats()))
testf = set(['jpg', 'png', 'mng', 'svg', 'ico', 'gif']) testf = set(['jpg', 'png', 'mng', 'svg', 'ico', 'gif'])
if testf.intersection(fmts) != testf: if testf.intersection(fmts) != testf: