summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fontdatabases
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fontdatabases')
-rw-r--r--src/platformsupport/fontdatabases/basicunix/basicunix.pri84
-rw-r--r--src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp422
-rw-r--r--src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h68
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/fontconfig.pri2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp604
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h56
-rw-r--r--src/platformsupport/fontdatabases/fontdatabases.pri10
-rw-r--r--src/platformsupport/fontdatabases/genericunix/genericunix.pri1
-rw-r--r--src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h53
9 files changed, 1300 insertions, 0 deletions
diff --git a/src/platformsupport/fontdatabases/basicunix/basicunix.pri b/src/platformsupport/fontdatabases/basicunix/basicunix.pri
new file mode 100644
index 0000000000..f83b89063b
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/basicunix.pri
@@ -0,0 +1,84 @@
+DEFINES += QT_NO_FONTCONFIG
+QT += gui-private core-private
+
+HEADERS += \
+ $$PWD/qbasicunixfontdatabase_p.h \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
+
+SOURCES += \
+ $$PWD/qbasicunixfontdatabase.cpp \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
+
+CONFIG += opentype
+
+contains(QT_CONFIG, freetype) {
+ QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
+ SOURCES += \
+ $$QT_FREETYPE_DIR/src/base/ftbase.c \
+ $$QT_FREETYPE_DIR/src/base/ftbbox.c \
+ $$QT_FREETYPE_DIR/src/base/ftdebug.c \
+ $$QT_FREETYPE_DIR/src/base/ftglyph.c \
+ $$QT_FREETYPE_DIR/src/base/ftinit.c \
+ $$QT_FREETYPE_DIR/src/base/ftmm.c \
+ $$QT_FREETYPE_DIR/src/base/fttype1.c \
+ $$QT_FREETYPE_DIR/src/base/ftsynth.c \
+ $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
+ $$QT_FREETYPE_DIR/src/bdf/bdf.c \
+ $$QT_FREETYPE_DIR/src/cache/ftcache.c \
+ $$QT_FREETYPE_DIR/src/cff/cff.c \
+ $$QT_FREETYPE_DIR/src/cid/type1cid.c \
+ $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
+ $$QT_FREETYPE_DIR/src/pcf/pcf.c \
+ $$QT_FREETYPE_DIR/src/pfr/pfr.c \
+ $$QT_FREETYPE_DIR/src/psaux/psaux.c \
+ $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
+ $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
+ $$QT_FREETYPE_DIR/src/raster/raster.c \
+ $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
+ $$QT_FREETYPE_DIR/src/smooth/smooth.c \
+ $$QT_FREETYPE_DIR/src/truetype/truetype.c \
+ $$QT_FREETYPE_DIR/src/type1/type1.c \
+ $$QT_FREETYPE_DIR/src/type42/type42.c \
+ $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
+ $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
+ $$QT_FREETYPE_DIR/src/autofit/afangles.c\
+ $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
+ $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
+ $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
+ $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
+ $$QT_FREETYPE_DIR/src/autofit/afhints.c\
+ $$QT_FREETYPE_DIR/src/autofit/afloader.c\
+ $$QT_FREETYPE_DIR/src/autofit/autofit.c
+
+ symbian {
+ SOURCES += \
+ $$QT_FREETYPE_DIR/src/base/ftsystem.c
+ } else {
+ SOURCES += \
+ $$QT_FREETYPE_DIR/builds/unix/ftsystem.c
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/builds/unix
+ }
+
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/src \
+ $$QT_FREETYPE_DIR/include
+
+ DEFINES += FT2_BUILD_LIBRARY
+ contains(QT_CONFIG, system-zlib) {
+ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
+ }
+
+} else:contains(QT_CONFIG, system-freetype) {
+ # pull in the proper freetype2 include directory
+ include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
+}
+
diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
new file mode 100644
index 0000000000..8012f84797
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
@@ -0,0 +1,422 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbasicunixfontdatabase_p.h"
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformScreen>
+
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+#include <QtCore/QUuid>
+
+#undef QT_NO_FREETYPE
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
+};
+
+static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
+{
+ QSupportedWritingSystems writingSystems;
+ bool hasScript = false;
+
+ int i;
+ for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ hasScript = true;
+ // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
+ hasScript = true;
+ //qDebug("font %s supports Simplified Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::TraditionalChinese);
+ hasScript = true;
+ //qDebug("font %s supports Traditional Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Japanese);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Korean);
+ hasScript = true;
+ //qDebug("font %s supports Korean", familyName.latin1());
+ }
+ if (!hasScript)
+ writingSystems.setSupported(QFontDatabase::Symbol);
+
+ return writingSystems;
+}
+
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+void QBasicUnixFontDatabase::populateFontDatabase()
+{
+ QPlatformFontDatabase::populateFontDatabase();
+ QString fontpath = fontDir();
+
+ if(!QFile::exists(fontpath)) {
+ qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qPrintable(fontpath));
+ }
+
+ QDir dir(fontpath);
+ dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
+ << QLatin1String("*.ttc") << QLatin1String("*.pfa")
+ << QLatin1String("*.pfb"));
+ dir.refresh();
+ for (int i = 0; i < int(dir.count()); ++i) {
+ const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
+// qDebug() << "looking at" << file;
+ addTTFile(QByteArray(), file);
+ }
+}
+
+QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
+{
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+ engine = new QFontEngineFT(fontDef);
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+namespace {
+
+ class QFontEngineFTRawData: public QFontEngineFT
+ {
+ public:
+ QFontEngineFTRawData(const QFontDef &fontDef) : QFontEngineFT(fontDef)
+ {
+ }
+
+ void updateFamilyNameAndStyle()
+ {
+ fontDef.family = QString::fromAscii(freetype->face->family_name);
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
+ fontDef.style = QFont::StyleItalic;
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
+ fontDef.weight = QFont::Bold;
+ }
+
+ bool initFromData(const QByteArray &fontData)
+ {
+ FaceId faceId;
+ faceId.filename = "";
+ faceId.index = 0;
+ faceId.uuid = QUuid::createUuid().toByteArray();
+
+ return init(faceId, true, Format_None, fontData);
+ }
+ };
+
+}
+
+QFontEngine *QBasicUnixFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+
+ QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
+ if (!fe->initFromData(fontData)) {
+ delete fe;
+ return 0;
+ }
+
+ fe->updateFamilyNameAndStyle();
+
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintNone);
+ break;
+ case QFont::PreferFullHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintFull);
+ break;
+ case QFont::PreferVerticalHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintLight);
+ break;
+ default:
+ // Leave it as it is
+ break;
+ }
+
+ return fe;
+}
+
+QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ Q_UNUSED(styleHint);
+ return QStringList();
+}
+
+QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ return addTTFile(fontData,fileName.toLocal8Bit());
+}
+
+void QBasicUnixFontDatabase::releaseHandle(void *handle)
+{
+ FontFile *file = static_cast<FontFile *>(handle);
+ delete file;
+}
+
+QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
+{
+ extern FT_Library qt_getFreetype();
+ FT_Library library = qt_getFreetype();
+
+ int index = 0;
+ int numFaces = 0;
+ QStringList families;
+ do {
+ FT_Face face;
+ FT_Error error;
+ if (!fontData.isEmpty()) {
+ error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ } else {
+ error = FT_New_Face(library, file.constData(), index, &face);
+ }
+ if (error != FT_Err_Ok) {
+ qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
+ break;
+ }
+ numFaces = face->num_faces;
+
+ QFont::Weight weight = QFont::Normal;
+
+ QFont::Style style = QFont::StyleNormal;
+ if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+ style = QFont::StyleItalic;
+
+ if (face->style_flags & FT_STYLE_FLAG_BOLD)
+ weight = QFont::Bold;
+
+ QSupportedWritingSystems writingSystems;
+ // detect symbol fonts
+ for (int i = 0; i < face->num_charmaps; ++i) {
+ FT_CharMap cm = face->charmaps[i];
+ if (cm->encoding == ft_encoding_adobe_custom
+ || cm->encoding == ft_encoding_symbol) {
+ writingSystems.setSupported(QFontDatabase::Symbol);
+ break;
+ }
+ }
+
+ TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ if (os2) {
+ quint32 unicodeRange[4] = {
+ os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
+ };
+ quint32 codePageRange[2] = {
+ os2->ulCodePageRange1, os2->ulCodePageRange2
+ };
+
+ writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+
+ if (os2->usWeightClass == 0)
+ ;
+ else if (os2->usWeightClass < 350)
+ weight = QFont::Light;
+ else if (os2->usWeightClass < 450)
+ weight = QFont::Normal;
+ else if (os2->usWeightClass < 650)
+ weight = QFont::DemiBold;
+ else if (os2->usWeightClass < 750)
+ weight = QFont::Bold;
+ else if (os2->usWeightClass < 1000)
+ weight = QFont::Black;
+
+ if (os2->panose[2] >= 2) {
+ int w = os2->panose[2];
+ if (w <= 3)
+ weight = QFont::Light;
+ else if (w <= 5)
+ weight = QFont::Normal;
+ else if (w <= 7)
+ weight = QFont::DemiBold;
+ else if (w <= 8)
+ weight = QFont::Bold;
+ else if (w <= 10)
+ weight = QFont::Black;
+ }
+ }
+
+ QString family = QString::fromAscii(face->family_name);
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QString::fromAscii(file);
+ fontFile->indexValue = index;
+
+ QFont::Stretch stretch = QFont::Unstretched;
+
+ registerFont(family,QString(),weight,style,stretch,true,true,0,writingSystems,fontFile);
+
+ families.append(family);
+
+ FT_Done_Face(face);
+ ++index;
+ } while (index < numFaces);
+ return families;
+}
diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h
new file mode 100644
index 0000000000..fa5fce0e20
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBASICUNIXFONTDATABASE_H
+#define QBASICUNIXFONTDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include <QtCore/QByteArray>
+#include <QtCore/QString>
+
+struct FontFile
+{
+ QString fileName;
+ int indexValue;
+};
+
+class QBasicUnixFontDatabase : public QPlatformFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ void releaseHandle(void *handle);
+
+ static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
+};
+
+#endif // QBASICUNIXFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
new file mode 100644
index 0000000000..2efcb4d4dc
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
@@ -0,0 +1,2 @@
+HEADERS += $$PWD/qfontconfigdatabase_p.h
+SOURCES += $$PWD/qfontconfigdatabase.cpp
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
new file mode 100644
index 0000000000..9726ad8119
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -0,0 +1,604 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfontconfigdatabase_p.h"
+
+#include <QtCore/QList>
+#include <QtGui/private/qfont_p.h>
+
+#include <QtCore/QElapsedTimer>
+
+#include <QtGui/QPlatformScreen>
+
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#include <fontconfig/fontconfig.h>
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static inline bool requiresOpenType(int writingSystem)
+{
+ return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
+ || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
+}
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+static int getFCWeight(int fc_weight)
+{
+ int qtweight = QFont::Black;
+ if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
+ qtweight = QFont::Light;
+ else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
+ qtweight = QFont::Normal;
+ else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
+ qtweight = QFont::DemiBold;
+ else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
+ qtweight = QFont::Bold;
+
+ return qtweight;
+}
+
+static const char *specialLanguages[] = {
+ "en", // Common
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "ko", // Hangul
+ "", // Ogham
+ "", // Runic
+ "km", // Khmer
+ "" // N'Ko
+};
+enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
+
+static const ushort specialChars[] = {
+ 0, // English
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Hangul
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0, // Khmer
+ 0x7ca // N'Ko
+};
+enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
+
+// this could become a list of all languages used for each writing
+// system, instead of using the single most common language.
+static const char *languageForWritingSystem[] = {
+ 0, // Any
+ "en", // Latin
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "km", // Khmer
+ "zh-cn", // SimplifiedChinese
+ "zh-tw", // TraditionalChinese
+ "ja", // Japanese
+ "ko", // Korean
+ "vi", // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ 0 // N'Ko
+};
+enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
+
+// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
+// charset. The lists below contain the systems where we need to do this.
+static const ushort sampleCharForWritingSystem[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0x7ca // N'Ko
+};
+enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
+
+// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
+// open type tables for is directly. Do this so we don't pick some strange
+// pseudo unicode font
+static const char *openType[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ "syrc", // Syriac
+ "thaa", // Thaana
+ "deva", // Devanagari
+ "beng", // Bengali
+ "guru", // Gurmukhi
+ "gurj", // Gujarati
+ "orya", // Oriya
+ "taml", // Tamil
+ "telu", // Telugu
+ "knda", // Kannada
+ "mlym", // Malayalam
+ "sinh", // Sinhala
+ 0, // Thai
+ 0, // Lao
+ "tibt", // Tibetan
+ "mymr", // Myanmar
+ 0, // Georgian
+ "khmr", // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ "nko " // N'Ko
+};
+
+static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
+{
+ const char *stylehint = 0;
+ switch (style) {
+ case QFont::SansSerif:
+ stylehint = "sans-serif";
+ break;
+ case QFont::Serif:
+ stylehint = "serif";
+ break;
+ case QFont::TypeWriter:
+ stylehint = "monospace";
+ break;
+ default:
+ break;
+ }
+ return stylehint;
+}
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcFontSet *fonts;
+
+ QString familyName;
+ FcChar8 *value = 0;
+ int weight_value;
+ int slant_value;
+ int spacing_value;
+ FcChar8 *file_value;
+ int indexValue;
+ FcChar8 *foundry_value;
+ FcBool scalable;
+ FcBool antialias;
+
+ {
+ FcObjectSet *os = FcObjectSetCreate();
+ FcPattern *pattern = FcPatternCreate();
+ const char *properties [] = {
+ FC_FAMILY, FC_WEIGHT, FC_SLANT,
+ FC_SPACING, FC_FILE, FC_INDEX,
+ FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
+ FC_WIDTH,
+#if FC_VERSION >= 20297
+ FC_CAPABILITY,
+#endif
+ (const char *)0
+ };
+ const char **p = properties;
+ while (*p) {
+ FcObjectSetAdd(os, *p);
+ ++p;
+ }
+ fonts = FcFontList(0, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
+ }
+
+ for (int i = 0; i < fonts->nfont; i++) {
+ if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ familyName = QString::fromUtf8((const char *)value);
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_MEDIUM;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_MEDIUM;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ for (int i = 1; i < LanguageCount; ++i) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang)
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+ FcCharSet *cs = 0;
+ res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
+ if (res == FcResultMatch) {
+ // some languages are not supported by FontConfig, we rather check the
+ // charset to detect these
+ for (int i = 1; i < SampleCharCount; ++i) {
+ if (!sampleCharForWritingSystem[i])
+ continue;
+ if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < LanguageCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
+
+ double pixel_size = 0;
+ if (!scalable) {
+ int width = 100;
+ FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
+ FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
+ }
+
+ QFont::Stretch stretch = QFont::Unstretched;
+ QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+ }
+
+ FcFontSetDestroy (fonts);
+
+ struct FcDefaultFont {
+ const char *qtname;
+ const char *rawname;
+ bool fixed;
+ };
+ const FcDefaultFont defaults[] = {
+ { "Serif", "serif", false },
+ { "Sans Serif", "sans-serif", false },
+ { "Monospace", "monospace", true },
+ { 0, 0, false }
+ };
+ const FcDefaultFont *f = defaults;
+ // aliases only make sense for 'common', not for any of the specials
+ QSupportedWritingSystems ws;
+ ws.setSupported(QFontDatabase::Latin);
+
+
+ QString familyQtName = QString::fromLatin1(f->qtname);
+ while (f->qtname) {
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0);
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0);
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0);
+ ++f;
+ }
+
+ //Lighthouse has very lazy population of the font db. We want it to be initialized when
+ //QApplication is constructed, so that the population procedure can do something like this to
+ //set the default font
+// const FcDefaultFont *s = defaults;
+// QFont font("Sans Serif");
+// font.setPointSize(9);
+// QApplication::setFont(font);
+}
+
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
+{
+ if (!usrPtr)
+ return 0;
+ QFontDef fontDef = f;
+
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+
+ engine = new QFontEngineFT(fontDef);
+
+ // try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = fontDef.family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+
+ value.u.s = (const FcChar8 *)fid.filename.data();
+ FcPatternAdd(pattern,FC_FILE,value,true);
+
+ value.type = FcTypeInteger;
+ value.u.i = fid.index;
+ FcPatternAdd(pattern,FC_INDEX,value,true);
+
+ if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
+ QFontEngineFT::HintStyle default_hint_style;
+
+ //hinting
+ int hint_style = 0;
+ if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ hint_style = QFontEngineFT::HintFull;
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ default_hint_style = QFontEngineFT::HintNone;
+ break;
+ case FC_HINT_SLIGHT:
+ default_hint_style = QFontEngineFT::HintLight;
+ break;
+ case FC_HINT_MEDIUM:
+ default_hint_style = QFontEngineFT::HintMedium;
+ break;
+ default:
+ default_hint_style = QFontEngineFT::HintFull;
+ break;
+ }
+ engine->setDefaultHintStyle(default_hint_style);
+ }
+ FcPatternDestroy(pattern);
+
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ QStringList fallbackFamilies;
+ FcPattern *pattern = FcPatternCreate();
+ if (!pattern)
+ return fallbackFamilies;
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+ int slant_value = FC_SLANT_ROMAN;
+ if (style == QFont::StyleItalic)
+ slant_value = FC_SLANT_ITALIC;
+ else if (style == QFont::StyleOblique)
+ slant_value = FC_SLANT_OBLIQUE;
+ FcPatternAddInteger(pattern, FC_SLANT, slant_value);
+
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
+ Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ FcLangSet *ls = FcLangSetCreate();
+ FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
+ FcPatternAddLangSet(pattern, FC_LANG, ls);
+ FcLangSetDestroy(ls);
+ }
+
+ const char *stylehint = getFcFamilyForStyleHint(styleHint);
+ if (stylehint) {
+ value.u.s = (const FcChar8 *)stylehint;
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcResult result = FcResultMatch;
+ FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
+ FcPatternDestroy(pattern);
+
+ if (fontSet) {
+ if (result == FcResultMatch) {
+ for (int i = 0; i < fontSet->nfont; i++) {
+ FcChar8 *value = 0;
+ if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ QString familyName = QString::fromUtf8((const char *)value);
+ if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
+ familyName.compare(family, Qt::CaseInsensitive)) {
+ fallbackFamilies << familyName;
+ }
+ }
+ }
+ FcFontSetDestroy(fontSet);
+ }
+// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
+
+ return fallbackFamilies;
+}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
new file mode 100644
index 0000000000..5a5e4b670f
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTCONFIGDATABASE_H
+#define QFONTCONFIGDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
+
+class QFontconfigDatabase : public QBasicUnixFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+};
+
+#endif // QFONTCONFIGDATABASE_H
diff --git a/src/platformsupport/fontdatabases/fontdatabases.pri b/src/platformsupport/fontdatabases/fontdatabases.pri
new file mode 100644
index 0000000000..0e282d97dd
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontdatabases.pri
@@ -0,0 +1,10 @@
+DEFINES += QT_COMPILES_IN_HARFBUZZ
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
+
+unix {
+ include($$PWD/basicunix/basicunix.pri)
+ include($$PWD/genericunix/genericunix.pri)
+ contains(QT_CONFIG,fontconfig) {
+ include($$PWD/fontconfig/fontconfig.pri)
+ }
+}
diff --git a/src/platformsupport/fontdatabases/genericunix/genericunix.pri b/src/platformsupport/fontdatabases/genericunix/genericunix.pri
new file mode 100644
index 0000000000..e9db6c07e2
--- /dev/null
+++ b/src/platformsupport/fontdatabases/genericunix/genericunix.pri
@@ -0,0 +1 @@
+HEADERS += $$PWD/qgenericunixfontdatabase_p.h
diff --git a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
new file mode 100644
index 0000000000..63f214df54
--- /dev/null
+++ b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGENERICUNIXFONTDATABASE_H
+#define QGENERICUNIXFONTDATABASE_H
+
+#ifdef Q_FONTCONFIGDATABASE
+#include <QtPlatformSupport/private/qfontconfigdatabase_p.h>
+typedef QFontconfigDatabase QGenericUnixFontDatabase;
+#else
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
+typedef QBasicUnixFontDatabase QGenericUnixFontDatabase;
+#endif //Q_FONTCONFIGDATABASE
+
+#endif // QGENERICUNIXFONTDATABASE_H